在python 3上乘以矩阵

时间:2017-06-21 16:50:11

标签: python numpy matrix

有谁知道我为什么会得到错误的结果?我知道代码的最后一行有一个错误,即f = p0 * pn * p

import numpy as np

def passage(n,i,j):
    # this function calculate the first time passage distribution after n 
    #steps starting at i and end at j.

    p=np.matrix([[0,1,0,0],[0.5,0,0.5,0],[0,.5,0,.5],[0,0,1,0]])

    p0=p[:]
    for k in range(len(p)): # let elements in column j be zeros
        p0[k,j]=0

    p1=p0[:]
    for k in range(len(p)): #let element in column j and row j be zeros 
        p1[j,k]=0

    pn=np.linalg.matrix_power(p1,n-2)


    f=p0*pn*p      # this line gives us wrong result. why


    return f

2 个答案:

答案 0 :(得分:1)

一个潜在的问题来源:

p0=p[:]

生成view,而不是copy。这意味着在这2个循环(可能无需循环编写)之后,pp0p1具有相同的值。

您是否确实逐行测试了此代码,确保每个步骤都正确无误?当我用Python编写函数时,尤其是numpy以交互方式测试所有步骤。

另一件事 - 除非你真的需要它,否则不要使用np.matrix。在创建数组时坚持np.array,甚至是2d。如果需要矩阵乘法,请使用np.dot(或@)。

快速重写您的功能:

def passage(n,i,j):
    p=np.array([[0,1,0,0],[0.5,0,0.5,0],[0,.5,0,.5],[0,0,1,0]])
    p0=p.copy()
    p0[:,j] = 0
    p1=p0.copy()
    p1[j,:] = 0
    pn=np.linalg.matrix_power(p1,n-2)
    f = p0@pn@p    # or p0.dot(pn.dot(p))
    return f

In [15]: passage(4,0,0)
Out[15]: 
array([[ 0.125 ,  0.    ,  0.375 ,  0.    ],
       [ 0.    ,  0.1875,  0.    ,  0.1875],
       [ 0.1875,  0.    ,  0.5625,  0.    ],
       [ 0.    ,  0.375 ,  0.    ,  0.375 ]])

答案 1 :(得分:0)

解决方案是使用np.copy()复制您的p矩阵。

p0 = np.copy(p)
p1 = np.copy(p0)

如果您仍然没有得到预期答案,那么您可能需要查看np.dot()np.matmul()

另请注意,PEP465引入了@作为矩阵乘法运算符。