Do not use the for loop to calculate the first number greater than 0 in each line

3 views (last 30 days)
x=randn(10,10)
...
  2 Comments
slevin Lee
slevin Lee on 19 Nov 2022
Edited: Jan on 19 Nov 2022
x=randn(10,10)
x1=x>0
x2=cumsum(x1,2)
x3=x2==0
x4=sum(x3,2)+1
x5=x(:,x4).*eye(10,10)
answer=sum(x5,2)
sorry!
I just want to see if there's a better way

Sign in to comment.

Accepted Answer

Jan
Jan on 19 Nov 2022
Edited: Jan on 19 Nov 2022
x = randn(10, 10)
y = x.'; % Required for the last step y(y3==1)
y1 = y > 0
y2 = cumsum(y1)
% Now a row can contain multiple 1's. Another CUMSUM helps:
y3 = cumsum(y2)
y(y3 == 1)
Another way:
x = randn(10, 10)
m = x > 0
y = cumsum(x .* m, 2)
y(~m) = Inf % Mask leading zeros
min(y, [], 2)
Or with beeing nitpicking for the formulation "no for loop":
result = zeros(1, 10);
m = x > 0;
k = 1;
while k <= 10
row = x(k, :);
result(k) = row(find(row(m(k, :)), 1));
k = k + 1;
end
And another method:
[row, col] = find(x > 0);
first = splitapply(@min, col, row);
x(sub2ind(size(x), 1:10, first.'))

More Answers (1)

DGM
DGM on 19 Nov 2022
Edited: DGM on 19 Nov 2022
Here's one way.
x = randn(10,10)
x = 10×10
0.5355 -1.4904 -0.9662 -0.7693 0.6789 0.6031 0.2375 -1.0743 0.6916 -0.8738 -0.0884 0.5313 -0.2913 1.0506 -1.1930 0.1070 0.2047 -0.2512 2.0512 0.1435 -0.1235 0.5840 1.3542 -0.3692 1.1048 -0.4211 -2.1762 -0.3553 0.8296 -2.1670 -0.6151 0.7344 -1.1325 -1.9521 -1.5595 0.8968 -0.8484 -2.5253 -0.1668 1.8909 1.0192 -0.4541 0.9363 -0.1635 -1.7753 -0.2266 1.1185 2.0062 -1.3746 -0.3283 -0.2484 -1.0466 1.2285 0.4551 -1.1110 -1.1021 0.3378 0.2945 -0.2886 1.0569 1.4228 -1.4178 0.5278 0.1037 0.7001 -0.3782 0.3081 1.4122 0.6484 -1.0982 -0.0277 -1.6063 -0.8334 -0.2916 -1.0505 -0.6081 -0.4252 -1.0511 0.4218 0.2551 -0.2180 0.5246 0.2145 1.4641 2.2411 -1.4396 -0.2848 -0.4727 2.5402 2.0645 0.5302 0.6045 -0.7767 1.2057 -0.9240 0.0234 1.1590 -0.0401 1.3279 0.5901
[~,idx] = min(x<=0,[],2) % note the logical inversion
idx = 10×1
1 2 2 2 1 3 1 9 2 1
firstnz = x(sub2ind(size(x),(1:size(x,1))',idx)) % get the values from the array
firstnz = 10×1
0.5355 0.5313 0.5840 0.7344 1.0192 1.2285 1.4228 0.4218 0.5246 0.5302

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by