问题描述
我有一个三维矩阵,例如u
.我还有另一个三维尺寸的矩阵,例如B
.假设u
和B
的尺寸为CxTxW
.对于u
的每个元素,我希望执行以下操作:如果u
为> 0,则报告回u
的值以及其所在的相应T
尺寸以及B/u
的相应元素.如果u
为0,则使用正u
和T
以及相应的B/u
元素报告下一个T
(对于相同的C
,W
).在下面的代码中,我将B/u
称为benefit
.
I have a matrix of three dimensions, say u
. I have another matrix of three dimensions, say B
. Say the dimensions of u
and B
are CxTxW
. For every element of u
, I wish to do the following:If u
is >0, then report back both the value of u
as well as the corresponding T
dimension it is in, and the corresponding element of B/u
. If the u
is 0, then report back the next T
(for the same C
,W
) with a positive u
and the T
and the corresponding B/u
element. In the code below I call B/u
as benefit
.
以下链接的问题以非常有效的方式回答了C = 1(即二维)的问题.我可以在c周围编写一个for循环,并为C的每个元素重复链接的答案,但我希望在没有for循环的情况下执行.
The following linked question answers this in a very efficient manner for C=1 (i.e, two dimensions). I can write a for loop around the c and repeat the linked answer for every element of C but I wish to do it without the for loop.
以下是带有循环的解决方案:
Here is the solution with a loop:
for c=1:C
dummy_u = reshape(u(c,:,:),[T+1 W]) ;
dummy_B = reshape(B(c,:,:),[T+1 W]) ;
dummy_i = nan(size(dummy_u)) ; % Start with all nan values
[dum_row, ~] = find(dummy_u); % Get row indices of non-zero values
dummy_i(dummy_u ~= 0) = dum_row; % Place row indices in locations of non-zero values
dummy_i = cummin(dummy_i, 1, 'reverse'); % Column-wise cumulative minimum, starting from bottomi
dum_i = dummy_i+(T+1).*repmat(0:(W-1), T+1, 1); % Create linear index
dummy_benefit = dummy_B(dum_i)./dummy_u(dum_i);
i(c,:,:) = dummy_i ;
benefit(c,:,:) = dummy_benefit ;
clear dum_i dum_row dummy_i dummy_benefit
end
没有for循环怎么办?
How can I do it without a for loop?
推荐答案
您可以将整个行置换为T x CW
矩阵,而不是将一行重新整形为T x W
矩阵:
Instead of reshaping one row into a T x W
matrix, you can permute the whole thing into a T x CW
matrix:
>> C = 4; T = 5; W = 3;
>> u = reshape(1:C*T*W, C, T, W) % generate sample u
u =
ans(:,:,1) =
1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20
ans(:,:,2) =
21 25 29 33 37
22 26 30 34 38
23 27 31 35 39
24 28 32 36 40
ans(:,:,3) =
41 45 49 53 57
42 46 50 54 58
43 47 51 55 59
44 48 52 56 60
>> du = reshape(permute(u, [2 1 3]), T, [])
du =
1 2 3 4 21 22 23 24 41 42 43 44
5 6 7 8 25 26 27 28 45 46 47 48
9 10 11 12 29 30 31 32 49 50 51 52
13 14 15 16 33 34 35 36 53 54 55 56
17 18 19 20 37 38 39 40 57 58 59 60
du
上的其余代码应保持不变(添加虚拟行除外).
The rest of your code should work unchanged (except for adding the dummy row) on du
.
倒数是:
>> permute(reshape(du, T, C, W), [2 1 3])
ans =
ans(:,:,1) =
1 5 9 13 17
2 6 10 14 18
3 7 11 15 19
4 8 12 16 20
ans(:,:,2) =
21 25 29 33 37
22 26 30 34 38
23 27 31 35 39
24 28 32 36 40
ans(:,:,3) =
41 45 49 53 57
42 46 50 54 58
43 47 51 55 59
44 48 52 56 60
我不知道这种解决方案是否真的更快.
I have no idea if this solution is actually faster.
这篇关于sub2ind多维-元素访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!