# FindFit and log norm function

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.}.

• 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. – Oleksandr R. Dec 20 '15 at 22:46
• 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. – Oleksandr R. Dec 20 '15 at 22:54
• 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]". – Krzysztof Narkowicz Dec 21 '15 at 9:31
• @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]. – Rom38 Dec 21 '15 at 10:50

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}]}]


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