Matlab 用对角矩阵替换矩阵中的每个元素
假设我有一个维数为NxV的矩阵。我想创建一个大小为NTxVT的更大矩阵,即我想用diag(T)*a(e)替换矩阵a(e)的每个元素e,同时保持矩阵的一般方向(例如,a(e)在a(e-1)的左侧,因此diag(T)*a(e)在diag(T)*a(e-1)的左侧) 在matlab中是否有实现这一点的技巧?(制作每个对角矩阵并将它们连接起来将花费永远的时间)Matlab 用对角矩阵替换矩阵中的每个元素,matlab,matrix,vectorization,Matlab,Matrix,Vectorization,假设我有一个维数为NxV的矩阵。我想创建一个大小为NTxVT的更大矩阵,即我想用diag(T)*a(e)替换矩阵a(e)的每个元素e,同时保持矩阵的一般方向(例如,a(e)在a(e-1)的左侧,因此diag(T)*a(e)在diag(T)*a(e-1)的左侧) 在matlab中是否有实现这一点的技巧?(制作每个对角矩阵并将它们连接起来将花费永远的时间) 非常感谢^我能想到的最简单的方法是组合和函数: B = cell2mat(arrayfun((@(x) T .* x), A, 'Uniform
非常感谢^我能想到的最简单的方法是组合和函数:
B = cell2mat(arrayfun((@(x) T .* x), A, 'UniformOutput', false));
首先,我将矩阵A
转换为矩阵T.*x
的单元数组,其中x
是A
的元素(假设T
是矩阵)
然后我使用cell2mat
将其转换回矩阵
下面是一个完整的示例():
导致:
B =
-8 0 -1 0 -6 0
0 8 0 1 0 6
-3 0 -5 0 -7 0
0 3 0 5 0 7
-4 0 -9 0 -2 0
0 4 0 9 0 2
下面是一个使用
bsxfun
A = magic(3);
T = [-1 1]
T = diag(T);
M=bsxfun(@times,permute(A,[3,1,4,2]),permute(T,[1,3,2,4]));
M=reshape(M,size(T).*size(A));
它创建一个4D矩阵,其中单个块为M(:,i,:,j)
,然后将其重塑为2D矩阵
图像处理工具箱提供了另一个非常简短但速度较慢的解决方案:
A = magic(3);
T = [-1 1]
T = diag(T);
M=blockproc(A,[1 1],@(x) x.data.*T);
最后是一个生成稀疏矩阵的实现,这可能有助于大T,因为矩阵将包含许多零:
T=[-1 1];
A=magic(3);
%p and q hold the positions where the first element element is stored. Check sparse(p(:),q(:),A(:)) to understand this intermediate step
[p,q]=ndgrid(1:numel(T):numel(T)*size(A,1),1:numel(T):numel(T)*size(A,2));
%now p and q are extended to hold the indices for all elements
tP=bsxfun(@plus,p(:),0:numel(T)-1);
tQ=bsxfun(@plus,q(:),0:numel(T)-1);
%
tA=bsxfun(@times,A(:),T);
M=sparse(tP,tQ,tA);
当T的大小为nx1时,稀疏解决方案会将内存使用量减少大约n/1.55倍
A = magic(3);
T = diag([-1 1]);
kron(A,T)
给予
附言:我仅使用索引从复制了这个想法:
A = magic(3);
T = diag([-1 1]); %// example data from Daniel's answer
[a1, a2] = size(A);
[t1, t2] = size(T);
M = A(ceil(1/t1:1/t1:a1), ceil(1/t2:1/t2:a2)).*T(repmat(1:t1,1,a1), repmat(1:t2,1,a2));
使用-
样本运行-
A = magic(4)
T = magic(3)
M = reshape(diag(T)*A(:).',[size(A,1)*size(T,1) size(A,2)])
将导致-
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
T = %// Notice that only diag(T) elements would be used to calculate M
8 1 6
3 5 7
4 9 2
M =
128 16 24 104
80 10 15 65
32 4 6 26
40 88 80 64
25 55 50 40
10 22 20 16
72 56 48 96
45 35 30 60
18 14 12 24
32 112 120 8
20 70 75 5
8 28 30 2
我认为,
permute(A,[3,1,4,2]).*permute(T,[1,3,2,4])
看起来比它的bsxfun
等价物更清晰。@LeonidBeschastny:octave user?Matlab不支持广播,这里需要bsxfun。你找到我了;)我几年前切换到了octave。你是对的,如果没有bsxfun
,它在MatLab中就无法工作。可能是你在寻找kron命令吗?你会不会得到一个大小为ntnxv
的矩阵,其中Tn
是size(t,1)
,因为diag(t)
将是size(t,1)
?这就是方法!简洁快速。
M = reshape(diag(T)*A(:).',[size(A,1)*size(T,1) size(A,2)])
A = magic(4)
T = magic(3)
M = reshape(diag(T)*A(:).',[size(A,1)*size(T,1) size(A,2)])
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
T = %// Notice that only diag(T) elements would be used to calculate M
8 1 6
3 5 7
4 9 2
M =
128 16 24 104
80 10 15 65
32 4 6 26
40 88 80 64
25 55 50 40
10 22 20 16
72 56 48 96
45 35 30 60
18 14 12 24
32 112 120 8
20 70 75 5
8 28 30 2