Python:矩阵指数方程

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,

我试图用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, -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!我一定会问我的教授,他为什么要我们实现自己的功能,因为我知道这会发生。我想知道我班上的其他学生是如何处理这件事的。也谢谢你的解释。它确实帮助我理解了这个问题和它的技术细节。