Message Boards Message Boards

Extracting values from NDSolve

Posted 4 months ago

Hi Guys

This may be a really noob question.
The below code is solving one of the Mathematica examples for NDSolve.
Once executed the "result" variable holds all the data for the solution, how can one easily access this data for plotting?

I have tried plotting within the "wolfram_code" section, however nothing is actually plotted and only a message in the terminal regarding the lot is presented.

from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl, wlexpr
import matplotlib.pyplot as plt
import numpy as np

session = WolframLanguageSession()

wolfram_code = """
                s = NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, 30}]
                """

result = session.evaluate(wlexpr(wolfram_code))

session.terminate()
POSTED BY: Mishal Mohanlal
3 Replies
Posted 3 months ago

HI,

This is a good example about how to run mathematica from Python.

I think it is better to change the title of this posting for better search, e.g., how to run Mathematica from Python

POSTED BY: Sangdon Lee
Posted 3 months ago

Hi Michael

Thank you for the detailed response.

I managed to develop the below code which fits my needs really well. I am just posting it here in case someone ever has a similar query.

from wolframclient.evaluation import WolframLanguageSession
from wolframclient.language import wl, wlexpr
import matplotlib.pyplot as plt
import numpy as np

session = WolframLanguageSession()



wolfram_code = """
    s = NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, 30}];
    Table[{x, y[x] /. s}, {x, 0, 30, 0.1}]
"""

# Evaluate the Wolfram code
result = session.evaluate(wlexpr(wolfram_code))

# Terminate the Wolfram session
session.terminate()

# Extract x and y values from the result
x_vals = [pair[0] for pair in result]
y_vals = [pair[1] for pair in result]

# Plot the solution using matplotlib
plt.plot(x_vals, y_vals, label='y(x)')
plt.xlabel('x')
plt.ylabel('y(x)')
plt.title('Solution of y\'[x] = y[x] Cos[x + y[x]]')
plt.grid(True)
plt.legend()

# Show the plot
plt.show()
POSTED BY: Mishal Mohanlal

In Mathematica, using WL, your code

s = NDSolve[{y'[x] == y[x] Cos[x + y[x]], y[0] == 1}, y, {x, 0, 30}]

returns a set of solutions; in this case, there is only one solution. First[s] yields that solution. One can plot the solution with

Plot[y[x] /. First[s], {x, 0, 30}]

One can get a single value of y at a specified x, say x=4.5, thus:

y[4.5] /. First[s]

One can get a table of values like this:

Table[y[x] /. First[s], {x, 0, 30, 0.5}]

Note that for values of x between the steps, an interpolation error is added to the integration error, and it usually has a lower order of precision than the integration method. For plotting and other applications, it is usually small enough not to matter. But if you need greater accuracy, add the option InterpolationOrder -> All to the NDSolve[] call.

If you want the actual steps taken by NDSolve, the following extracts the x and y values (separately, which is how they're stored):

xgrid = y["Grid"] /. First[s] (* xgrid  = {{x0}, {x1}, {x2}, ...} *)
yvals = y["ValuesOnGrid"] /. First[s] (* yvals = {y0, y1, y2, ...} *)

Use Flatten[xgrid] if you want a flat list {x0, x1, x2,...} of x coordinates. One could also use xgrid = First[y["Coordinates"] /. First[s]] instead of "Grid" and Flatten. The following is are quick ways to plot the steps:

ListPlot[y /. First[s]]     (* Not y[x]! *)
ListLinePlot[y /. First[s]] (* Connects the dots between the steps *)

I hope that helps. I don't use the framework shown your question. I don't know how graphics work in it, for instance. I'm just hoping that all you need are the WL codes for evaluating and plotting the solution.

POSTED BY: Michael Rogers
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract