MathGroup Archive 2004

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Using NDSolve in NonlinearFit

  • To: mathgroup at smc.vnet.net
  • Subject: [mg48863] Re: Using NDSolve in NonlinearFit
  • From: ab_def at prontomail.com (Maxim)
  • Date: Sat, 19 Jun 2004 04:31:28 -0400 (EDT)
  • References: <cap36v$c82$1@smc.vnet.net> <capcqu$eu2$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

"Jens-Peer Kuska" <kuska at informatik.uni-leipzig-de> wrote in message news:<capcqu$eu2$1 at smc.vnet.net>...
> Hi,
> 
> what is with:
> fun[omega_?NumericQ, x_?NumericQ] :=
> Module[{t, sol},
>   sol = NDSolve[
>             {y1'[t] == y2[t],
>              y2'[t] == -omega^2*y1[t],
> 
>               y1[0] == 0, y2[0] == omega},
> 
> {y1[t], y2[t]},
> {t, 0, x}];
> y1[t] /. sol[[1]] /. t -> x
> ]
> 
> data = Table[{x, Sin[2*x]}, {x, 0, 2Pi, 2Pi/256}];
> 
> FindFit[data, fun[omega, x], {{omega, 2.2}}, x]
> 
> Regards
>   Jens
> 
> 

In this particular case we can speed up the computations by finding
f[omega] once and then simply evaluating the obtained
InterpolatingFunction for different values of x:

In[1]:=
Module[{fun, f, data},
    
    fun[omega_?NumericQ, x_?NumericQ] := f[omega][x];
    
    f[omega_] := f[omega] =
        y1 /. First@NDSolve[
              {y1'[t] == y2[t], y2'[t] == -omega^2y1[t],
                y1[0] == 0, y2[0] == omega},
              {y1, y2}, {t, 0, 2Pi}];
    
    data = Table[{x, Sin[2x]}, {x, 0, 2Pi, 2Pi/256}];

    FindFit[data, fun[omega, x], {{omega, 2.2}}, x]
    ] // Timing

Out[1]=
{7.281 Second, {omega -> 2.0000001}}

It should be noted that we cannot use f[omega][x] in FindFit, we have
to add the extra definition fun[omega_,x_]:=f[omega][x], because
FindFit, using the default optimization method, will need to evaluate
the derivatives and D[f[omega][x],omega] is 0. If we use
{{omega,2.2,2.3}} instead of {{omega,2.2}}, then the derivatives won't
be used and f[omega][x] will work just as well.

It's interesting that of the following two definitions,

f[a_] = NIntegrate[Sin[a x], {x, 0, a}]
f[a_?NumericQ] := NIntegrate[Sin[a x], {x, 0, a}]

the first one will be more efficient in computations where f'[a] is
used, because in the first case Mathematica uses the built-in rules
for the derivative of NIntegrate, while in the second case it has to
resort to numerical differentiation.

As a not-quite-related issue, we can see that the numerical
optimization functions share similar syntax, with one exception: 
FindRoot and FindMinumum don't handle vector-valued functions the same
way:

In[2]:=
FindMinimum[Norm[x], {x, {1,1}}]
FindRoot[Norm[x], {x, {1,1}}]

<FindMinimum::lstol warning>

Out[2]=
{6.280369834735101*^-16,
 {x -> {4.440892098500626*^-16, 4.440892098500626*^-16}}}

FindRoot::nveq: The number of equations does not match
  the number of variables in FindRoot[Norm[x], {x, {1, 1}}].

Out[3]=
FindRoot[Norm[x], {x, {1, 1}}]

It looks like FindRoot doesn't take into account that functions can be
not only R^n->R^n, but also R^n->R.

Maxim Rytin
m.r at inbox.ru


  • Prev by Date: Re: Re: Question about Hold
  • Next by Date: RE: Overlay graphs
  • Previous by thread: Re: Using NDSolve in NonlinearFit
  • Next by thread: Question about Hold