I'm trying to fit a function to data using FindFit, but I can't find a way to replace norm function RMSE with a RMSE in log space: Total[(Log10[a] - Log10[b])^2]

I tried:

logNorm [x_, y_] = Total[(Log10[x + 1] - Log10[y + 1])^2];
nlm = FindFit[data, x*a+b, {a, b}, x, NormFunction -> (logNorm[#] &)]

But I get an error:

The function value logNorm[<long list>] is not a real number at {a,b} = {1.,1.}.

  • 3
    $\begingroup$ NormFunction operates on the list of residuals, which are already formed and provided to this function. You seem to want it to represent the log-distance to the point. Sorry, but it cannot do this; you should use FindMinimum instead with a suitable objective function. FindFit just calls FindMinimum internally, if that makes you feel better. $\endgroup$ Commented Dec 20, 2015 at 22:46
  • $\begingroup$ But, perhaps I misunderstood your question. Is Norm[Log10[## + 1], 2] & what you want? I am not sure I understand what your x and y arguments to logNorm are supposed to represent. $\endgroup$ Commented Dec 20, 2015 at 22:54
  • $\begingroup$ Thanks. I wanted to replace RMSE with LRMSE. If residuals are already formed, then it's not possible and I'd have to use FindMinimum. In logNorm, x corresponds to observed value and y to fitted value provided by a model. In other words I wanted to replace current residuals calculated as "x-y" with "Log10[x+1]-Log10[y+1]". $\endgroup$ Commented Dec 21, 2015 at 9:31
  • $\begingroup$ @Krzysztof Narkowicz, I guess the norm-function should be represented as f[Delta=observed-calculated], so you should transform your logarithmic expression to this form instead of your f[observed,calculated]. $\endgroup$
    – Rom38
    Commented Dec 21, 2015 at 10:50

1 Answer 1


You can pass your data to the NormFunction:

myNorm[residuals_, data_] := 
   Total[(Log[data[[All, 2]] + 1] - 
          Log[data[[All, 2]] + residuals + 1])^2];
data = {#, 2 # + 10 + # RandomReal[{0, 2}]} & /@ Range[100];
fit = x*a + b /. 
    FindFit[data, x*a + b, {a, b}, x, 
         NormFunction -> (myNorm[#, data] &)] 

10.3158 + 2.86435 x

Show[{ListPlot[data], Plot[fit, {x, 0, 100}]}]

enter image description here

or even do this: NormFunction -> (logNorm[data[[All, 2]] + #, data[[All, 2]]] &) and your function as originally defined will work.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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