如何修复在使用数组参数进行积分时“只能将长度为1的数组转换为Python标量”
我正在使用scipy.integrate中的quad来获取对象有限范围内的积分。假设目标对象处于打击中:如何修复在使用数组参数进行积分时“只能将长度为1的数组转换为Python标量”,python,numpy,scipy,integrate,quad,Python,Numpy,Scipy,Integrate,Quad,我正在使用scipy.integrate中的quad来获取对象有限范围内的积分。假设目标对象处于打击中: ∫expm(A*X).expm(B*X)dx 其中A和B都是numpy矩阵 为了解决这个问题,我使用了blow代码: from scipy.integrate import quad from scipy.linalg import expm import numpy as np def integrand(X, A, B): return np.dot(expm(A*X),ex
∫expm(A*X).expm(B*X)dx
其中A和B都是numpy矩阵
为了解决这个问题,我使用了blow代码:
from scipy.integrate import quad
from scipy.linalg import expm
import numpy as np
def integrand(X, A, B):
return np.dot(expm(A*X),expm(B*X))
A = np.array([[1, 2], [3, 4]])
B = np.array([[1, 2], [3, 4]])
I= quad(integrand, 0, 1, args=(A,B))
但对于结果,我得到了以下错误:
TypeError: only length-1 arrays can be converted to Python scalars
我知道,当函数需要一个值,而您传递的是一个数组时,会出现将仅长度为1的数组转换为Python标量的错误。但我的问题是基于数组的。那么我该如何修复它。正如注释中所指出的,quad需要一个标量函数。通过将索引添加为输出,始终可以将函数传递给标量:
def integrand(X, A, B, ix=None):
""" pass ix=None to return the matrix, ix = 0,1,2,3 to return an element"""
output = np.dot(expm(A*X),expm(B*X))
if ix is None:
return output
i, j = ix//2, ix%2
return output[i,j]
I= np.array([quad(integrand, 0, 1, args=(A,B, i))[0]
for i in range(4)]).reshape(2,2)
I
>>array([[1031.61668602, 1502.47836021],
[2253.71754031, 3285.33422634]])
请注意,这是非常低效的,因为您要计算4次积分,只要这不打扰您
或者,使用trapz:
进行矢量化计算。事实上,expm只适用于方阵,而不适用于方阵列表,这需要对矩阵形状进行一些处理
从四边形导入四边形
将numpy作为np导入
从scipy.linalg导入expm
A=np.数组[[1,2],[3,4]]
B=np.数组[[1,2],[3,4]]
def integrandX:
expAX=np.array[expmA*x表示x中的x]
expAX=np.moveaxisexpAX,0,-1
expBX=np.array[expmB*x代表x中的x]
expBX=np.moveaxisexpBX,0,-1
返回np.einsumij…,jk…->ik…,expAX,expBX
val,err=quad被积函数,0,1
printval
仔细检查有关quad函数参数的文档。@hpaulj您能给我推荐一个合适的文档吗?您不知道在哪里可以找到您使用的Python代码的文档吗?你们是怎么找到如何调用quad的?好吧,让我们更明确一点,quad集成了一个标量函数。你的函数返回一个数组。我不太会使用“quad”,我是通过搜索并阅读“scipy”网站上的相关文档找到它的。但它们只是一个简单的例子。如果我说你能推荐我吗,我指的是更详细的文件@hpauljyes我用你的想法通过索引来解决这个问题,但是对于大型矩阵和更复杂的集成来说,它太慢了。所以我用另一种方式尝试了你的推荐,速度提高了。它真的很有用而且很棒
x_i = np.linspace(0,1,60)
np.trapz([integrand(x, A, B) for x in x_i], x=x_i, axis=0)
>>array([[1034.46472361, 1506.62915374],
[2259.94373062, 3294.40845422]])
[[1031.61668602 1502.47836021]
[2253.71754031 3285.33422633]]