Блокировать тридиагональную матрицу python

Я хотел бы создать трехдиагональную матрицу, начиная с трех numpy.ndarray. Есть ли какой-либо (прямой) способ сделать это в python?

Заранее спасибо!

ура

С «регулярными» массивами 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) 

Вы также можете сделать это с помощью «регулярных» массивов 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_ если вы хотите быть более краткими. Например, вместо data[np.arange(3)+4, np.arange(3)] используйте 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]] 

Ответ @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.]]) 

Используйте функцию 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.]]) 

Поскольку тридиагональная матрица является разреженной матрицей с использованием разреженного пакета, это может быть хорошим вариантом, см. http://pysparse.sourceforge.net/spmatrix.html#matlab-implementation , есть примеры и сравнения с MATLAB даже …

Мой ответ строит ответ @ TheCorwoodRep. Я просто разместил его, потому что сделал несколько изменений, чтобы сделать его более модульным, чтобы он работал для разных порядков матриц, а также изменял значения 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)