简体   繁体   中英

Parsing Complex Mathematical Functions in Python

Is there a way in Python to parse a mathematical expression in Python that describes a 3D graph? Using other math modules or not. I couldn't seem to find a way for it to handle two inputs.

An example of a function I would want to parse is Holder Table Function .

It has multiple inputs, trigonometric functions, and I would need to parse the abs() parts too.

I have two 2D numpy meshgrids as input for x1 and x2, and would prefer to pass them directly to the expression for it to evaluate.

Any help would be greatly appreciated, thanks.

It's not hard to write straight numpy code that evaluates this formula.

def holder(x1, x2):
    f1 = 1 - np.sqrt(x1**2 + x2**2)/np.pi
    f2 = np.exp(np.abs(f1))
    f3 = np.sin(x1)*np.cos(x2)*f2
    return -np.abs(f3)

Evaluated at a point:

In [109]: holder(10,10)
Out[109]: -15.140223856952055

Evaluated on a grid:

In [60]: I,J = np.mgrid[-bd:bd:.01, -bd:bd:.01]
In [61]: H = holder(I,J)

Quick-n-dirty sympy

Diving into sympy without reading much of the docs:

In [65]: from sympy.abc import x,y
In [69]: import sympy as sp
In [70]: x
Out[70]: x
In [71]: x**2
Out[71]: x**2
In [72]: (x**2 + y**2)/sp.pi
Out[72]: (x**2 + y**2)/pi
In [73]: 1-(x**2 + y**2)/sp.pi
Out[73]: -(x**2 + y**2)/pi + 1
In [75]: from sympy import Abs
...
In [113]: h = -Abs(sp.sin(x)*sp.cos(y)*sp.exp(Abs(1-sp.sqrt(x**2 + y**2)/sp.pi)))
In [114]: float(h.subs(x,10).subs(y,10))
Out[114]: -15.140223856952053

Or with the sympify that DSM suggested

In [117]: h1 = sp.sympify("-Abs(sin(x)*cos(y)*exp(Abs(1-sqrt(x**2 + y**2)/pi)))")
In [118]: h1
Out[118]: -exp(Abs(sqrt(x**2 + y**2)/pi - 1))*Abs(sin(x)*cos(y))
In [119]: float(h1.subs(x,10).subs(y,10))
Out[119]: -15.140223856952053
...
In [8]: h1.subs({x:10, y:10}).n()
Out[8]: -15.1402238569521

Now how do I use this with numpy arrays?

Evaluating the result of sympy lambdify on a numpy mesgrid

In [22]: f = sp.lambdify((x,y), h1,  [{'ImmutableMatrix': np.array}, "numpy"])
In [23]: z = f(I,J)
In [24]: z.shape
Out[24]: (2000, 2000)
In [25]: np.allclose(z,H)
Out[25]: True
In [26]: timeit holder(I,J)
1 loop, best of 3: 898 ms per loop
In [27]: timeit f(I,J)
1 loop, best of 3: 899 ms per loop

Interesting - basically the same speed.

Earlier answer along this line: How to read a system of differential equations from a text file to solve the system with scipy.odeint?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM