FindFit and complex data
- To: mathgroup at smc.vnet.net
- Subject: [mg99273] FindFit and complex data
- From: "Paul Ellsmore" <paul.ellsmore at nanion.co.uk>
- Date: Fri, 1 May 2009 05:25:01 -0400 (EDT)
I'm having trouble with FindFit, when I try to fit complex data. A search of
the MathGroup archive shows that I am not alone, and I have at least managed
to choose a NormFunction that lets FindFit actually run with complex data.
However, I have lots of other problems.
Take this function:
explicitz =
R1 + R2*(I/(-2*pi*fr*C2)/(R2 + I/(-2*pi*fr*C2))) +
R3*(I/(-2*pi*fr*C3)/(R3 + I/(-2*pi*fr*C3)))
Which is the complex impedance of a network of resistors and capacitors, as
a fxn of frequency (fr).
I use these values to determine some dummy data:
R1 = 1000
R2 = 3000
R3 = 2000
R4 = 2000
C2 = 9.4/10^6
C3 = 9.4/10^8
C4 = 9.4/10^10
then try to fit that data using FindFit and the same function as the model:
model = fitR1 +
fitR2*(I/(-2*pi*fr*fitC2)/(fitR2 + I/(-2*pi*fr*fitC2))) +
fitR3*(I/(-2*pi*fr*fitC3)/(fitR3 + I/(-2*pi*fr*fitC3)));
In:= f1 = FindFit[explicitzdata,
model, {fitR1, fitR2, fitR3, fitC2, fitC3}, fr,
NormFunction -> (Norm[#1, 1] & ), MaxIterations -> 2000]
Out:= {fitR1 -> 1850.182794346571, fitR2 -> 34.002054354436076,
fitR3 -> 34.00205435443611, fitC2 -> 4.195230095190922*^-6,
fitC3 -> 0.000020577828982070793}
The fit values are not very good at all, so I try to add constraints, such
as fitR1>0, but this makes it MUCH worse:
In:= f1 = FindFit[
explicitzdata, { model, {fitR1 > 0}}, {fitR1, fitR2, fitR3, fitC2,
fitC3}, fr, NormFunction -> (Norm[#1, 1] & ),
MaxIterations -> 2000]
Out:= During evaluation of In[130]:= FindFit::eit:The algorithm does not
converge to the tolerance of 4.806217383937354`*^-6 in 2000 iterations. The
best estimated solution, with feasibility residual, KKT residual or
complementary residual of {1.46567*10^-9,0.00140564,1.48047*10^-9}, is
returned. >>
Out[133]= {fitR1 -> 2524.9496987320085, fitR2 -> 45.92331910801086,
fitR3 -> 45.92331910801086, fitC2 -> -21.55828521496288,
fitC3 -> -21.55828521496288}
So why is this? Can someone give me some hints as to how constraints affect
the way FindFit searches for results?
I have found that giving the actual rs and Cs I used to calculate the data,
to FindFit as starting values, still leads to big errors in the Cs. This is
what I think happens:
NormFunction is set to Norm[#1,1] (because it won't run with complex data
otherwise), which apparently returns Total[Abs[v]^p]^(1/p), and this is the
value that is minimized by FindFit. What I can't work out is what V is
given to Abs? Is it just a list of complex model minus complex data, for
each data/model point? If so, then I have a problem with weighting, because
my y-data varies by several orders of magnitude as x increases, and it is at
high x values that the Cs dominate, but the y values are smallest. I think
the absolute difference between model and data at high x values is just too
small to register in the minimizing function. Is there some form of Norm, or
some way of generating V to give to Norm, that uses some weighting? Even a
percentage, as opposed to absolute difference would help. It looks as though
it should be possible to define a custom NormFunction, if so, does anyone
have any advice for the best kind of function for this kind of data?
Some more problems:
If I set Method->NMinimize, I get the error:
Out:=During evaluation of In[170]:= Less::nord: Invalid comparison with
14.8382+0. I attempted. >>
Out[173]= {fitR1 -> 51963.2, fitR2 -> -33184.2, fitR3 -> -301167.,
fitC2 -> -3.71464*10^6, fitC3 -> 1.07187*10^6}
Can anyone interpret what the error message is actually telling me?
If I set Method->LevenbergMarquardt, I get the error FindFit::notlm: The
objective function for the method LevenbergMarquardt must be in a
least-squares form: Sum[f[i][x]^2,{i,1,n}] or Sum[w[i] f[i][x]^2,{i,1,n}]
with positive w[i]. >> I assume that this is because NormFunction is set to
Norm[#,1]? Is it not possible to use LevenbergMarquardt with complex data at
all?
I am left wondering whether FindFit is just a bit of a gimmick, good for
some simple tasks, but completely unsuited to what I'm trying to do. Should
I be using another built-in function, or is this a job that requires custom
code?
Thanks in advance.
Paul
Dr. Paul A. Ellsmore
Nanion Limited
Oxford Centre for Innovation
Mill Street
Oxford
United Kingdom
OX2 0JX
Tel: +44 (0) 1865 811175
Fax: +44 (0) 1865 248594