2
$\begingroup$

In general Mathematica may return a value even if NDSolve has run into error.

A simple example is

s = NDSolve[{y'[x] == Sin[x], y[0] == 0}, y, {x, 0, 1}, WorkingPrecision -> 60]
Print[First[y[1] /. s]]

which returns a value for y[1] along with an error

NDSolve::nderr: Error test failure at x == 4.8320299102694283008304019926655375368705512022963654026223787904735038`60.*^-7; unable to continue.

Now suppose that Mathematica is asked to loop over $10^4$ values of y[0] to find $10^4$ y[1] via NDSolve and then append {y[0], y[1]} to some .txt file.

There are some different ways to achieve this but in any case one is facing the following question: from all the y[1]'s that are in my .txt in the end of the day (or in the next morning) which can I trust?

A brute-force approach is to open whatever .nb file you used, check the warnings one by one and then manually delete the corresponding values from the .txt file.

Another brute-force approach is not to loop over NDSolve at all and repeat manually the calculations for all $10^4$ y[0]'s

However it would be better if one had some variable e.g. error initiated as error=0 at the beggining of each loop and then coined unity i.e. error=1 when a warning occurs. If this value is then appended to the .txt along with y[0] and y[1] then one can erase any untrustworthy value with simple list manipulation.

In this case the above simplistic example should look like

error=0; 
s = NDSolve[{y'[x] == Sin[x], y[0] == 0}, y, {x, 0, 1}, WorkingPrecision -> 60]
Print[First[y[1] /. s]]
If[(...),{error=1}];

So the question is: what should be the condition in (...)? How can one implement the condition "if an arror occurs" in Mathematica programming?

$\endgroup$
4
  • 1
    $\begingroup$ Have you looked at the function Check? $\endgroup$
    – Natas
    Jun 18 '20 at 12:47
  • $\begingroup$ I tried Check[s = NDSolve[{y'[x] == Sin[x], y[0] == 0}, y, {x, 0, 1}, WorkingPrecision -> 10], err] which shows no error. However Check does not set err to unity. So probably I'd rather ask how to implement Check to NDSolve? $\endgroup$
    – user67126
    Jun 18 '20 at 12:54
  • $\begingroup$ The basic syntax is Check[expr, failexpr] where failexpr is evaluated and returned if an error has occurred. In your case you could try Check[s = ..., error=1] if you want to use If. However I do not recommend this practice. You should perhaps have a look at Throw and Catch. $\endgroup$
    – Natas
    Jun 18 '20 at 12:58
  • $\begingroup$ There are several standard practices, a couple of which are mentioned in the comments above $\endgroup$
    – Jason B.
    Jun 18 '20 at 13:07
0
$\begingroup$

One way

SetDirectory[NotebookDirectory[]];
ode1 = {y'[x] == Sin[x], y[0] == 0};
ode2 = {y'[x] == x, y[0] == 0};
ode3 = {y'[x] == Cos[x], y[0] == 0};
odes = {ode1, ode2, ode3}
Do[
 Print["solving ode number ", n];
 
 s = Quiet@Check[
    NDSolve[odes[[n]], y, {x, 0, 1}, WorkingPrecision -> 60]
    ,
    Null,
    NDSolve::nderr (*you can add more error code here*)
                    (*Or do not use this field at all to catch any error*)
    ];
 
 If[s === Null,
  Print["Skipping n=", n, " because error was detected"]
  ,
  Print["good n=", n];
  Print[First[y[1] /. s]] (*change this to write to file *)
  ]
 , {n, 1, Length@odes}]

enter image description here

So basically, you write to the file, only when s is not Null, which means no error messages were generated.

You can customize this as needed.

$\endgroup$
4
  • $\begingroup$ Thanks for your time Nasser! Thanks a lot! $\endgroup$
    – user67126
    Jun 18 '20 at 13:14
  • $\begingroup$ Is there any bibliography on how to loop over NDSolve? I really had no idea. $\endgroup$
    – user67126
    Jun 18 '20 at 13:18
  • $\begingroup$ You could make one big list of all your odes? and just iterate over them as above. You could arrange them in an association also. One field for the ode, second field for the initial conditions, third field for the dependent variable, and so on. Then once the list is made, just run the Do loop over them. $\endgroup$
    – Nasser
    Jun 18 '20 at 13:20
  • $\begingroup$ Check out ParametricNDSolve $\endgroup$
    – chuy
    Jun 18 '20 at 15:55

Your Answer

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