我有一个矩阵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始终为非零(我通过在行末人工添加一行来强制执行此操作)。
然后boo是tprime某个矩阵对应的项number除以对应的项u(根据构造,该值不为零)。
你能解决这个使用find,cummin和一些逻辑索引。从此示例案例开始:
>> 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)
| 归档时间: |
|
| 查看次数: |
86 次 |
| 最近记录: |