Reputation: 53
So, I have a matrix with 2 columns and 5 rows (as an example).
2 1
5 1
3 1
4 1
7 1
what I want to do is:
Starting from position (1,1) and moving down the first column, find the cells that lead to a value <10. In this case I would have:
step 1: 2 = 10? No, continue
step 2: 2+5 = 10? No, continue
step 3: 2+5+3 = 10? Yes, stop and return the sum of the corresponding values in the second column
step 4: 4 = 10? No, continue
step 5: 4+7 = 10? No, it's larger, thus we save the previous step and return 1 form the second column.
In the end of this process I would need to obtain a new matrix that looks like this:
10 3
4 1
7 1
Upvotes: 0
Views: 61
Reputation: 23685
This is my proposed solution:
% Create A and the cumulative sum of its first column...
A = [2 1; 5 1; 3 1; 4 1; 7 1];
A_cs = cumsum(A(:,1));
% Create a variable R to store the result and an indexer to it...
R = NaN(size(A_cs,1),2);
R_off = 1;
% Perform the computation...
while (~isempty(A_cs))
idx = find(A_cs <= 10);
idx_max = max(idx);
R(R_off,:) = [A_cs(idx_max) sum(A(idx,2))];
A_cs = A_cs - A_cs(idx_max);
disp(A_cs);
A_cs(idx) = [];
R_off = R_off + 1;
end
% Clear unused slots in R...
R(any(isnan(R),2),:) = [];
The computation is performed by taking the maximum index of the first cumsum group that lies within the specified threshold (10
in this case). Once it has been found, its corresponding value is inserted into the result matrix and the cumsum array is updated by removing the group entries and subtracting their sum. When the cumsum array is empty, the iteration finishes and R
contains the desired result.
Upvotes: 0
Reputation: 30165
You can perform exactly the logic you described in a loop.
Each row, test the "recent sum", where "recent" here means from the last output row to the current row.
If the sum is 10 or more, add to the output as described. Otherwise continue to the next row.
Code:
% Original data
x =[2 1; 5 1; 3 1; 4 1; 7 1];
% Output for result
output = [];
% idx is the row we start sum from on each test
idx = 1;
% Loop over all rows
for ii = 1:size(x,1)
% Get sum in column 1
s = sum(x(idx:ii, 1));
if s == 10
% Append row with sums
output = [output; 10 sum(x(idx:ii,2))];
idx = ii+1;
elseif s > 10
% Append all "recent" rows
output = [output; x(idx:ii,:)];
idx = ii+1;
end
end
Result:
>> disp(output)
10 3
4 1
7 1
Upvotes: 1