Parsing Complex Mathematical Functions in Python

拥有回忆 提交于 2019-12-13 08:00:45

问题


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.


回答1:


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?



来源:https://stackoverflow.com/questions/42520470/parsing-complex-mathematical-functions-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!