If I have a function of list argument (presumably with large number of entries), how can I pass it to NonlinearModelFit
? I don't want to pass it by pattern checking (f[x_?(VectorQ[#, Numeric!]&)]
) because apparently it turns off some intermediate operations and heavily slows down the fitting.
Example:
f[x_, a_] := Exp[-Sin[{x, x}.a]];
NonlinearModelFit[RandomReal[{0, 1}, {10, 3}], f[x, a], {{a, {1, 2}}},
x]
Answer
I've always done it like this, and I've done fits with a few hundred parameters so it isn't that much of a pain.
The point is that you define the function f
to take a vector input for x
and a
. Then you define a vector of variables, {x1, x2,....} and that is the fourth argument to NonlinearModelFit
. The second argument to NonlinearModelFit
needs to be a scalar function, where all the matrix expansions have happened already. In the case here, f[variables, parameters]
evaluates the matrix product before it does any fitting.
parameters = Array[a, {7}]
variables = Array[x, {7}]
guess = Range[7]
f[x_, a_] := Exp[-Sin[x.a]];
nlm = NonlinearModelFit[RandomReal[{0, 1}, {40, 8}],
f[variables, parameters], Transpose[{parameters, guess}],
Evaluate@variables]
nlm["BestFitParameters"]
(* {a[1], a[2], a[3], a[4], a[5], a[6], a[7]} *)
(* {x[1], x[2], x[3], x[4], x[5], x[6], x[7]} *)
(* {1, 2, 3, 4, 5, 6, 7} *)
(* {a[1] -> 3.47592, a[2] -> 0.155765, a[3] -> 4.18935, a[4] -> 1.59981,
a[5] -> 7.34998, a[6] -> 1.60615, a[7] -> 10.3245} *)
Comments
Post a Comment