【问题标题】:matlab: addressing of one index without sub2indmatlab:没有sub2ind的一个索引的寻址
【发布时间】:2011-05-04 15:38:03
【问题描述】:

这与this other question 密切相关,但由于性能问题,该问题想避免sub2ind。我更关心使用sub2ind的“不优雅”。

假设我想创建另一个 MxN 矩阵,除了我想从向量中的相应条目分配的每一列中的一个条目之外,它全为零,并且每列中的行选择基于另一个向量。例如:

z = zeros(10,4);
rchoice = [3 1 8 7];
newvals = [123 456 789 10];
% ??? I would like to set z(3,1)=123, z(1,2)=456, z(8,3)=789, z(7,4)=10

我可以使用sub2ind 来完成此操作(我在an answer to a closely related question 中使用过):

z(sub2ind(size(z),rchoice,1:4)) = newvals

但是还有其他选择吗?似乎可以以某种方式使用逻辑寻址,但我很难过,因为为了将逻辑矩阵的元素设置为 1,您处理的元素位置与您实际想要处理的矩阵中的元素位置相同。

【问题讨论】:

    标签: matlab vectorization


    【解决方案1】:

    有一种非常更简单的方法。

    nCols=size(z,2);
    z(rchoice,1:nCols)=diag(newvals);
    

    【讨论】:

    • 这实际上是创建一个 NxN 矩阵,还是 MATLAB 足够聪明,可以理解我的意思?如果我有 1000 个值,这是有效还是内存不足?
    • diag 将创建一个NxN 矩阵。我没有费心使用稀疏,因为这只是一个概念性的例子。如果你有大量的值,你可以使用spdiags(newvals',0,N,N)。这仅使用N 元素,因此不会耗尽内存。
    • hmm... 我喜欢这个答案,它解决了我提出的字面问题,但它依赖于能够将其他值设置为零的副作用(而不仅仅是更改其他值),所以我无法在其他情况下使用它。
    • 您仍然可以像 dummy=z(...); dummy(1:N+1:N^2)=newvals; z(...)=dummy; 那样执行此操作,在这里我已将块拉出,替换其对角线并将其重新插入。这将涉及 NxN 矩阵,所以如果您正在处理对于超大矩阵,性能可能会受到影响。但是话又说回来,这只是因为您不允许sub2ind 束缚了我们的手脚。所以,也许在这么大的矩阵中,使用 Jonas 的解决方案或者使用sub2ind 是很好的。
    【解决方案2】:

    你可以直接在rchoice中加上前几列的行数,直接得到线性索引。

    nRows = size(z,1); %# in case you don't know this already
    nCols2write = length(newvals);
    z(rchoice+[0:nRows:(nRows*(nCols2write-1)]) = newvals;
    

    【讨论】:

    • 这适用于 2D(我链接到或认为我链接到的答案提到这种方法是对 sub2ind 的性能改进),所以 +1,但似乎很难正确处理 3D 或更大。
    • @Jason:虽然不像 2D 情况那么简单,但对于 N-D 矩阵,当然可以以直接的方式计算索引...查看this 问题和this 的答案有关 3D 和 4D 矩阵中的线性索引的示例。
    猜你喜欢
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 2018-05-31
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多