在绘制 mpmath 模块而不是 scipy 中定义的函数时如何管理 "TypeError" 消息?
How to manage "TypeError" message when plotting functions defined in mpmath module instead of scipy?
为了解决我的问题,我必须使用 mpmath
模块中的 gamma 函数而不是 scipy.但是,当变量取自 numpy
array 时,我使用 matplotlib.pyplot
绘制我的函数并且 y 值应该在相同的格式。但是在这样做的过程中,我收到了 TypeError
的错误消息,抱怨从 array 到 mpf 的转换。
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import quad, dblquad
import mpmath as mp
low, up = 5.630e5, 1.167e12
alpha, threshold = 1.05 , 2.15e10
beta = 274
def g(x, low, up, beta):
return mp.gamma(-2/3) * (mp.gammainc(-2/3, beta*(x/low)**3) - mp.gammainc(-2/3, beta*(x/up)**3))
def Integrand1(x, low, up, threshold, alpha, beta):
return pow(x/threshold, alpha) * g(x, low, up, beta)
def Integrand2(x, low, up, threshold, alpha, beta):
return g(x, low, up, beta)
def PDF(x, low, up, threshold, alpha, beta):
A = quad(Integrand1, low, threshold, args=(low, up, threshold, alpha, beta))
B = quad(Integrand2, threshold, up, args=(low, up, threshold, alpha, beta))
C=(A[0]+B[0])**(-1)
y = np.piecewise(x,
[x < threshold], [lambda x: C * pow(x/threshold, alpha) * g(x, low, up, beta),
lambda x: C * g(x, low, up, beta)
]
)
return y
x_array = np.array(np.logspace(8.2, 11.8, 10))
y_array = PDF(x_array, low, up, threshold, alpha, beta)
plt.plot(x_array, y_array, color='green', linestyle='-')
plt.gca().autoscale(False)
plt.vlines([threshold],
plt.gca().get_ylim()[0], plt.gca().get_ylim()[1],
linestyles='dashed', color='k', label='')
plt.xscale("log", nonposx='clip')
plt.yscale("log", nonposy='clip')
plt.show()
Traceback (most recent call last): File "test.py", line 35, in
y_array = PDF(x_array, low, up, threshold, alpha, beta) File "test.py", line 28, in PDF
lambda x: C * g(x, low, up, beta) File "/home/username/anaconda3/lib/python3.6/site-packages/numpy/lib/function_base.py",
line 1344, in piecewise
y[condlist[k]] = item(vals, *args, **kw) File "test.py", line 27, in
[x < threshold], [lambda x: C * pow(x/threshold, alpha) * g(x, low, up, beta), File "test.py", line 13, in g
return mp.gamma(-2/3) * (mp.gammainc(-2/3, beta*(x/low)**3) - mp.gammainc(-2/3, beta*(x/up)**3)) File
"/home/username/anaconda3/lib/python3.6/site-packages/mpmath/functions/expintegrals.py",
line 141, in gammainc
a = ctx.convert(a) File "/home/username/anaconda3/lib/python3.6/site-packages/mpmath/ctx_mp_python.py",
line 662, in convert
return ctx._convert_fallback(x, strings) File "/home/username/anaconda3/lib/python3.6/site-packages/mpmath/ctx_mp.py",
line 614, in _convert_fallback
raise TypeError("cannot create mpf from " + repr(x)) TypeError: cannot create mpf from array([ 6.11259157e+09, 9.68780477e+10,
1.53541358e+12,
2.43346654e+13, 3.85678455e+14, 6.11259157e+15])
我需要知道如何 mpf 一个数组,我找到了这些页面 (How to mpf an array) and (),但我不知道如何将它们应用到我的绘图程序中。
这不是密谋。错误发生在函数 PDF
中,特别是在 np.piecewise
中。正如 documentation 所说,您传递给 piecewise
的 lambda 必须能够采用数组,因为这是 piecewise
将传递给它们的内容。
并且您的函数 g
无法接受数组,因为它使用的 mpmath 函数适用于单个浮点数。解决方案:np.vectorize
包装器:
gv = np.vectorize(g)
然后在 piecewise
.
中使用 gv
而不是 g
然后 np.piecewise
将起作用,您将能够继续处理其他错误,例如不匹配的名称 PDF_values
和 y_array
。
为了解决我的问题,我必须使用 mpmath
模块中的 gamma 函数而不是 scipy.但是,当变量取自 numpy
array 时,我使用 matplotlib.pyplot
绘制我的函数并且 y 值应该在相同的格式。但是在这样做的过程中,我收到了 TypeError
的错误消息,抱怨从 array 到 mpf 的转换。
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import quad, dblquad
import mpmath as mp
low, up = 5.630e5, 1.167e12
alpha, threshold = 1.05 , 2.15e10
beta = 274
def g(x, low, up, beta):
return mp.gamma(-2/3) * (mp.gammainc(-2/3, beta*(x/low)**3) - mp.gammainc(-2/3, beta*(x/up)**3))
def Integrand1(x, low, up, threshold, alpha, beta):
return pow(x/threshold, alpha) * g(x, low, up, beta)
def Integrand2(x, low, up, threshold, alpha, beta):
return g(x, low, up, beta)
def PDF(x, low, up, threshold, alpha, beta):
A = quad(Integrand1, low, threshold, args=(low, up, threshold, alpha, beta))
B = quad(Integrand2, threshold, up, args=(low, up, threshold, alpha, beta))
C=(A[0]+B[0])**(-1)
y = np.piecewise(x,
[x < threshold], [lambda x: C * pow(x/threshold, alpha) * g(x, low, up, beta),
lambda x: C * g(x, low, up, beta)
]
)
return y
x_array = np.array(np.logspace(8.2, 11.8, 10))
y_array = PDF(x_array, low, up, threshold, alpha, beta)
plt.plot(x_array, y_array, color='green', linestyle='-')
plt.gca().autoscale(False)
plt.vlines([threshold],
plt.gca().get_ylim()[0], plt.gca().get_ylim()[1],
linestyles='dashed', color='k', label='')
plt.xscale("log", nonposx='clip')
plt.yscale("log", nonposy='clip')
plt.show()
Traceback (most recent call last): File "test.py", line 35, in y_array = PDF(x_array, low, up, threshold, alpha, beta) File "test.py", line 28, in PDF lambda x: C * g(x, low, up, beta) File "/home/username/anaconda3/lib/python3.6/site-packages/numpy/lib/function_base.py", line 1344, in piecewise y[condlist[k]] = item(vals, *args, **kw) File "test.py", line 27, in [x < threshold], [lambda x: C * pow(x/threshold, alpha) * g(x, low, up, beta), File "test.py", line 13, in g return mp.gamma(-2/3) * (mp.gammainc(-2/3, beta*(x/low)**3) - mp.gammainc(-2/3, beta*(x/up)**3)) File "/home/username/anaconda3/lib/python3.6/site-packages/mpmath/functions/expintegrals.py", line 141, in gammainc a = ctx.convert(a) File "/home/username/anaconda3/lib/python3.6/site-packages/mpmath/ctx_mp_python.py", line 662, in convert return ctx._convert_fallback(x, strings) File "/home/username/anaconda3/lib/python3.6/site-packages/mpmath/ctx_mp.py", line 614, in _convert_fallback raise TypeError("cannot create mpf from " + repr(x)) TypeError: cannot create mpf from array([ 6.11259157e+09, 9.68780477e+10,
1.53541358e+12, 2.43346654e+13, 3.85678455e+14, 6.11259157e+15])
我需要知道如何 mpf 一个数组,我找到了这些页面 (How to mpf an array) and (
这不是密谋。错误发生在函数 PDF
中,特别是在 np.piecewise
中。正如 documentation 所说,您传递给 piecewise
的 lambda 必须能够采用数组,因为这是 piecewise
将传递给它们的内容。
并且您的函数 g
无法接受数组,因为它使用的 mpmath 函数适用于单个浮点数。解决方案:np.vectorize
包装器:
gv = np.vectorize(g)
然后在 piecewise
.
gv
而不是 g
然后 np.piecewise
将起作用,您将能够继续处理其他错误,例如不匹配的名称 PDF_values
和 y_array
。