带if语句的矢量化FIND函数MATLAB

bis*_*ssi 1 matlab for-loop

我有一个矩阵u,我想遍历所有行和所有列,然后执行以下操作。如果元素不为零,则返回行索引的值。如果元素为零,则在该元素之后的下一个非零元素中查找行索引。我可以使用两个带有查找功能的for循环轻松地做到这一点。但是我需要做很多次(不是因为矩阵的大小,而是因为多次调用)。我怎样才能更快地完成?

这是for循环代码:

     for w=scenario_size:-1:1
            for t=1:time_size
                l = u(t,w) ;
                if l~=0
                    tprime = t ;
                else
                    tprime = t+ find(u(t:end,w),1,'first') -1 ;
                end
                i(t,w)       = tprime ;
                boo(t,w)     = number(tprime,w)/u(tprime,w) ;
            end
end
Run Code Online (Sandbox Code Playgroud)

例如,如果一列为[0,0,5,1,0,3]i则为[3,3,3,4,6,6]。的任何列的最后一个元素u始终为非零(我通过在行末人工添加一行来强制执行此操作)。

然后bootprime某个矩阵对应的项number除以对应的项u(根据构造,该值不为零)。

gno*_*ice 5

你能解决这个使用findcummin和一些逻辑索引。从此示例案例开始:

>> u = randi([0 1], 10);
>> u(end, :) = 1

u =

     0     0     0     0     1     0     1     0     1     1
     1     0     1     1     1     0     0     0     0     1
     0     0     0     0     0     1     0     1     1     0
     1     1     1     0     1     1     0     0     0     0
     0     0     1     0     0     0     0     0     1     0
     1     1     1     0     0     0     0     0     0     0
     0     1     0     1     0     0     1     1     0     1
     1     1     0     1     0     1     1     1     1     1
     1     0     0     1     0     0     1     1     1     1
     1     1     1     1     1     1     1     1     1     1
Run Code Online (Sandbox Code Playgroud)

以下将执行您想要的操作:

i = nan(size(u));  % Start with all nan values
[r, ~] = find(u);  % Get row indices of non-zero values
i(u ~= 0) = r;     % Place row indices in locations of non-zero values
i = cummin(i, 1, 'reverse');  % Column-wise cumulative minimum, starting from bottom
Run Code Online (Sandbox Code Playgroud)

结果:

i =

     2     4     2     2     1     3     1     3     1     1
     2     4     2     2     2     3     7     3     3     2
     4     4     4     7     4     3     7     3     3     7
     4     4     4     7     4     4     7     7     5     7
     6     6     5     7    10     8     7     7     5     7
     6     6     6     7    10     8     7     7     8     7
     8     7    10     7    10     8     7     7     8     7
     8     8    10     8    10     8     8     8     8     8
     9    10    10     9    10    10     9     9     9     9
    10    10    10    10    10    10    10    10    10    10
Run Code Online (Sandbox Code Playgroud)

然后,您可以boo通过转换i线性索引来计算矩阵:

index = i+time_size.*repmat(0:(scenario_size-1), time_size, 1);  % Create linear index
boo = number(index)./u(index);
Run Code Online (Sandbox Code Playgroud)

或者,您可以i从头开始计算为线性索引:

i = nan(size(u));  % Start with all nan values
index = find(u);   % Get linear indices of non-zero values
i(index) = index;  % Place linear indices in locations of non-zero values
i = cummin(i, 1, 'reverse');  % Column-wise cumulative minimum, starting from bottom
boo = number(i)./u(i);
Run Code Online (Sandbox Code Playgroud)