Unexpected differences with various uses of NormFunction

I would expect all of the following to give the same answer (2.12467) but only half of them give this answer. The others seem to be using the default NormFunction:>(Norm[#,2]&). Can anyone explain this?

α = 3;
n /. FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> ((Null; Norm[#, α]) &)]
n /. FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> ((Norm[#, α]) &)]
n /. FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> (Norm[#, 3] &)]

Block[{α = 3},  n /. FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> (Norm[#, α] &)]]
With[{α = 3}, n /. FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> (Norm[#, α] &)]]
Module[{α = 3}, n /. FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> (Norm[#, α] &)]]

(* Outputs: 2.12467, 2.13284, 2.12467, 2.13284, 2.12467, 2.13284 *)
• Actually, the last three cases can be reduced to the second and third: Block just has the effect of temporarily setting a to 3 therefore the expression is exactly equivalent to the second case (indeed, if executed in that order, the Block is even redundant because a already has the value 3). The With replaces the a by the literal 3, therefore it's exactly equivalent to the third case. And Module replaces a by a temporary variable which is set to 3, but of course the name (and life time) of the variable doesn't matter, therefore it's again equivalent to case 2. – celtschk May 1 '12 at 19:20

This must have to do with the symbolic preprocessing, happening in FindFit. In all cases when you get 2.13284, this was a result of symbolic preprocessing, which was possible because the norm function could be evaluated on symbolic arguments. The subsequent result is likely explained by the mechanism described by @Searke.

But if you define your own norm as

ClearAll[norm];
norm[vec_?(VectorQ[#, NumericQ] &), alpha_] := Norm[vec, alpha];

and replace Norm with norm in all your examples, you always get 2.12467. You can gain more insight into this by using Trace with TraceInternal -> True.

• In fact it seems to be enough to write norm=Norm, so the symbolic preprocessing must be doing something very fragile. – Lev Bishop May 1 '12 at 19:36
• @LevBishop Good point. Alas, I don't have enough time right now to dig deeper into it. – Leonid Shifrin May 1 '12 at 20:08

Compare your results to:

FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> ((Norm[#, thisisnotavariable]) &)]

When the NormFunction fails and is not well designed, FindFit just quietly chooses the 2-norm.

This is effectively what is happening in your example above.

• What, in this case, makes Norm[#, α]& not well designed? – rcollyer May 1 '12 at 19:10
• It's not so simple: FindFit[{1, 3, 9, 20}, x^n, n, x, NormFunction :> (notavariable &)] gives a straightforward error message ("not a real number"). And why does adding a redundant compoundexpression (Null;) change my NormFunction from "not well designed" to "well designed"? – Lev Bishop May 1 '12 at 19:11