2011-04-30 7 views
11

मैं तीन numpy.ndarray से शुरू एक ब्लॉक tridiagonal मैट्रिक्स बनाना चाहता हूँ। क्या अजगर में ऐसा करने के लिए कोई (प्रत्यक्ष) तरीका है?ब्लॉक tridiagonal मैट्रिक्स पायथन

अग्रिम धन्यवाद!

चीयर्स

+1

आप परिणाम एक और ndarray होना चाहते हैं, या आप परिणाम के लिए एक विरल सरणी का उपयोग कर के लिए खुले हैं क्या? – talonmies

उत्तर

0

के बाद से tridiagonal मैट्रिक्स एक विरल मैट्रिक्स एक विरल पैकेज का उपयोग एक अच्छा विकल्प हो सकता है, को देखने के http://pysparse.sourceforge.net/spmatrix.html#matlab-implementation, वहाँ कुछ उदाहरण और MATLAB के साथ तुलना कर रहे हैं यहां तक ​​कि ...

7

तुम भी ऐसा कर सकते हैं है फैंसी अनुक्रमण के माध्यम से "नियमित" NumPy सरणी के साथ:

import numpy as np 
data = np.zeros((10,10)) 
data[np.arange(5), np.arange(5)+2] = [5, 6, 7, 8, 9] 
data[np.arange(3)+4, np.arange(3)] = [1, 2, 3] 
print data 

(आप उन कॉल np.arange को np.r_ साथ यदि आप अधिक संक्षिप्त बनना चाहता थाके बजाय बदल सकते उदा। 03,210, data[np.r_[:3]+4, np.r_[:3]] का उपयोग करें)

यह पैदावार:

[[0 0 5 0 0 0 0 0 0 0] 
[0 0 0 6 0 0 0 0 0 0] 
[0 0 0 0 7 0 0 0 0 0] 
[0 0 0 0 0 8 0 0 0 0] 
[1 0 0 0 0 0 9 0 0 0] 
[0 2 0 0 0 0 0 0 0 0] 
[0 0 3 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]] 

हालांकि, अगर आप वैसे भी विरल मैट्रिक्स का उपयोग किया जा रहे हैं, scipy.sparse.spdiags पर एक नजर है। (ध्यान दें कि आप अगर आप एक सकारात्मक मूल्य (जैसे 3 उदाहरण में स्थान 4 के) के साथ एक विकर्ण की स्थिति में डेटा डाल रहे हैं अपनी पंक्ति मूल्यों पर नकली डेटा आगे जोड़ते करने की आवश्यकता होगी) एक त्वरित रूप

उदाहरण:

import numpy as np 
import scipy as sp 
import scipy.sparse 

diag_rows = np.array([[1, 1, 1, 1, 1, 1, 1], 
         [2, 2, 2, 2, 2, 2, 2], 
         [0, 0, 0, 0, 3, 3, 3]]) 
positions = [-3, 0, 4] 
print sp.sparse.spdiags(diag_rows, positions, 10, 10).todense() 

यह पैदावार:

[[2 0 0 0 3 0 0 0 0 0] 
[0 2 0 0 0 3 0 0 0 0] 
[0 0 2 0 0 0 3 0 0 0] 
[1 0 0 2 0 0 0 0 0 0] 
[0 1 0 0 2 0 0 0 0 0] 
[0 0 1 0 0 2 0 0 0 0] 
[0 0 0 1 0 0 2 0 0 0] 
[0 0 0 0 1 0 0 0 0 0] 
[0 0 0 0 0 1 0 0 0 0] 
[0 0 0 0 0 0 1 0 0 0]] 
+0

धन्यवाद दोस्तों! –

19
"नियमित" NumPy सरणी के साथ

, numpy.diag का उपयोग कर:

def tridiag(a, b, c, k1=-1, k2=0, k3=1): 
    return np.diag(a, k1) + np.diag(b, k2) + np.diag(c, k3) 

a = [1, 1]; b = [2, 2, 2]; c = [3, 3] 
A = tridiag(a, b, c) 
0

मेरा उत्तर @ TheCorwoodRep के उत्तर का निर्माण करता है। मैं इसे सिर्फ पोस्ट कर रहा हूं क्योंकि मैंने इसे अधिक मॉड्यूलर बनाने के लिए कुछ बदलाव किए हैं ताकि यह matrices के विभिन्न आदेशों के लिए काम करे और k1, k2, k3 यानी यह निर्धारित करने के लिए कि कौन सा विकर्ण दिखाई देता है, स्वचालित रूप से अतिप्रवाह। फ़ंक्शन को कॉल करते समय आप निर्दिष्ट कर सकते हैं कि विकर्णों पर कौन से मान दिखने चाहिए।

import numpy as np 
def tridiag(T,x,y,z,k1=-1, k2=0, k3=1): 
    a = [x]*(T-abs(k1)); b = [y]*(T-abs(k2)); c = [z]*(T-abs(k3)) 
    return np.diag(a, k1) + np.diag(b, k2) + np.diag(c, k3) 

D=tridiag(10,-1,2,-1) 
2

@TheCorwoodRep के जवाब वास्तव में एक पंक्ति में किया जा सकता है। एक अलग समारोह की कोई ज़रूरत नहीं है।

np.eye(3,3,k=-1) + np.eye(3,3)*2 + np.eye(3,3,k=1)*3 

यह पैदा करता है:

array([[ 2., 3., 0.], 
     [ 1., 2., 3.], 
     [ 0., 1., 2.]]) 
2

समारोह scipy.sparse.diags का प्रयोग करें।

उदाहरण:

from scipy.sparse import diags 
import numpy as np 
# 
n = 10 
k = np.array([np.ones(n-1),-2*np.ones(n),np.ones(n-1)]) 
offset = [-1,0,1] 
A = diags(k,offset).toarray() 

यह रिटर्न:

array([[-2., 1., 0., 0., 0.], 
     [ 1., -2., 1., 0., 0.], 
     [ 0., 1., -2., 1., 0.], 
     [ 0., 0., 1., -2., 1.], 
     [ 0., 0., 0., 1., -2.]]) 
संबंधित मुद्दे