如何有效地获得非方阵的多值对角线?

时间:2018-03-12 09:18:51

标签: matlab matrix diagonal

成像我有以下矩阵A(5x20)

    A = [6.4475 3.3487 Inf 6.4940 6.5480 3.4857 Inf 6.5030 6.5035 3.5732 Inf 6.4951 6.6372 3.3639 Inf 6.5371 Inf 4.4444 Inf Inf;
         6.6761 2.3999 Inf 6.8620 6.5776 2.1963 Inf 6.8535 6.8733 3.1184 Inf 6.8688 6.5918 2.2900 Inf 6.8656 Inf 4.4667 Inf Inf;
         5.9808 4.1965 Inf 5.8950 6.2467 4.5779 Inf 5.9116 5.9198 4.0071 Inf 5.8938 6.3981 4.3019 Inf 5.9570 Inf 4.3433 Inf Inf;
         5.7438 1.5369 Inf 5.9868 5.5404 1.6374 Inf 5.9537 6.0332 2.1704 Inf 6.0024 5.5235 1.5035 Inf 5.9397 Inf 3.5727 Inf Inf;
         4.0544 3.8845 Inf 4.1466 4.6749 4.6560 Inf 4.3833 3.7550 3.0591 Inf 4.0693 4.9586 4.1296 Inf 4.6826 Inf 2.5593 Inf Inf];

然后我想以下列方式提取值:

enter image description here

所以我的输出矩阵是:

B = [6.4475 3.3487 Inf 6.4940;
     6.5776 2.1963 Inf 6.8535;
     5.9198 4.0071 Inf 5.8938;
     5.5235 1.5035 Inf 5.9397;
     Inf 2.5593 Inf Inf]

2 个答案:

答案 0 :(得分:1)

我假设每行的元素数量是参数k

在一行中,您可以检索如下元素:

B = A(sub2ind(size(A), repmat((1:size(A,1)).', 1, k), (1:k)+((1:k:size(A,2))-1).'));

让我们解释一下。您可以创建要检索的元素的索引,并将其转换为sub2ind的线性索引。使用repmat可以轻松创建行索引。

对于列索引,一种解决方案是创建一个矩阵,其中元素是列索引。在这里我选择一个长版本:

(1:k)+((1:k:size(A,2))-1).'

它允许您跳过或复制元素(取决于size(A,2)k的倍数)。请注意,此构造适用于最近的Matlab版本,在旧版本中,您已经调用bsxfun(@plus, 1:k, ((1:k:size(A,2))-1).')

如果你确定在结果中每列只取一个元素,那就让我们更有效率地做:     重塑(1:大小(A,2),k,[])。'

请注意,它不会处理奇数大小的输入矩阵(例如,如果您有更多行)。

答案 1 :(得分:1)

这应该可以正常工作:

% Define the data sample...
A = [
  6.4475 3.3487 Inf 6.4940 6.5480 3.4857 Inf 6.5030 6.5035 3.5732 Inf 6.4951 6.6372 3.3639 Inf 6.5371 Inf 4.4444 Inf Inf;
  6.6761 2.3999 Inf 6.8620 6.5776 2.1963 Inf 6.8535 6.8733 3.1184 Inf 6.8688 6.5918 2.2900 Inf 6.8656 Inf 4.4667 Inf Inf;
  5.9808 4.1965 Inf 5.8950 6.2467 4.5779 Inf 5.9116 5.9198 4.0071 Inf 5.8938 6.3981 4.3019 Inf 5.9570 Inf 4.3433 Inf Inf;
  5.7438 1.5369 Inf 5.9868 5.5404 1.6374 Inf 5.9537 6.0332 2.1704 Inf 6.0024 5.5235 1.5035 Inf 5.9397 Inf 3.5727 Inf Inf;
  4.0544 3.8845 Inf 4.1466 4.6749 4.6560 Inf 4.3833 3.7550 3.0591 Inf 4.0693 4.9586 4.1296 Inf 4.6826 Inf 2.5593 Inf Inf
];

% Define the script parameters...
k = 4;
n = size(A,2) / k;

% Create the auxiliary matrix for indexing...
aux = repmat({ones(1,k)},1,n);
idx = blkdiag(aux{:});

% Extract the elements using the indexing and properly reshape the result...
B = reshape(A(logical(idx)),k,size(A,1)).'

最终输出是:

B =
    6.4475  3.3487  Inf  6.4940
    6.5776  2.1963  Inf  6.8535
    5.9198  4.0071  Inf  5.8938
    5.5235  1.5035  Inf  5.9397
       Inf  2.5593  Inf     Inf
相关问题