Python:矩阵指数方程
我试图用Python实现以下等式 这是一个计算给定矩阵a和标量x的矩阵指数的方程。 当我将我的代码与scipy中的Python expm进行比较时,我的代码似乎不起作用Python:矩阵指数方程,python,matrix,numerical-analysis,Python,Matrix,Numerical Analysis,我试图用Python实现以下等式 这是一个计算给定矩阵a和标量x的矩阵指数的方程。 当我将我的代码与scipy中的Python expm进行比较时,我的代码似乎不起作用 import math import numpy as np from scipy.linalg import expm # Scalar x (will later on be for user input) x = 1 matrix = np.array([[-5, 2, 3], [2, -6, 4], [4, 5,
import math
import numpy as np
from scipy.linalg import expm
# Scalar x (will later on be for user input)
x = 1
matrix = np.array([[-5, 2, 3], [2, -6, 4], [4, 5, -9]])
# Using scipy to compute the matrix exponential (for comparison)
B = expm(matrix)
print(B)
# Defining the equation
def equation(n):
y = ((pow(x, n) * np.linalg.matrix_power(matrix, n)) / int(math.factorial(n)))
return y
# Summing the equation with finite iterations
result = sum([equation(n) for n in range(0, 1000)])
print(result)
我已经定义了矩阵matrix=np.array([[-5,2,3],[2,-6,4],[4,5,-9]])
,通过scipy的expm函数,我得到了输出:
[[0.3659571 0.35453832 0.27950458]
[0.36527461 0.35510049 0.27962489]
[0.36551524 0.35489926 0.27958549]]
但我对方程的实现给了我:
[[282.7927229097503 439.9138578271309 2167.1107527813792]
[548.8430305150805 -1876.4510112837029 1328.9683527937962]
[1753.0719360816013 3838.501983853133 -5590.574633487889]]
我已经盯着我的代码看了好几个小时了,但我最近才学会Python,所以我的技能非常有限。这是因为精度的损失。事实证明,矩阵指数运算需要太多的项才能收敛(在本例中约为35),矩阵M^35已经分解了整数。使用相同的算法,让我们看看Julia是如何做到的:
julia> M = [-5 2 3; 2 -6 4; 4 5 -9]
3×3 Array{Int64,2}:
-5 2 3
2 -6 4
4 5 -9
julia> exp(M)
3×3 Array{Float64,2}:
0.365957 0.354538 0.279505
0.365275 0.3551 0.279625
0.365515 0.354899 0.279585
julia> term = (n) -> (M^n)/factorial(big(n))
#1 (generic function with 1 method)
julia> sum(term, 0:40)
3×3 Array{BigFloat,2}:
282.793 439.914 2167.11
548.843 -1876.45 1328.97
1753.07 3838.5 -5590.57
julia> M^20
3×3 Array{Int64,2}:
8757855768227185495 5428672870161680643 4260215435320685478
2846510725988846806 -6309877790968251876 3463367064979405070
1252813985306285990 3038127759137839419 -4290941744444125409
julia> M = Matrix{Int128}(M)
3×3 Array{Int128,2}:
-5 2 3
2 -6 4
4 5 -9
julia> M^20
3×3 Array{Int128,2}:
691287386495480595287 1259807269882411190531 -1951094656377891785818
1423245804401624321238 2594681036602078525980 -4017926841003702847218
-2710418564849997801562 -4940689283995021993669 7651107848845019795231
julia> sum(term, 0:40)
3×3 Array{BigFloat,2}:
0.365246 0.353079 0.28076
0.363873 0.353114 0.283013
0.367464 0.358922 0.305631
从上面可以看出,当矩阵位于Int64和Int128中时,M^20
的差别很大。实际上,它会悄悄地溢出整数,而不会引发异常。如果你把这些条件加起来,这也是你得到错误答案的原因
不幸的是,numpy没有像Julia那样的int128类型。但我们有128辆。因此,让我们修改您的代码,改为使用float128:
来自scipy.linalg导入expm的>>
>>>将numpy作为np导入
>>>输入数学
>>>M=np.数组([-5,2,3],[2,-6,4],[4,5,-9]]
>>>M
数组([-5,2,3],
[ 2, -6, 4],
[ 4, 5, -9]])
>>>expm(M)
数组([[0.3659571,0.35453832,0.2795058],
[0.36527461, 0.35510049, 0.27962489],
[0.36551524, 0.35489926, 0.27958549]])
>>>np.linalg.matrix_幂(M,20)
数组([[8757855768227185495154286728701616806434260215435320685478],
[ 2846510725988846806, -6309877790968251876, 3463367064979405070],
[ 1252813985306285990, 3038127759137839419, -4290941744444125409]])
>>>term=lambda n:np.linalg.matrix_幂(M,n)/float(数学阶乘(n))
>>>总和([范围(40)内n的项(n)])
数组([[282.79272291439.913857832167.11075278],
[ 548.84303052, -1876.45101128, 1328.96835279],
[ 1753.07193608, 3838.50198385, -5590.57463349]])
>>>M=M.astype('float128')
>>>M
数组([-5,2,3.],
[ 2., -6., 4.],
[4,5.,-9.],数据类型=128)
>>>np.linalg.matrix_幂(M,20)
阵列([[6.91287386e+20,1.25980727e+21,-1.95109466e+21],
[1.42324580e+21,2.59468104e+21,-4.01792684e+21],
[2.71041856e+21,-4.94068928e+21,7.65110785e+21],
dtype=128)
>>>总和([范围(40)内n的项(n)])
数组([[0.36595003,0.35452543,0.27952454],
[0.36526005, 0.35507395, 0.279666 ],
[0.36554297,0.35494981,0.27950722]],数据类型=float128)
同样,当数据类型不同时,可以看到矩阵M
增加到20次方的差异。通过使用float,您失去了一些精度,但是您不会提前溢出并得到正确的答案,至少对于这个特定的矩阵
经验教训:如果scipy为您提供功能,请不要实现您自己的功能。人们在库中实现它是有原因的。|首先尝试svd可能会有助于解决数字错误。非常感谢您,adrtam!我一定会问我的教授,他为什么要我们实现自己的功能,因为我知道这会发生。我想知道我班上的其他学生是如何处理这件事的。也谢谢你的解释。它确实帮助我理解了这个问题和它的技术细节。