Message Boards Message Boards

GROUPS:

Using NonlinearModelFit for complex data ?

Posted 5 years ago
7764 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

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

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

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.

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 3 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.

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