# Using NonlinearModelFit for complex data ?

Posted 6 years ago
8232 Views
|
4 Replies
|
0 Total Likes
|
 Hello Everyone,I am trying to fit an impedance model with real data. I have measured the real and imaginary part of an impedance for a set of frequencies (here from 10kHz to 800kHz). And I want to fit a non linear model (called here: ZeFull[R,Cc,C2,C0,2Pi f], where R,Cc,C2,C0 are parameters (that I want to estimate from the data) and f is the frequency (or w=2 Pi f the pulsation) as showed below: In[2720]:= Zlist = {{10000, 35292.4 - 335783. I}, {20000, 28850.3 - 173613. I}, {30000, 25831.2 - 119349. I}, {50000, 22358.5 - 76039.9 I}, {80000, 19092.1 - 52161.6 I}, {100000, 17317.4 - 44323.6 I}, {200000, 10797. - 28171.2 I}, {300000, 6879.63 - 21538. I}, {500000, 3260.48 - 14499.7 I}, {800000, 1439.32 - 9671.26 I}}; In[2709]:= ?ZeFull GlobalZeFull ZeFull[R_,Cc_,C2_,C0_,w_]=(C2 R Sqrt[I w]+Sqrt[Cc] Sqrt[R] Coth[Sqrt[Cc] Sqrt[R] Sqrt[I w]])/(Sqrt[I w] (Cc+I C0 C2 R w)+I (C0+C2) Sqrt[Cc] Sqrt[R] w Coth[Sqrt[Cc] Sqrt[R] Sqrt[I w]]) In[2719]:= NonlinearModelFit[Zlist, ZeFull[R, Cc, C2, C0, 2 Pi f], {{R, 30000}, {Cc, 10. 10^-12}, {C2, 10.10^-12}, {C0, 20.10^-12}}, {f}] During evaluation of In[2719]:= NonlinearModelFit::nrlnum: The function value {-24411.3-1.12602*10^6 I,-17969.3-557314. I,-14950.4-367963. I,-11478.3-216399. I,-8213.2-130691. I,-6439.74-102017. I,70.392 -45241.2 I,3970.71 -27671.5 I,7535.87 -15535.4 I,9228.93 -9857.22 I} is not a list of real numbers with dimensions {10} at {R,Cc,C2,C0} = {30000.,1.*10^-11,8.87449*10^-13,2.29957*10^-16}. >> Out[2719]= NonlinearModelFit[{{10000, 35292.4 - 335783. I}, {20000, 28850.3 - 173613. I}, {30000, 25831.2 - 119349. I}, {50000, 22358.5 - 76039.9 I}, {80000, 19092.1 - 52161.6 I}, {100000, 17317.4 - 44323.6 I}, {200000, 10797. - 28171.2 I}, {300000, 6879.63 - 21538. I}, {500000, 3260.48 - 14499.7 I}, {800000, 1439.32 - 9671.26 I}}, ( C2 Sqrt[I f] Sqrt[2 \[Pi]] R + Sqrt[Cc] Sqrt[R] Coth[Sqrt[Cc] Sqrt[I f] Sqrt[2 \[Pi]] Sqrt[R]])/( Sqrt[I f] Sqrt[2 \[Pi]] (Cc + 2 I C0 C2 f \[Pi] R) + 2 I (C0 + C2) Sqrt[Cc] f \[Pi] Sqrt[R] Coth[Sqrt[Cc] Sqrt[I f] Sqrt[2 \[Pi]] Sqrt[R]]), {{R, 30000}, {Cc, 1.*10^-11}, {C2, 8.87449*10^-13}, {C0, 2.29957*10^-16}}, {f}] I think I respected the syntax of the function but it seems that the function NonlinearModelFit does not work on complex numbers. I am thinking to use a NMinimize function on a cost function built with the squared module of the difference between model and data but I wonder if there is a simpler way to do that?Thanks for your feedbackChristian
4 Replies
Sort By:
Posted 6 years ago
 Hello,I finally tried this and it worked last night: In[47]:= NMinimize[ Plus @@ (Abs /@ ((ZeFull[R, Cc, C2, C0, 2 Pi #] &) /@ Transpose[Zlist][[1]] - Transpose[Zlist][[2]])), {{R, 10000., 300000}, {Cc, 1. 10^-12, 100. 10^-12}, {C2, 1. 10^-12, 100. 10^-12}, {C0, 1. 10^-12, 100. 10^-12}}] Out[47]= {22025.6, {R -> 150721., Cc -> 2.39849*10^-11, C2 -> 6.6428*10^-12, C0 -> 1.64356*10^-11}} Solution seems to be physically coherent...But it took about 1hour of CPU on Mathematica 8 at home on my (Windows XP SP3) old pentium 4 I'll try at work today with V10 on Core i7 but I am not optimistic.Any suggestions for speed improvement ?CheersChristian
Posted 6 years ago
 Hi, Christian,You can compile the model function: DATA = { {10000, 35292.4 - 335783. I}, {20000, 28850.3 - 173613. I}, {30000, 25831.2 - 119349. I}, {50000, 22358.5 - 76039.9 I}, {80000, 19092.1 - 52161.6 I}, {100000, 17317.4 - 44323.6 I}, {200000, 10797. - 28171.2 I}, {300000, 6879.63 - 21538. I}, {500000, 3260.48 - 14499.7 I}, {800000, 1439.32 - 9671.26 I} }; ZC = Compile[ {{X,_Real,1}}, ( CompileGetElement[X,1] CompileGetElement[X,3] Sqrt[I CompileGetElement[X,5]] + Sqrt[CompileGetElement[X,2]] Sqrt[CompileGetElement[X,1]] Coth[Sqrt[CompileGetElement[X,2]] Sqrt[CompileGetElement[X,1]] Sqrt[I CompileGetElement[X,5]]] )/ ( Sqrt[I CompileGetElement[X,5]] (CompileGetElement[X,2] + I CompileGetElement[X,4] CompileGetElement[X,3] CompileGetElement[X,1] CompileGetElement[X,5]) + I (CompileGetElement[X,4]+CompileGetElement[X,3]) Sqrt[CompileGetElement[X,2]] Sqrt[CompileGetElement[X,1]] CompileGetElement[X,5] Coth[Sqrt[CompileGetElement[X,2]] Sqrt[CompileGetElement[X,1]] Sqrt[I CompileGetElement[X,5]]] ), RuntimeOptions -> "Speed", CompilationOptions -> { "ExpressionOptimization" -> True}, RuntimeAttributes -> {Listable}, Parallelization -> True, CompilationTarget -> "WVM" ] ; Then it takes about a second to reproduce your result: Off[CompiledFunction::cfta] ; NMinimize[ Plus@@(Abs[((ZC[{R,Cc,C2,C0,2.Pi #}] &)/@ #[[;;,1]] - #[[;;,2]])& @ DATA]), {{R, 10000., 300000}, {Cc, 1. 10^-12, 100. 10^-12}, {C2, 1. 10^-12, 100. 10^-12}, {C0, 1. 10^-12, 100. 10^-12}}, MaxIterations -> 100 ] // AbsoluteTiming NMinimize::cvmit: Failed to converge to the requested accuracy or precision within 100 iterations. >> {0.823515, {22050.4, {R -> 150721., Cc -> 2.40162*10^-11, C2 -> 6.66602*10^-12, C0 -> 1.64684*10^-11}}} If more iterations are allowed then one of Cs gets negative.I.M.