我想为具有n个点的等式系统构建块矩阵。 结果是(2n + 2)x(2n + 2)矩阵。例如,对于2个点,矩阵是:
1 0 0 0 0 0
a b c d 0 0
e f g h 0 0
0 0 a b c d
0 0 e f g h
0 0 0 0 0 1
对于3分,矩阵是
1 0 0 0 0 0 0 0
a b c d 0 0 0 0
e f g h 0 0 0 0
0 0 a b c d 0 0
0 0 e f g h 0 0
0 0 0 0 a b c d
0 0 0 0 e f g h
0 0 0 0 0 0 0 1
这里,a,b,c,d,e,f,g,h是提前已知的浮点值。 但我不提前知道n的价值。在python中有一个库可以做到这一点吗?我看过scipy.sparse.diag,scipy.linalg.block_diag和numpy.bat,但这些都达不到我想要的效果。
答案 0 :(得分:1)
我们可以使用np.identity
为我们提供一个" square"数组(两个轴的尺寸相同),指定的是1和0:
myarr = np.identity(2*n+2)
然后,我们为a-h定义了我们的小子集值:
subset = np.array([[a,b,c,d],[e,f,g,h]])
现在替换更大数组中的相应值:
for i in range(1, 2*n+2-1, 2):
myarr[i:i+2, i-1:i+3] = subset
编辑:这是我为a-h选择的一些随机值的输出:
>>> myarr = np.identity(2*n+2)
>>> subset = np.array([[a,b,c,d],[e,f,g,h]])
>>> for i in range(1, 2*n+2-1, 2):
... myarr[i:i+2, i-1:i+3] = subset
...
>>> myarr
array([[ 1., 0., 0., 0., 0., 0., 0., 0.],
[ 11., 2., 3., 4., 0., 0., 0., 0.],
[ 5., 6., 7., 9., 0., 0., 0., 0.],
[ 0., 0., 11., 2., 3., 4., 0., 0.],
[ 0., 0., 5., 6., 7., 9., 0., 0.],
[ 0., 0., 0., 0., 11., 2., 3., 4.],
[ 0., 0., 0., 0., 5., 6., 7., 9.],
[ 0., 0., 0., 0., 0., 0., 0., 1.]])
答案 1 :(得分:0)
这是一种在broadcasted manner
中计算这些线性指数然后分配到zeros-initialized
数组中的方法 -
def block_mat(list_, n = 2):
input_arr = np.array(list_).reshape(-1,4)
N = 2*n + 2
M = 2*N + 2
p,q = input_arr.shape
I,J,K = np.ix_(M*np.arange(n), N*np.arange(p), np.arange(q))
idx = I + J + K + N
out = np.zeros((N,N),dtype=input_arr.dtype)
out.flat[idx] = input_arr
out.flat[[0,-1]] = 1
return out
样品运行 -
1)输入元素:
In [497]: a,b,c,d,e,f,g,h = range(3,11)
In [498]: a,b,c,d,e,f,g,h
Out[498]: (3, 4, 5, 6, 7, 8, 9, 10)
2)各种n
案例:
In [499]: block_mat([a,b,c,d,e,f,g,h], n = 2)
Out[499]:
array([[ 1, 0, 0, 0, 0, 0],
[ 3, 4, 5, 6, 0, 0],
[ 7, 8, 9, 10, 0, 0],
[ 0, 0, 3, 4, 5, 6],
[ 0, 0, 7, 8, 9, 10],
[ 0, 0, 0, 0, 0, 1]])
In [500]: block_mat([a,b,c,d,e,f,g,h], n = 3)
Out[500]:
array([[ 1, 0, 0, 0, 0, 0, 0, 0],
[ 3, 4, 5, 6, 0, 0, 0, 0],
[ 7, 8, 9, 10, 0, 0, 0, 0],
[ 0, 0, 3, 4, 5, 6, 0, 0],
[ 0, 0, 7, 8, 9, 10, 0, 0],
[ 0, 0, 0, 0, 3, 4, 5, 6],
[ 0, 0, 0, 0, 7, 8, 9, 10],
[ 0, 0, 0, 0, 0, 0, 0, 1]])
In [501]: block_mat([a,b,c,d,e,f,g,h], n = 4)
Out[501]:
array([[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 3, 4, 5, 6, 0, 0, 0, 0, 0, 0],
[ 7, 8, 9, 10, 0, 0, 0, 0, 0, 0],
[ 0, 0, 3, 4, 5, 6, 0, 0, 0, 0],
[ 0, 0, 7, 8, 9, 10, 0, 0, 0, 0],
[ 0, 0, 0, 0, 3, 4, 5, 6, 0, 0],
[ 0, 0, 0, 0, 7, 8, 9, 10, 0, 0],
[ 0, 0, 0, 0, 0, 0, 3, 4, 5, 6],
[ 0, 0, 0, 0, 0, 0, 7, 8, 9, 10],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])
答案 2 :(得分:0)
以下是适合您的代码:
import string
n = 3
letters = string.ascii_lowercase
block1 = letters[:4]
block2 = letters[4:8]
matrix = [[1 if b == 0 and i == 0 or b == 2*n+1 and i == 2*n + 1 else 0 for b in range(2*n+2)] for i in range(2*n+2)]
count = 0
for i, a in enumerate(matrix[1:-1]): #fix to account for the fact that we are starting at 2, not 0
if i%2 == 0:
matrix[i+1][count:count+4] = list(block1)
else:
matrix[i+1][count:count+4] = list(block2)
count += 2
for i in matrix:
print i
当n == 3时的输出:
[1, 0, 0, 0, 0, 0, 0, 0]
['a', 'b', 'c', 'd', 0, 0, 0, 0]
['e', 'f', 'g', 'h', 0, 0, 0, 0]
[0, 0, 'a', 'b', 'c', 'd', 0, 0]
[0, 0, 'e', 'f', 'g', 'h', 0, 0]
[0, 0, 0, 0, 'a', 'b', 'c', 'd']
[0, 0, 0, 0, 'e', 'f', 'g', 'h']
[0, 0, 0, 0, 0, 0, 0, 1]
当n == 2时的输出:
[1, 0, 0, 0, 0, 0]
['a', 'b', 'c', 'd', 0, 0]
['e', 'f', 'g', 'h', 0, 0]
[0, 0, 'a', 'b', 'c', 'd']
[0, 0, 'e', 'f', 'g', 'h']
[0, 0, 0, 0, 0, 1]
我意识到你实际上并没有使用字符串“a”,“b”,“c”等,但是当你想使用变量时,将block1
替换为前四个变量的列表和block2
以及最近四个变量的列表。