I'm trying to fit an equation to data using FindFit. When I type
in the equation and data and then FindFit, I get this:
Z := [Omega]^(-(2 ArcTan[H/G])/[Pi]) (G - i H) + R
Data := {{1.`, 2.658637`- 8.389573` i}, {1.5`,
1.784396`- 6.214955` i}, {2.5`,
1.656569`- 3.97147` i}, {3.5`,
1.633799`- 2.878841` i}, {5.5`,
1.357069`- 1.776964` i}, {6.5`,
1.259121`- 1.848249` i}, {8.5`,
1.105417`- 1.344566` i}, {9.5`,
1.119456`- 1.148945` i}, {11.5`,
1.082122`- 1.064767` i}, {14.5`,
1.015714`- 0.8684088` i}, {15.5`,
1.055329`- 0.664562` i}, {18.5`,
0.8675349`- 0.5107938` i}, {20.5`,
0.8968949`- 0.4148388` i}}
FindFit[Data, Z, {R, G, H}, \[Omega]]
FindFit::nrlnum: The function value {-0.658637+7.38957 \
\[ImaginaryI],0.0321006+5.39846 \[ImaginaryI],-0.0241135+3.33901 \
\[ImaginaryI],<<5>>,0.212762+0.769883 \[ImaginaryI],0.246899+0.605796
\
\[ImaginaryI],<<3>>} is not a list of real numbers with dimensions \
{13} at {R,G,H} = {1.,1.,1.}. >>
Why?!?!? Why can't FindFit handle this? What's wrong with it not
being a list of real numbers? I'm pulling my hair out. I've looked
at others' suggestions for similar problems and they don't work for
this problem. Am I out of my mind? Does anyone have a suggeston?
Regards,
Benji
I was curious about this, so I searched MathGroup, and the suggested
solution appears to be to use a "real-valued" norm function instead:
FindFit[ ... , NormFunction -> (Abs@Norm[#]&)
This solution does works.
http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/=
thread/6afe1f108e51190b/d31cd1dd0cb8519b?lnk=gst&q=FindFit+complex#d31cd=
1dd0cb8519b
However, when I read this, I got suspicious. Doesn't the Norm[]
function *always* return a real number? Perhaps FindFit calls Norm
with more than one argument? We can try
FindFit[ ... , NormFunction -> (Norm[#]&) ]
to suppress all but the first argument, but it returns the same error
that we get when using simply Norm! (FindFit[ ... , NormFunction ->
Norm ])
This was really strange, so I experimented a bit with different norm
functions. According to the documentation, Norm[#]& is equivalent to
Sqrt[#.Conjugate[#]& for vectors, still, using Norm[#]& with FindFit
gives an error, while using Sqrt[#.Conjugate[#]& works. I tried
printing the arguments of the norm function, and it really *is* being
called with a simple vector.
Finally I discovered that using the norm function
norm[x_] := Norm[x]
works too, so FindFit is probably not calling Norm[] at all when
NormFunction -> Norm is used! (An alternative explanation would be
that the norm function is compiled and something goes wrong during the
compilation of Norm. But even though Norm was introduces in version
5.0, it is still not compilable in version 6.0 ... so this cannot be
the case)
I think that WRI is taking this "black box function" thing too far.
It is not a good idea to make a function *appear* to do one thing,
when in fact it does something else. Users should be aware of what
is happening inside the function.
Could someone from WRI please explain what is going on here? Am I
missing something obvious?
Szabolcs Horv=E1t
FindFit[] cant handle complex values ? as the error message
"The function value {-0.658637+7.38957\ I,0.0321006+5.39846\ \
I,<<8>>,<<3>>} is not a list of real number"
say ?
Regards
Jens
Hi Benji,
there seems to be a bug in FindFit. It works if you specify the error
function explicitely:
err[x_]:=Norm[x,2];
FindFit[Data,Z,{R,G,H},w,NormFunction->err]
please inform Wolfram about this bug.
hope this helps, Daniel
Kevin
--
Kevin J. McCann
Research Associate Professor
JCET/Physics
Physics Building
University of Maryland, Baltimore County
1000 Hilltop Circle
Baltimore, MD 21250
Z := (G - I*H)/omega^((2*ArcTan[H/G])/Pi) + R;
Data = {{1., 2.658637 - 8.389573*I}, {1.5, 1.784396 - 6.214955*I},
{2.5, 1.656569 - 3.97147*I}, {3.5, 1.633799 - 2.878841*I},
{5.5, 1.357069 - 1.776964*I}, {6.5, 1.259121 - 1.848249*I},
{8.5, 1.105417 - 1.344566*I}, {9.5, 1.119456 - 1.148945*I},
{11.5, 1.082122 - 1.064767*I}, {14.5, 1.015714 - 0.8684088*I},
{15.5, 1.055329 - 0.664562*I}, {18.5, 0.8675349 - 0.5107938*I},
{20.5, 0.8968949 - 0.4148388*I}};
pars = FindFit[Data, Z, {R, G, H}, omega, NormFunction ->
(Norm[Abs[#1^2]] & )]
p1 = ListPlot[{Re[Data], ({#1[[1]], Im[#1[[2]]]} & ) /@ Data},
PlotMarkers -> Automatic];
p2 = Plot[{Re[Z], Im[Z]} /. pars, {omega, 0, 22}];
Show[p1, p2]
BR, Martin
Norm is just as real-valued as Norm[Abs[#1^2]]&