4
$\begingroup$

I would like to use a different norm instead of the 2-norm in FindFit (Mathematica 9). For example, instead of using

$$\sqrt{\sum (x_{\mathrm{model}} - x_{\mathrm{data}})^2}$$

I'd like to use

$$\sum \frac{x_{\mathrm{model}}}{x_{\mathrm{data}}}$$

I can tell FindFit to use a user-created function as the NormFunction. However, I am unsure of the syntax to use when defining $x_{\mathrm{model}}$. Can anyone point me to example code for using a user-defined NormFunction in FindFit or NDSolve?

$\endgroup$
  • 1
    $\begingroup$ It doesn't look too straightforward to do, since the norm functions always take $\text{model}-\text{data}$ as the argument. Worst comes to worst, you can use NArgMin[]/FindArgMin[] for your custom fitting. $\endgroup$ – J. M.'s discontentment Apr 25 '13 at 13:15
  • $\begingroup$ Thank you @J.M. I will look into using 'NArgMin[]/FindArgMin[] for fitting, if I cannot code a user-defined normfunction. $\endgroup$ – JACapp Apr 25 '13 at 13:42
6
$\begingroup$

Suppose your data is formatted as following:

data = Table[{x[t], y[t]}, {t, 0, 1, .2}]

{{x[0.], y[0.]}, {x[0.2], y[0.2]}, {x[0.4], y[0.4]}, {x[0.6], y[0.6]}, {x[0.8], y[0.8]}, {x[1.], y[1.]}}

You can use this symbolic "data" to peep into the FindFit to see what does the NormFunction take as its argument (as J.M. said (and the documentation), it's the residual):

Reap[
   FindFit[data, model[x, a, b], {a, b}, x,
     NormFunction -> (Sow[myNorm[#]] &),
     MaxIterations -> 1];
   ][[2, 1, 1]] // Quiet
myNorm[{
   model[x[0.], a, b] - y[0.],
   model[x[0.2], a, b] - y[0.2],
   model[x[0.4], a, b] - y[0.4],
   model[x[0.6], a, b] - y[0.6],
   model[x[0.8], a, b] - y[0.8],
   model[x[1.], a, b] - y[1.]}]

So a custom NormFunction as the question specified can be realized as:

ydata = data[[All, 2]];

Reap[
   FindFit[data, model[x, a, b], {a, b}, x,
     NormFunction -> (Sow[
           Total[(# + ydata)/ydata ]
         ] &),
     MaxIterations -> 1];
   ][[2, 1, 1]] // Quiet

$$\begin{split} &\frac{\text{model}(x(0.),a,b)}{y(0.)}+\frac{\text{model}(x(0.2),a,b)}{y(0.2)}+\frac{\text{model}(x(0.4),a,b)}{y(0.4)}\\ +&\frac{\text{model}(x(0.6),a,b)}{y(0.6)}+\frac{\text{model}(x(0.8),a,b)}{y(0.8)}+\frac{\text{model}(x(1.),a,b)}{y(1.)}\\ \end{split}$$

| improve this answer | |
$\endgroup$
  • $\begingroup$ If you're going to do it that way, maybe one should cache data[[All, 2]] so that it is not being repeatedly evaluated... matter of fact, maybe just do Total[1 + #/data[[All, 2]]] &... $\endgroup$ – J. M.'s discontentment Apr 25 '13 at 14:24
  • $\begingroup$ @J.M. Yes you're right. Well this is just a principle demonstration. But please see my edit. $\endgroup$ – Silvia Apr 25 '13 at 14:28
  • $\begingroup$ @J.M. I keep (# + ydata)/ydata to emphasize the x_model/x_data structure OP asked. $\endgroup$ – Silvia Apr 25 '13 at 14:31
  • $\begingroup$ @Silvia - thank you for the excellent explanation. I was able to implement this method into my fitting function, resulting in better fits of my model to my data. $\endgroup$ – JACapp Apr 25 '13 at 18:55
  • $\begingroup$ @user7104 You're welcome. $\endgroup$ – Silvia Apr 25 '13 at 18:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.