Python 3.x 等效代码,不同结果(Python、Mathematica)

Python 3.x 等效代码,不同结果(Python、Mathematica),python-3.x,wolfram-mathematica,Python 3.x,Wolfram Mathematica,这是两个代码,一个用Python 3编写,另一个用Wolfram Mathematica编写。代码是等效的,因此结果(图)应该是相同的。但是代码给出了不同的图。这是密码 Python代码: import numpy as np import matplotlib.pyplot as plt from scipy.special import k0, k1, i0, i1 k=100.0 x = 0.0103406 B = 80.0 def fdens(f): return (1/2

这是两个代码,一个用Python 3编写,另一个用Wolfram Mathematica编写。代码是等效的,因此结果(图)应该是相同的。但是代码给出了不同的图。这是密码

Python代码:

import numpy as np
import matplotlib.pyplot as plt 
from scipy.special import k0, k1, i0, i1

k=100.0
x = 0.0103406
B = 80.0

def fdens(f):
    return (1/2*(1-f**2)**2+f **4/2
            +1/2*B*k*x**2*f**2*(1-f**2)*np.log(1+2/(B*k*x**2))
            +(B*f**2*(1+B*k*x**2))/((k*(2+B*k*x**2))**2)
            -f**4/(2+B*k*x**2)
            +(B*f)/(k*x)*
            (k0(f*x)*i1(f *np.sqrt(2/(k*B)+x**2))
            +i0(f*x)*k1(f *np.sqrt(2/(k*B)+x**2)))/
            (k1(f*x)*i1(f *np.sqrt(2/(k*B)+x**2))
            -i1(f*x)*k1(f *np.sqrt(2/(k*B)+x**2)))
            )

plt.figure(figsize=(10, 8), dpi=70)
X = np.linspace(0, 1, 100, endpoint=True)
C = fdens(X)
plt.plot(X, C, color="blue", linewidth=2.0, linestyle="-")
plt.show()
k=100.;B=80.;
x=0.0103406;
func[f_]:=1/2*(1-f^2)^2+1/2*B*k*x^2*f^2*(1-f^2)*Log[1+2/(B*k*x^2)]+f^4/2-f^4/(2+B*k*x^2)+B*f^2*(1+B*k*x^2)/(k*(2+B*k*x^2)^2)+(B*f)/(k*x)*(BesselI[1, (f*Sqrt[2/(B*k) + x^2])]*BesselK[0, f*x] + BesselI[0, f*x]*BesselK[1, (f*Sqrt[2/(B*k) + x^2])])/(BesselI[1, (f*Sqrt[2/(B*k) + x^2])]*BesselK[1,f*x] - BesselI[1,f*x]*BesselK[1, (f*Sqrt[2/(B*k) + x^2])]);

Plot[func[f],{f,0,1}]

Mathematica代码:

import numpy as np
import matplotlib.pyplot as plt 
from scipy.special import k0, k1, i0, i1

k=100.0
x = 0.0103406
B = 80.0

def fdens(f):
    return (1/2*(1-f**2)**2+f **4/2
            +1/2*B*k*x**2*f**2*(1-f**2)*np.log(1+2/(B*k*x**2))
            +(B*f**2*(1+B*k*x**2))/((k*(2+B*k*x**2))**2)
            -f**4/(2+B*k*x**2)
            +(B*f)/(k*x)*
            (k0(f*x)*i1(f *np.sqrt(2/(k*B)+x**2))
            +i0(f*x)*k1(f *np.sqrt(2/(k*B)+x**2)))/
            (k1(f*x)*i1(f *np.sqrt(2/(k*B)+x**2))
            -i1(f*x)*k1(f *np.sqrt(2/(k*B)+x**2)))
            )

plt.figure(figsize=(10, 8), dpi=70)
X = np.linspace(0, 1, 100, endpoint=True)
C = fdens(X)
plt.plot(X, C, color="blue", linewidth=2.0, linestyle="-")
plt.show()
k=100.;B=80.;
x=0.0103406;
func[f_]:=1/2*(1-f^2)^2+1/2*B*k*x^2*f^2*(1-f^2)*Log[1+2/(B*k*x^2)]+f^4/2-f^4/(2+B*k*x^2)+B*f^2*(1+B*k*x^2)/(k*(2+B*k*x^2)^2)+(B*f)/(k*x)*(BesselI[1, (f*Sqrt[2/(B*k) + x^2])]*BesselK[0, f*x] + BesselI[0, f*x]*BesselK[1, (f*Sqrt[2/(B*k) + x^2])])/(BesselI[1, (f*Sqrt[2/(B*k) + x^2])]*BesselK[1,f*x] - BesselI[1,f*x]*BesselK[1, (f*Sqrt[2/(B*k) + x^2])]);

Plot[func[f],{f,0,1}]
(正确的一个)


结果不同。有人知道为什么吗?

从我的测试来看,一阶贝塞尔函数给出了不同的结果。两者最初的计算结果都是贝塞尔(f*0.0188925),但scipy版本给了我从0到9.4e-3的范围,其中wolframalpha(使用Mathematica后端)给出了0到1.4的值。我会更深入一点


此外,python使用标准C浮点数,而Mathematica使用符号运算。试图在python中模拟这种符号操作。

它们处理浮点的方式不同?也许吧。然而,函数的极小值的偏移大于0.4。我不希望不同的浮点处理会出现这种情况。找到问题根源的一个好方法是,取一个子表达式,逐个检查它们的值。递归地做这个检查以减少问题的规模。另外,我认为MMA涉及符号执行。如果在MMA中使用
Compile[]
,会发生什么?我忘了提到,Mathematica的结果是正确的。所以问题出在python代码中。谢谢,我们将深入研究它。