Matlab中的扩展分块对角矩阵
Extended block diagonal matrix in Matlab
我知道要在 Matlab 中生成一个 block-diagonal 矩阵,命令 blkdiag
会生成这样一个矩阵:
现在我面临生成相同的 block-diagonal 矩阵,但在上对角线上还有矩阵元素 B_1
、B_2
、...、B_{n-1}
,其他地方为零:
- 我想这可以用循环硬编码,但我想找到一个更优雅的解决方案。关于如何实现这样的事情有什么想法吗?
P.S。我 diag
命令,使用 diag(A,k)
returns 第 k
对角线。我需要一些东西来写矩阵,k
>0,以及块矩阵,不仅仅是元素。
的方法
%// Take all A1, A2, A3, etc in a cell array for easy access and same for B
A = {A1,A2,A3,A4}
B = {B1,B2,B3}
%// Setup output array with the A blocks at main diagonal
out = blkdiag(A{:})
%// logical array with 1s at places where kth diagonal elements are to be put
idx = kron(triu(true(numel(A)),k) & tril(true(numel(A)),k),ones(size(A{1})))>0
%// Put kth diagonal blocks using the logical mask
out(idx) = [B{1:numel(A)-k}]
运行 样本 k = 1
2 x 2
大小矩阵 -
>> A{:}
ans =
0.3467 0.7966
0.6228 0.7459
ans =
0.1255 0.0252
0.8224 0.4144
ans =
0.7314 0.3673
0.7814 0.7449
ans =
0.8923 0.1296
0.2426 0.2251
>> B{:}
ans =
0.3500 0.9275
0.2871 0.0513
ans =
0.5927 0.8384
0.1629 0.1676
ans =
0.5022 0.3554
0.9993 0.0471
>> out
out =
0.3467 0.7966 0.3500 0.9275 0 0 0 0
0.6228 0.7459 0.2871 0.0513 0 0 0 0
0 0 0.1255 0.0252 0.5927 0.8384 0 0
0 0 0.8224 0.4144 0.1629 0.1676 0 0
0 0 0 0 0.7314 0.3673 0.5022 0.3554
0 0 0 0 0.7814 0.7449 0.9993 0.0471
0 0 0 0 0 0 0.8923 0.1296
0 0 0 0 0 0 0.2426 0.2251
File Exchange 上有一个可以执行此操作的提交:
(Block) tri-diagonal matrices.
您为函数提供三个 3D 数组,3D 数组的每一层代表一个主对角线、次对角线或超对角线的块。 (这意味着块必须具有相同的大小。)结果将是一个稀疏矩阵,因此它在内存方面应该相当有效。
示例用法为:
As = bsxfun(@times,ones(3),permute(1:3,[3,1,2]));
Bs = bsxfun(@times,ones(3),permute(10:11,[3,1,2]));
M = blktridiag(As, zeros(size(Bs)), Bs);
其中 full(M)
给你:
1 1 1 10 10 10 0 0 0
1 1 1 10 10 10 0 0 0
1 1 1 10 10 10 0 0 0
0 0 0 2 2 2 11 11 11
0 0 0 2 2 2 11 11 11
0 0 0 2 2 2 11 11 11
0 0 0 0 0 0 3 3 3
0 0 0 0 0 0 3 3 3
0 0 0 0 0 0 3 3 3
我知道要在 Matlab 中生成一个 block-diagonal 矩阵,命令 blkdiag
会生成这样一个矩阵:
现在我面临生成相同的 block-diagonal 矩阵,但在上对角线上还有矩阵元素 B_1
、B_2
、...、B_{n-1}
,其他地方为零:
- 我想这可以用循环硬编码,但我想找到一个更优雅的解决方案。关于如何实现这样的事情有什么想法吗?
P.S。我 diag
命令,使用 diag(A,k)
returns 第 k
对角线。我需要一些东西来写矩阵,k
>0,以及块矩阵,不仅仅是元素。
%// Take all A1, A2, A3, etc in a cell array for easy access and same for B
A = {A1,A2,A3,A4}
B = {B1,B2,B3}
%// Setup output array with the A blocks at main diagonal
out = blkdiag(A{:})
%// logical array with 1s at places where kth diagonal elements are to be put
idx = kron(triu(true(numel(A)),k) & tril(true(numel(A)),k),ones(size(A{1})))>0
%// Put kth diagonal blocks using the logical mask
out(idx) = [B{1:numel(A)-k}]
运行 样本 k = 1
2 x 2
大小矩阵 -
>> A{:}
ans =
0.3467 0.7966
0.6228 0.7459
ans =
0.1255 0.0252
0.8224 0.4144
ans =
0.7314 0.3673
0.7814 0.7449
ans =
0.8923 0.1296
0.2426 0.2251
>> B{:}
ans =
0.3500 0.9275
0.2871 0.0513
ans =
0.5927 0.8384
0.1629 0.1676
ans =
0.5022 0.3554
0.9993 0.0471
>> out
out =
0.3467 0.7966 0.3500 0.9275 0 0 0 0
0.6228 0.7459 0.2871 0.0513 0 0 0 0
0 0 0.1255 0.0252 0.5927 0.8384 0 0
0 0 0.8224 0.4144 0.1629 0.1676 0 0
0 0 0 0 0.7314 0.3673 0.5022 0.3554
0 0 0 0 0.7814 0.7449 0.9993 0.0471
0 0 0 0 0 0 0.8923 0.1296
0 0 0 0 0 0 0.2426 0.2251
File Exchange 上有一个可以执行此操作的提交: (Block) tri-diagonal matrices.
您为函数提供三个 3D 数组,3D 数组的每一层代表一个主对角线、次对角线或超对角线的块。 (这意味着块必须具有相同的大小。)结果将是一个稀疏矩阵,因此它在内存方面应该相当有效。
示例用法为:
As = bsxfun(@times,ones(3),permute(1:3,[3,1,2]));
Bs = bsxfun(@times,ones(3),permute(10:11,[3,1,2]));
M = blktridiag(As, zeros(size(Bs)), Bs);
其中 full(M)
给你:
1 1 1 10 10 10 0 0 0
1 1 1 10 10 10 0 0 0
1 1 1 10 10 10 0 0 0
0 0 0 2 2 2 11 11 11
0 0 0 2 2 2 11 11 11
0 0 0 2 2 2 11 11 11
0 0 0 0 0 0 3 3 3
0 0 0 0 0 0 3 3 3
0 0 0 0 0 0 3 3 3