2017-10-18 318 views
1

在Matlab中/八度音功能不是,spdiags([-8037.500 50.000 -12.500], 0:2, 1, 51)給出以下輸出:spdiags()如預期工作在Python

(1, 1) -> -8037.5 
(1, 2) -> 50 
(1, 3) -> -12.500 

然而,當我使用在Python下面,它不會產生類似的結果作爲在Matlab /八度:

​​

Python的spdiags()產生下面的輸出,這是在缺少一號50-12.5條款和第二指數:

array([[-8037.5,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , 
      0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , 
      0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , 
      0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , 
      0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , 
      0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , 
      0. ,  0. ,  0. ,  0. ,  0. ,  0. ,  0. , 
      0. ,  0. ]]) 

我看了一下this對一個類似問題的回答,但我不確定我哪裏出錯了。

編輯:

我想建立如下圖所示的是由A_diag1A_diag2A_diag3矩陣A。按照答案中的建議,我定義了A_diag1A_diag3

import numpy as np 
import scipy as sp 
A_diag1 = np.tile(np.array([-8037.500, 50, -12.5]), (3,1)) 
A_diag2 = np.reshape(np.repeat([1250, -18505, 1250], 49), (3, 49)) 
A_diag3 = np.tile(np.array([12.5, -50, 8037.500]), (3,1)) 
A = np.concatenate((sp.sparse.spdiags(A_diag1, np.r_[0:2 + 1], 1, 51).toarray(), \ 
       sp.sparse.spdiags(A_diag2, np.r_[0:2 + 1], 49, 51).toarray(), \ 
       sp.sparse.spdiags(A_diag3, np.r_[48:50 + 1], 1, 51).toarray()), axis=0) 

然而,五顯現細胞在過去的3行和A列顯示爲零/單數顯示在下面的快照。我預計當前顯示爲零的突出顯示的單元格不爲零。 [您可以複製並粘貼上面的代碼片段以再現A矩陣,從中可以獲取如下所示的快照。]

enter image description here

EDIT2:

繼使用sp.sparse.diags()按預期工作代碼。與sp.sparse.spdiags不同,使用sp.sparse.diags()時,輸入參數的結果形狀(數組維數)必須在列表中。

import numpy as np 
import scipy as sp 
A_diag1 = np.array([[-8037.500], [50], [-12.5]]) 
A_diag2 = np.reshape(np.repeat([1250, -18505, 1250], 49), (3, 49)) 
A_diag3 = np.array([[12.5], [-50], [8037.500]]) 
A = np.concatenate((sp.sparse.diags(A_diag1, np.arange(0, 2 + 1), [1, 51]).toarray(), \ 
sp.sparse.diags(A_diag2, np.arange(0, 2 + 1), [49, 51]).toarray(), \ 
sp.sparse.diags(A_diag3, np.arange(48, 50 + 1), [1, 51]).toarray()), axis=0) 

回答

3

這使得一個稀疏矩陣(51.1),具有值向下每一行:

In [5]: sparse.spdiags(data,[0,-1,-2],51,1) 
Out[5]: 
<51x1 sparse matrix of type '<class 'numpy.float64'>' 
    with 3 stored elements (3 diagonals) in DIAgonal format> 
In [6]: print(_) 
    (0, 0) -8037.5 
    (1, 0) 50.0 
    (2, 0) -12.5 

注意,spdiags定義:

數據:存儲array_like 矩陣對角線行嚮明智的

稀疏diagonal format將其數據存儲在矩陣中,其中的一部分可以是「屏幕外」。所以使用起來有點棘手。我通常使用coo類型的輸入創建矩陣。

In [27]: M =sparse.spdiags(data,[0,-1,-2],3,3) 
In [28]: M.A 
Out[28]: 
array([[-8037.5,  0. ,  0. ], 
     [ 50. ,  0. ,  0. ], 
     [ -12.5,  0. ,  0. ]]) 
In [29]: M.data 
Out[29]: 
array([[-8037.5], 
     [ 50. ], 
     [ -12.5]]) 
In [30]: M.offsets 
Out[30]: array([ 0, -1, -2], dtype=int32) 

你想要的是它的轉置(也許)

In [32]: Mt = M.T 
In [33]: Mt.A 
Out[33]: 
array([[-8037.5, 50. , -12.5], 
     [ 0. ,  0. ,  0. ], 
     [ 0. ,  0. ,  0. ]]) 
In [34]: Mt.data 
Out[34]: 
array([[-8037.5,  0. ,  0. ], 
     [ 0. , 50. ,  0. ], 
     [ 0. ,  0. , -12.5]]) 
In [35]: Mt.offsets 
Out[35]: array([0, 1, 2], dtype=int32) 

因此,我們可以重新Mt有:

sparse.spdiags(Mt.data, Mt.offsets, 3,3) 

如果我救了八度矩陣並加載它,我得到:

