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