改变矩阵数组的对角线

Change diagonals of an array of matrices

我有一个包含矩阵数组的应用程序。我必须多次操纵对角线。其他元素不变。我想做这样的事情:

for j=1:nj
  for i=1:n
      g(i,i,j) = gd(i,j)
   end
 end

我已经看到如何使用 logical(eye(n)) 作为单个索引对单个矩阵执行此操作,但这不适用于矩阵数组。当然有办法解决这个问题。谢谢

使用linear index如下:

g = rand(3,3,2); % example data
gd = [1 4; 2 5; 3 6]; % example data. Each column will go to a diagonal
s = size(g); % size of g
ind = bsxfun(@plus, 1:s(1)+1:s(1)*s(2), (0:s(3)-1).'*s(1)*s(2)); % linear index
g(ind) = gd.'; % write values

结果:

>> g
g(:,:,1) =
   1.000000000000000   0.483437118939645   0.814179952862505
   0.154841697368116   2.000000000000000   0.989922194103104
   0.195709075365218   0.356349047562417   3.000000000000000
g(:,:,2) =
   4.000000000000000   0.585604389346560   0.279862618046844
   0.802492555607293   5.000000000000000   0.610960767605581
   0.272602365429990   0.551583664885735   6.000000000000000

根据 Luis Mendo 的回答,根据个人的具体目的,可能更容易修改的版本。毫无疑问,他的版本在计算上会更有效率。

g = rand(3,3,2); % example data
gd = [1 4; 2 5; 3 6]; % example data. Each column will go to a diagonal
sz = size(g); % Get size of data
sub = find(eye(sz(1))); % Find indices for 2d matrix

% Add number depending on location in third dimension.
sub = repmat(sub,sz(3),1); %  
dim3 = repmat(0:sz(1)^2:prod(sz)-1, sz(1),1); 
idx = sub + dim3(:);

% Replace elements.
g(idx) = gd;

我们已经开始打代码高尔夫了吗?另一个更小更易读的解决方案

g = rand(3,3,2);
gd = [1 4; 2 5; 3 6];
s = size(g);
g(find(repmat(eye(s(1)),1,1,s(3))))=gd(:)

g =

ans(:,:,1) =

1.00000   0.35565   0.69742
0.85690   2.00000   0.71275
0.87536   0.13130   3.00000

ans(:,:,2) =

4.00000   0.63031   0.32666
0.33063   5.00000   0.28597
0.80829   0.52401   6.00000