In [40]: loadmat('diags') 
Out[40]: 
{'__globals__': [], 
'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.0.0, 2017-10-19 01:24:58 UTC', 
'__version__': '1.0', 
'x': <1x51 sparse matrix of type '<class 'numpy.float64'>' 
    with 3 stored elements in Compressed Sparse Column format>} 
In [42]: X=_['x'] 
In [43]: print(X) 
    (0, 0) -8037.5 
    (0, 1) 50.0 
    (0, 2) -12.5 

如果我把它轉換爲dia格式我得到類似Mt

In [48]: sparse.dia_matrix(X) 
Out[48]: 
<1x51 sparse matrix of type '<class 'numpy.float64'>' 
    with 3 stored elements (3 diagonals) in DIAgonal format> 
In [49]: print(_) 
    (0, 0) -8037.5 
    (0, 1) 50.0 
    (0, 2) -12.5 
In [50]: _.data, _.offsets 
Out[50]: 
(array([[-8037.5,  0. ,  0. ], 
     [ 0. , 50. ,  0. ], 
     [ 0. ,  0. , -12.5]]), array([0, 1, 2])) 

sparse.diags功能可能更直觀:

In [92]: sparse.diags(data, [0,1,2],(1,3)) 
Out[92]: 
<1x3 sparse matrix of type '<class 'numpy.float64'>' 
    with 3 stored elements (3 diagonals) in DIAgonal format> 
In [93]: _.A 
Out[93]: array([[-8037.5, 50. , -12.5]]) 
In [94]: print(__) 
    (0, 0) -8037.5 
    (0, 1) 50.0 
    (0, 2) -12.5 

In [56]: sp1 = sparse.spdiags(A_diag1, np.r_[0:2 + 1], 1, 51) 
In [57]: sp2 = sparse.spdiags(A_diag2, np.r_[0:2 + 1], 49, 51) 
In [58]: sp3 = sparse.spdiags(A_diag3, np.r_[48:50 + 1], 1, 51) 

(該r_表達式也可以是np.arange(0,3)np.arange(48,51)

這些可以sparse.vstack加盟(它結合了coo格式屬性)

In [69]: B = sparse.vstack((sp1,sp2,sp3)) 
    In [72]: B 
    Out[72]: 
    <51x51 sparse matrix of type '<class 'numpy.float64'>' 
     with 147 stored elements in COOrdinate format> 

In [75]: B.tocsr()[45:, 46:].A 
Out[75]: 
array([[ 1250.,  0.,  0.,  0.,  0.], 
     [-18505., 1250.,  0.,  0.,  0.], 
     [ 1250., -18505., 1250.,  0.,  0.], 
     [  0., 1250., -18505.,  0.,  0.], 
     [  0.,  0., 1250.,  0.,  0.], 
     [  0.,  0.,  0.,  0.,  0.]]) 

快照匹配。 (我仍然需要弄清楚你正在創建什麼)。

sparse.spdiags(data, diags, m, n)是調用sparse.dia_matrix((data, diags), shape=(m,n))

再回到sparse.diags,如果你想3個對角線,每個充滿了來自data一個值,我們可以用另一種方式:

​​

所以sp1將有看起來像

In [117]: B.tocsr()[0,:].todia().data 
Out[117]: 
array([[-8037.5,  0. ,  0. ], 
     [ 0. , 50. ,  0. ], 
     [ 0. ,  0. , -12.5]]) 
+0

謝謝。你能否看看爲什麼在編輯下描述的矩陣'A'沒有按預期給出正確的輸出? – user11

+1

'sparse.diags'可能是您想要使用的函數,而不是'spdiags'。 – hpaulj

+0

是的,'sp.sparse.diags'按照建議運行良好。謝謝。 – user11

1

我對你的觀察沒有解釋(沒有太大的MATLAB用戶的,但我可以證實,倍頻是做什麼像你說的),但以下SciPy的的example-usage,則可以使用達到這一結果:

import numpy as np 
import scipy.sparse as sp 

data = np.tile(np.array([-8037.5, 50., -12.5]), (3,1)) 
x = sp.spdiags(data, np.arange(3), 1, 51) 

print(x) 

輸出:

(0, 0)  -8037.5 
(0, 1)  50.0 
(0, 2)  -12.5 

瓦片步驟構建:

[[-8037.5 50. -12.5] 
[-8037.5 50. -12.5] 
[-8037.5 50. -12.5]] 

當然,一切都是基於0索引的。

+0

你可以建議如何使其工作時,添加在en d喜歡跟隨,因爲它在末尾連接時不起作用? 'A = np.concatenate(your_solved_matrix,\ sp.sparse.spdiags(diagA_innerPts,np.r_ [0:2 + 1],49,51)。toarray(),\ your_solved_matrix ),axis = 0)' – user11

+0

不能跟着你,但是你調用numpy的連接(對於密集的numpy數組),而你可能想要scipy的'''sparse.hstack'' '或'''sparse.vstack'''在混合這兩種非常不同的類型時要小心。 – sascha

+0

如果您仍然需要更多說明,請讓我知道。謝謝。 – user11