Python Mittag-Leffler函数的不稳定性
在尝试复制和帮助时,我遇到了一些我不理解的数值不稳定性:Python Mittag-Leffler函数的不稳定性,python,numpy,Python,Numpy,在尝试复制和帮助时,我遇到了一些我不理解的数值不稳定性: import numpy as np import matplotlib.pyplot as plt from scipy.special import gamma def MLf(z, a): """Mittag-Leffler function """ k = np.arange(100).reshape(-1, 1) E = z**k / gamma(a*k + 1) return np.s
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import gamma
def MLf(z, a):
"""Mittag-Leffler function
"""
k = np.arange(100).reshape(-1, 1)
E = z**k / gamma(a*k + 1)
return np.sum(E, axis=0)
x = np.arange(-50, 10, 0.1)
plt.figure(figsize=(10,5))
for i in range(5):
plt.plot(x, MLf(x, i), label="alpha = "+str(i))
plt.legend()
plt.ylim(-5, 5); plt.xlim(-55, 15); plt.grid()
您可以在橙色线中看到不稳定性最好,其中a=1
,从大约x=-35
开始,但是a=0
(蓝色线)也有问题。更改要求和的项数(即j
)会更改发生不稳定性的x
发生什么事了?我怎样才能避免这种情况
如果a=0,您使用的MLf系列定义仅在| z | 1或全部(z>0)时适用: k=np.arange(100) 返回np.多项式.多项式.polyval(z,1/伽马(a*k+1)) #一个棘手案件的帮手,来自Gorenflo、Loutchko和Luchko 定义MLf(z,a): 如果z<0: f=λx:(np.exp(-x*(-z)**(1/a))*x**(a-1)*np.sin(np.pi*a) /(x**(2*a)+2*x**a*np.cos(np.pi*a)+1) 返回1/np.pi*quad(f,0,np.inf)[0] elif z==0: 返回1 其他: 返回MLf(z,a) 返回np.vectorize(_MLf)(z,a) x=np.arange(-50,10,0.1) plt.图(figsize=(10,5)) 对于范围(1,5)内的i: plt.plot(x,MLf(x,i/3),label=“alpha=”+str(i/3)) plt.legend() plt.ylim(-5,5);plt.xlim(-55,15);plt.grid() 这里没有数字问题
有趣。。。我很惊讶其他曲线看起来很好(a=0的例外情况比a=1的情况更失败)。我猜高阶粒子不会表现出奇怪的行为,因为它们收敛得很快(分母增长得很快)。遗憾的是,我没有比为`a={0,1}'的情况找到一种显示更好稳定性的替代表示法更好的建议。对于数学来说,一个好的表达方式并不一定是一个好的计算方式。是的,这很有趣!我尝试了使用
gammaln
的对数空间表示法,并将偶数和奇数分开,但a=1的曲线更糟糕。可能有一个很好的理由,但我无法理解。对于0np.polymonel.polyval(-z**a,1/gamma(a*k+1))
k = np.arange(100)
return np.polynomial.polynomial.polyval(z, 1/gamma(a*k + 1))
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import gamma
from scipy.integrate import quad
def MLf(z, a):
"""Mittag-Leffler function
"""
z = np.atleast_1d(z)
if a == 0:
return 1/(1 - z)
elif a == 1:
return np.exp(z)
elif a > 1 or all(z > 0):
k = np.arange(100)
return np.polynomial.polynomial.polyval(z, 1/gamma(a*k + 1))
# a helper for tricky case, from Gorenflo, Loutchko & Luchko
def _MLf(z, a):
if z < 0:
f = lambda x: (np.exp(-x*(-z)**(1/a)) * x**(a-1)*np.sin(np.pi*a)
/ (x**(2*a) + 2*x**a*np.cos(np.pi*a) + 1))
return 1/np.pi * quad(f, 0, np.inf)[0]
elif z == 0:
return 1
else:
return MLf(z, a)
return np.vectorize(_MLf)(z, a)
x = np.arange(-50, 10, 0.1)
plt.figure(figsize=(10,5))
for i in range(1, 5):
plt.plot(x, MLf(x, i/3), label="alpha = "+str(i/3))
plt.legend()
plt.ylim(-5, 5); plt.xlim(-55, 15); plt.grid()