0
$\begingroup$

I've seen some people using _?NumericQ to prevent symbolic calculation and speed up NDSolve.
Why in this simple code is not working ?

qlist = {q1, q2, q3, q4, q5};
q0 = {0, 0, 0, 3, 2};
q[t_] = ToString@# <> "[t]" & /@ qlist // ToExpression;

f[{q1_?NumericQ, q2_?NumericQ, q3_?NumericQ, q4_?NumericQ, 
   q5_?NumericQ}] := {Cos@q3, Sin@q3, 1, 0, 0}

NDSolve[{q'[t] == f@q[t], q[0] == q0}, q[t], {t, 0, 3}]

I just get the error

NDSolve:"There are more dependent variables, {q1[t],q2[t],q3[t],q4[t],q5[t]}, 
than equations, so the system is underdetermined"

I'll better explain with a second exmple:

Pmat = SparseArray[{i_, j_} :> "p" <> ToString@i <> ToString@j, {5, 
     5}] // ToExpression;

P[t_] = Array[ToString@Pmat[[#1, #2]] <> "[t]" &, Dimensions@Pmat] // 
   ToExpression;

P0 = IdentityMatrix[5];

RHS := P[t].P[t] + IdentityMatrix[5] // Inverse // Inverse

NDSolve[{P[0] == P0, P'[t] == RHS}, P[t], {t, 0, 3}]

Here Mathematica spend a huge amount of time due to the symbolic evaluation. I'm asking if is there a way to bypass this process.The problem inside is very simple because the initial condition is a diagonal matrix.
I've tried this approach tho overcome the issue:

Pmat = SparseArray[{i_, j_} :> "p" <> ToString@i <> ToString@j, {5, 
     5}] // ToExpression;

P[t_] = Array[ToString@Pmat[[#1, #2]] <> "[t]" &, Dimensions@Pmat] // 
   ToExpression;

P0 = IdentityMatrix[5];

RHS[Pi_?(MatrixQ[#, NumericQ] &)] := 
 Pi.Pi + IdentityMatrix[5] // Inverse // Inverse

NDSolve[{P[0] == P0, P'[t] == RHS[P[t]]}, P[t], {t, 0, 3}]

(*NDSolve::underdet: There are more dependent variables, {p11[t],p12[t],p13[t],p14[t],p15[t],p21[t],p22[t],p23[t],p24[t],p25[t],p31[t],p32[t],p33[t],p34[t],p35[t],p41[t],p42[t],p43[t],p44[t],p45[t],p51[t],p52[t],p53[t],p54[t],p55[t]}, than equations, so the system is underdetermined.*)

But the code doesn't run.
This one is a sort of simulink approach, is there a way to make Mathematica work as it was in simulink, with a numerical approach, maybe using Module to calculate the RHS of a ODE system ?

Is possible to prevent symbolic evaluation inside NDSovle ? is my approach wrong ?

$\endgroup$
1
  • $\begingroup$ I guess that form is not supported, but this vector form is: NDSolve[{qq'[t] == f@qq[t], qq[0] == q0}, qq[t], {t, 0, 3}] (Please include error messages, when your code produces them.) $\endgroup$
    – Michael E2
    May 11 at 15:08
1
$\begingroup$

Change the definition of f

qlist = {q1, q2, q3, q4, q5};
q0 = {0, 0, 0, 3, 2};
q[t_] = ToString@# <> "[t]" & /@ qlist //ToExpression;
f = Function[q, {Cos[q[[3]]], Sin[q[[3]]], 1, 0,0}];
NDSolve[{q'[t] == f@q[t], q[0] == q0}, q[t], {t,0, 3}]
$\endgroup$
5
  • $\begingroup$ You could just remove the _?NumericQ from the OP's f, too, no? $\endgroup$
    – Michael E2
    May 11 at 15:43
  • $\begingroup$ Yes, the fact is that i'd want numerical evaluation before the symbolic one, I've seen several codes which use this technique. I've tried to replicate them but I got error $\endgroup$ May 11 at 17:36
  • 3
    $\begingroup$ I think an idiomatic way to get {q1[t], q2[t], q3[t], q4[t], q5[t]} is to use Through[qlist[t]] $\endgroup$
    – yarchik
    May 11 at 17:42
  • 1
    $\begingroup$ @yarchik - or #[t] & /@ qlist $\endgroup$
    – Bob Hanlon
    May 11 at 21:19
  • $\begingroup$ @yarchik thanks for the advice ! $\endgroup$ May 12 at 6:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.