5
$\begingroup$

The following code works fine in mathematica 10 but it does not produces output in mathematica 11.

s = NDSolve[{y'[x] == g[x], g'[x] == -60 (1 - x) Cos[y[x]], y[0] ==0,g[0]== 1.2}, {y, g}, {x, 0, 1}];
f[x_] = Evaluate[y[x] /. s];
intcos[x_Real] := NIntegrate[Cos[f[t]], {t, 0, x}];
intsin[x_Real] := NIntegrate[Sin[f[t]], {t, 0, x}];
ParametricPlot[{intcos[x], intsin[x]}, {x, 0, 1}]

The version of Mathematica 10 I am using is:

10.0 for Linux x86 (64-bit) (June 29, 2014)

I would just understand what happens! Thanks!

$\endgroup$
  • $\begingroup$ What version of 10 are you running? I can't produce a ParametricPlot in 10.4, so the issue predates 11. $\endgroup$ – rcollyer Apr 27 '17 at 13:19
  • $\begingroup$ I modified the post! Thanks! $\endgroup$ – Popbatman Apr 27 '17 at 13:26
  • 1
    $\begingroup$ This is pretty bizarre. ParametricPlot[p = {intcos[x], intsin[x]}, {x, 0, 1}] works, but takes a long time. Without the assignment, it looks like it never evaluates (I checked with EvaluationMonitor/Sow/Reap). It also takes a while. All those NIntegrates slow things down. $\endgroup$ – Pillsy Apr 27 '17 at 13:47
  • $\begingroup$ Thanks everyone for your very useful suggestions! $\endgroup$ – Popbatman Apr 27 '17 at 16:51
  • $\begingroup$ Seriously, now that I've figured it out, I have no idea why this ever worked in 10. $\endgroup$ – Pillsy Apr 27 '17 at 17:08
10
$\begingroup$

OK, this is actually much simpler than it looks. Let's just take the first part, where you solve the diffy queues:

ClearAll[f, intcos, intsin, s]

s = NDSolve[{y'[x] == g[x], g'[x] == -60 (1 - x) Cos[y[x]], y[0] == 0, 
    g[0] == 1.2}, {y, g}, {x, 0, 1}];
f[x_] = Evaluate[y[x] /. s];

Now, one thing you may know is that NDSolve always returns a list of solutions. Let's see what happens when we evaluate f:

f[0.5] 
(* {-3.31356} *)

This will carry through to the results of intcos and intsin:

{intcos[0.5], intsin[0.5]}
(* {{0.0454218}, {-0.22277}} *)

It turns out this list of one-element list structure doesn't work so well with ParametricPlot in Mathematica 11.1.0, but it might have worked with earlier versions. In any event,

ParametricPlot[{{Sin[t]}, {Cos[t]}}, {t, 0, 1}]

also returns an empty set of axes.

Now, we could fix this, but when I tried that it took an inordinate amount of time to plot since it redoes the NIntegrate for each point. Let's only do the integration once using NDSolveValue:

s = First@s;
f[x_] = Evaluate[y[x] /. s];
{intcos, intsin} = 
 NDSolveValue[{ic'[t] == Cos[f[t]], is'[t] == Sin[f[t]], ic[0] == 0, 
  is[0] == 0},
  {ic, is}, {t, 0, 1}];

Now it will plot in an eye blink.

 ParametricPlot[{intcos[x], intsin[x]}, {x, 0, 1}]

plot

$\endgroup$
  • 2
    $\begingroup$ he doesn't use intcos[f] anywhere, so the pattern match is not an issue. $\endgroup$ – george2079 Apr 27 '17 at 17:42
  • 1
    $\begingroup$ strong point. i'll fix my answer. $\endgroup$ – Pillsy Apr 28 '17 at 0:24
5
$\begingroup$

Mathematica 11. The result of f[x] is a list but not a number.

{InterpolatingFunction[{{0., 1.}}, <>][x]}

In:

Clear[s, x, y, g, f]
s = NDSolve[{y'[x] == g[x], g'[x] == -60 (1 - x) Cos[y[x]], y[0] == 0,
     g[0] == 1.2}, {y, g}, {x, 0, 1}];

(*f[x_] = Evaluate[y[x] /. s] ;*)
f[x_] = Evaluate[y[x] /. s] // First;

intcos[x_Real] := NIntegrate[Cos[f[t]], {t, 0, x}];
intsin[x_Real] := NIntegrate[Sin[f[t]], {t, 0, x}];

{intcos[0.1], intsin[0.1]}

ParametricPlot[{intcos[x], intsin[x]}, {x, 0, 1}]

Out:

{0.0997858, -0.00373958}

enter image description here

$\endgroup$
3
$\begingroup$

I'm not sure why it has stopped evaluating between versions, but your code could be significantly improved.

Evaluating f[0.1] gives a list containing a value, rather than just a value. If you take only the first (and only in this case) solution from NDSolve the issue will disappear:

s = NDSolve[{y'[x] == g[x], g'[x] == -60 (1 - x) Cos[y[x]], y[0] ==0,g[0]== 1.2}, {y, g}, {x, 0, 1}][[1]];
f[x_] = Evaluate[y[x] /. s];
intcos[x_Real] := NIntegrate[Cos[f[t]], {t, 0, x}];
intsin[x_Real] := NIntegrate[Sin[f[t]], {t, 0, x}];
ParametricPlot[{intcos[x], intsin[x]}, {x, 0, 1}]

Presumably something has changed in how ParametricPlot evaluates in this case, but ParametricPlot hasn't ever (or at least back to version 9) worked when the arguments are lists, so I'm surprised it did before.

However, it will be much quicker to put the integrations into the NDSolve:

s2 = NDSolve[{y'[x] == g[x], g'[x] == -60 (1 - x) Cos[y[x]], 
     a'[x] == Cos[y[x]], b'[x] == Sin[y[x]], y[0] == 0, g[0] == 1.2, 
     a[0] == 0, b[0] == 0}, {y, g, a, b}, {x, 0, 1}][[1]];
ParametricPlot[{a[x], b[x]} /. s2, {x, 0, 1}]

Also in general you shouldn't use _Real, use _?NumericQ instead, as with your definition intcos[0] doesn't give a value (whereas intcos[0.] will)

$\endgroup$

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.