Re: How to use FindMaximum with a parameter passed to NDSolve??
- To: mathgroup at smc.vnet.net
- Subject: [mg129150] Re: How to use FindMaximum with a parameter passed to NDSolve??
- From: Bob Hanlon <hanlonr357 at gmail.com>
- Date: Tue, 18 Dec 2012 02:38:40 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- Delivered-to: l-mathgroup@wolfram.com
- Delivered-to: mathgroup-newout@smc.vnet.net
- Delivered-to: mathgroup-newsend@smc.vnet.net
- References: <20121217075827.C668D6947@smc.vnet.net>
>From the documentation for FindMaximum: "FindMaximum first localizes the values of all variables, then evaluates f with the variables being symbolic, and then repeatedly evaluates the result numerically." This initial symbolic evaluation launches a sequence of symbolic calls that if not stopped will result in a call to NDSolve symbolically. Restricting the definition of pendulum for only numeric arguments terminates this sequence before the problem occurs. Bob Hanlon On Mon, Dec 17, 2012 at 4:38 PM, Juan Barandiaran <barandiaran.juan at gmail.com> wrote: > Thanks Bob, > your answer solves my question: just by adding ?NumericQ to the function > "pendulum" with NDSolve everything works fine apart from the precision > problems which is another matter (not important in this case). > > pendulum[long_?NumericQ] := > First[fi /. > NDSolve[{fi''[t] + 9.8 Cos[long] Sin[fi[t]] + .5 fi'[t] == 0, > fi[0] == Pi/2, fi'[0] == 0}, fi, {t, 0, 50}]] > > total[dynamics_, p_] := dynamics[3.1] + p > FindMaximum[total[pendulum[long], long ] , {long, 0.01}] > > But why? > What is the rationale behind it? > If I understand correctly, using ?NumericQ in the variables of a function > should test the variable and only execute the function if the variable is a > number. > Is this test enough for the FindMaximum function to assign a value to the > long before calling total, and then pendulum, and then NDSolve? Why? > > Thanks a lot for your answer, it helped me a lot. > > Best regards, > > JBB > > > > > 2012/12/17 Bob Hanlon <hanlonr357 at gmail.com> >> >> Since pendulum uses NDSolve it can only be evaluated for a numeric >> argument; consequently, its definition should be restricted to numeric >> arguments. You will also need to use a higher precision than machine >> precision. >> >> eqns = Rationalize[{ >> fi''[t] + 9.8 Cos[long] Sin[fi[t]] + >> .5 fi'[t] == 0, fi[0] == Pi/2, fi'[0] == 0}, 0]; >> >> pendulum[long_?NumericQ] := First[fi /. NDSolve[ >> eqns, fi, {t, 0, 50}, WorkingPrecision -> 25]] >> >> total[dynamics_, p_] := dynamics[31/10] + p >> >> max = FindMaximum[{total[pendulum[long], long]}, >> {long, 0.01`30}, WorkingPrecision -> 30]; >> >> max /. x_?NumericQ :> Round[x, 10.^-6] >> >> {13.3595, {long -> 9.81034}} >> >> >> Bob Hanlon >> >> >> On Mon, Dec 17, 2012 at 2:58 AM, JBB <barandiaran.juan at gmail.com> wrote: >> > Hello, >> > >> > This is probably a simple sintax question, but could somebody tell me >> > how can I use the FindMaximum function when the variable used has to be used >> > in an internal NDSolve?? >> > >> > A simplified version of some code to show the error is as follows: >> > >> > pendulum[long_] := >> > First[fi /. >> > NDSolve[{fi''[t] + 9.8 Cos[long] Sin[fi[t]] + .5 fi'[t] == 0, >> > fi[0] == Pi/2, fi'[0] == 0}, fi, {t, 0, 50}]] >> > >> > total[dynamics_, p_] := dynamics[3.1] + p >> > >> > FindMaximum[{total[pendulum[long], long ] }, {long, 0.01}] >> > >> > I get the following error: >> > >> > In[146]:= FindMaximum[ >> > Evaluate[total[pendulum[long], long ] ], {long, 0.01}] >> > >> > During evaluation of In[146]:= NDSolve::ndnum: Encountered non-numerical >> > value for a derivative at t == 0.`. >> >> > >> > During evaluation of In[146]:= ReplaceAll::reps: {NDSolve[{9.8 Cos[long] >> > Sin[fi[<<1>>]]+0.5 >> > (fi^\[Prime])[t]+(fi^\[Prime]\[Prime])[t]==0,fi[0]==\[Pi]/2,(fi^\[Prime])[0]==0},fi,{t,0,50}]} >> > is neither a list of replacement rules nor a valid dispatch table, and so >> > cannot be used for replacing. >> >> > >> > During evaluation of In[146]:= FindMaximum::nrnum: The function value >> > -0.01-fi[3.1] is not a real number at {long} = {0.01}. >> >> > >> > Out[146]= FindMaximum[long + fi[3.1], {long, 0.01}] >> > >> > If I understand correctly, probably because the variable "long" has not >> > been assigned a value by FindMaximum before calling the internal NDSolve. >> > >> > Is there a simple way of doing this? >> > In my real case the functions are longer but the essence of the problem >> > is the same: I have to find the maximum of some function in which the >> > variables are parameters of other functions including a NDSolve. >> > >> > Thanks for any hint, >> > >> > JBB > >
- References:
- How to use FindMaximum with a parameter passed to NDSolve??
- From: JBB <barandiaran.juan@gmail.com>
- How to use FindMaximum with a parameter passed to NDSolve??