python - 用 Python 重写 Mathematica 输出

标签 python numpy wolfram-mathematica sympy

我想将 Mathematica 中计算的分段函数输出转换为 Python。从 this 获取灵感Mathematica->Python 转换页面和 this编写分段函数的页面,我有

from numpy import linspace, vectorize, array
from numpy import arctan, log
import matplotlib.pyplot as plt
from sympy.parsing.mathematica import parse

def fun(x,a,b,c):
    # string inside parse('') is my mathematica output
    if a == 0:
        out = parse('a (-I b + x) ArcTan[(b - a)/c]')
    else:
        out = parse('4 c a^2 Log[c^2 + (x - a)^2]')
    return out

a = 0.17
b = 0.44
c = 0.29
x = linspace(0,50,int(1e3))

vfun = vectorize(fun)
y = vfun(x,a,b,c)
yp = 4*c*a**2*log(c**2 + (x - a)**2)

plt.figure()
plt.plot(x,y,'.-')
plt.title('mathematica -> python conversion')

plt.figure()
plt.plot(x,yp,'.-')
plt.title('expected')

plt.show()

情节如下:

enter image description here

而它应该是:

enter image description here

将 Mathematica 转换为 Python 时我是否做错了什么?或者给abc赋值的时候有问题吗? (请注意,这是一个 MWE,我想要转换的 Mathematica 代码比上面显示的要长得多且复杂。)

最佳答案

一个更简单的解决方案是使用eval。现在我知道 eval 非常危险,但大多数时候它需要用户的输入,但这里的输入已经为我们定义了。

现在来看答案。< br/> 您没有获得预期的输出,因为您的矢量化数组不包含任何 float ,而仅包含mathematica解析器的输出,该解析器返回未评估的字符串,因此我们可以使用 .evalf() 作为@David给出的答案, lambdify() 内部使用 eval(),或者我们可以直接使用 eval()
以下是所使用方法的文档:https://docs.sympy.org/latest/tutorial/basic_operations.html

from numpy import linspace, vectorize, array
from numpy import arctan, log
import matplotlib.pyplot as plt
from sympy.parsing.mathematica import MathematicaParser

def fun(x,a,b,c):
    obj = MathematicaParser()
    if a == 0:
        out = obj.parse('a (-I b + x) ArcTan[(b - a)/c]')
    else:
        out = obj.parse('4 c a^2 Log[c^2 + (x - a)^2]')

    return out

a = 0.17
b = 0.44
c = 0.29
x = linspace(0,50,int(1e3))
yp = 4*c*a**2*log(c**2 + (x - a)**2)
vfun = vectorize(fun)
y = vfun(x,a,b,c)
#Here y is a type <class 'numpy.ndarray'> containing 1000 <class 'numpy.str_'>
#['4*c*a**2*log(c**2+(x-a)**2)' '4*c*a**2*log(c**2+(x-a)**2)'
#'4*c*a**2*log(c**2+(x-a)**2)' '4*c*a**2*log(c**2+(x-a)**2)'
#'4*c*a**2*log(c**2+(x-a)**2)' '4*c*a**2*log(c**2+(x-a)**2)'
#'4*c*a**2*log(c**2+(x-a)**2)' '4*c*a**2*log(c**2+(x-a)**2)'
#....
y = eval(y[0]) #y[0] is '4*c*a**2*log(c**2+(x-a)**2)'
#When we evaluate y[0] we again get y as <class 'numpy.ndarray'> conatining 1000 <class 'numpy.float64'>
#Because x is <class 'numpy.ndarray'> it evaluates the first string over
#all the points in x.
#[-0.07309464 -0.07770262 -0.08110382 -0.0828403  -0.08263539 -0.08052339
#-0.07683235 -0.07203573 -0.06659307 -0.06086366 -0.05509179 -0.04942739
#-0.04395413 -0.03871304 -0.03371924 -0.0289728  -0.02446552 -0.02018495
#.....
plt.figure()
plt.plot(x, y,'.-')
plt.title('mathematica -> python conversion')

plt.figure()
plt.plot(x,yp,'.-')
plt.title('expected')

plt.show()

输出:
enter image description here

关于python - 用 Python 重写 Mathematica 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56321120/

相关文章:

python - simplejson不序列化

python - 如何将 numpy 数组的 dtype 更改为 'object' ?

wolfram-mathematica - 是否可以在播种时访问部分列表内容,还是必须等待它被收割?

python - 优化测试多个 NumPy 数组中的所有行组合

python - 如何防止 QTableView 项在双击时被清除

python-3.x - 如何将预训练的 Keras 模型的所有层转换为不同的 dtype(从 float32 到 float16)?

python - 如何根据 Pandas 中的列填充缺失值?

c# - C# 中的复杂计算

wolfram-mathematica - 我如何在 Mathematica 中进行此替换?

python - 如何将 APScheduler JobStore 与 SQLAlchemy 模型(外键)相关联 - Python Flask