Message Boards Message Boards

Using NonlinearModelFit for complex data ?

Posted 10 years ago

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

Global`ZeFull

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 feedback

Christian

POSTED BY: Christian Neel
4 Replies

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 ?

Cheers

Christian

POSTED BY: Christian Neel

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}},
    (
       Compile`GetElement[X,1] Compile`GetElement[X,3] Sqrt[I Compile`GetElement[X,5]] + 
       Sqrt[Compile`GetElement[X,2]] Sqrt[Compile`GetElement[X,1]] Coth[Sqrt[Compile`GetElement[X,2]] Sqrt[Compile`GetElement[X,1]] Sqrt[I Compile`GetElement[X,5]]]
    )/
    (
       Sqrt[I Compile`GetElement[X,5]] (Compile`GetElement[X,2] + I Compile`GetElement[X,4] Compile`GetElement[X,3] Compile`GetElement[X,1] Compile`GetElement[X,5]) + 
       I (Compile`GetElement[X,4]+Compile`GetElement[X,3]) Sqrt[Compile`GetElement[X,2]] Sqrt[Compile`GetElement[X,1]] Compile`GetElement[X,5] Coth[Sqrt[Compile`GetElement[X,2]] Sqrt[Compile`GetElement[X,1]] Sqrt[I Compile`GetElement[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.

POSTED BY: Ivan Morozov

Hi Ivan,

Thank you!! It really helped!! I just copied you code and "zap!": I could even do the fit into a Manipulate loop and still get quasi real time display of data and fit residues on graphs...

Thank you also for the nice programming style.

Christian

POSTED BY: Christian Neel
Posted 9 years ago

I can not execute the code provided by Ivan. Firstly, the expression Compile`GetElement" looks different in my Notebook: the "Compile" part has no black colour, its still blue. Second, The code is far away from beeing manipulated in realtime. The code is running forever.

POSTED BY: Gale Bradfield
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract