更直观的方法来填充对角矢量的三个元素

时间:2017-04-01 15:24:45

标签: python

我需要填写图中的矩阵。我的方法是使用非东读的循环。当尺寸很大时,效率也不高。 有没有办法让它更容易阅读,可能更快(比如使用矢量化或某些我不知道的功能?)

enter image description here

# The code is in python, but I am open to R as well.    
    S=6
    p=[0.1,0.3,0.6] # the pi in the figure
    # The reason I use loop for p is that it handles a flexible dimension of p
    mat = np.zeros((S, S))
    p = np.array(p) 
    for i in range(S):
        for j, x in enumerate(p): 
                if i + j < S-1:
                    mat[i+j][i] = x

                elif i + j == S-1:
                    mat[S-1][i] = p[j:].sum()
                else:
                    pass

    mat.T

2 个答案:

答案 0 :(得分:1)

以下是一个示例 - 填写您需要的值(并调整最终列)...

mat <- matrix(0,nrow=10,ncol=10)
diag(mat) <- 1
diag(mat[1:(ncol(mat)-1),-1]) <- 2
diag(mat[1:(ncol(mat)-2),-(1:2)]) <- 3

mat
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    2    3    0    0    0    0    0    0     0
 [2,]    0    1    2    3    0    0    0    0    0     0
 [3,]    0    0    1    2    3    0    0    0    0     0
 [4,]    0    0    0    1    2    3    0    0    0     0
 [5,]    0    0    0    0    1    2    3    0    0     0
 [6,]    0    0    0    0    0    1    2    3    0     0
 [7,]    0    0    0    0    0    0    1    2    3     0
 [8,]    0    0    0    0    0    0    0    1    2     3
 [9,]    0    0    0    0    0    0    0    0    1     2
[10,]    0    0    0    0    0    0    0    0    0     1

答案 1 :(得分:1)

与往常一样,有许多等效的方法来构建矩阵。当我第一次看到它时,我想“哦,它就像是Toeplitz的顶部”,但是对p中的对角线求和也应该有效(注意我已经包含了右下角的变化)。一些谷歌搜索透露了另一种方式,使用scipy.sparse.diags

import numpy as np
import scipy.sparse
from scipy.linalg import triu, toeplitz

def build_toep(S, p):
    out = triu(toeplitz(p + [0]*(S-len(p))))
    out[-2:,-1] = [1 - p[1], 1]
    return out

def build_diag(S, p):
    out = sum(np.diag([v]*(S-i), i) for i,v in enumerate(p))
    out[-2:,-1] = [1 - p[1], 1]
    return out

def build_sparse(S, p):
    out = scipy.sparse.diags(p, range(len(p)), shape=(S, S)).toarray()
    out[-2:,-1] = [1 - p[1], 1]
    return out

给出了

In [150]: S, p = 6, [0.1, 0.3, 0.6]

In [151]: build_toep(S, p)
Out[151]: 
array([[ 0.1,  0.3,  0.6,  0. ,  0. ,  0. ],
       [ 0. ,  0.1,  0.3,  0.6,  0. ,  0. ],
       [ 0. ,  0. ,  0.1,  0.3,  0.6,  0. ],
       [ 0. ,  0. ,  0. ,  0.1,  0.3,  0.6],
       [ 0. ,  0. ,  0. ,  0. ,  0.1,  0.7],
       [ 0. ,  0. ,  0. ,  0. ,  0. ,  1. ]])

In [152]: np.allclose(build_toep(S, p), build_diag(S, p))
Out[152]: True

In [153]: np.allclose(build_toep(S, p), build_sparse(S, p))
Out[153]: True