Create a matrix that contains a specific total value, made by the maximum values, of another matrix

2 views (last 30 days)
So, I have an NxM matrix of doubles that is asymmetrically arranged. What I'd like to do is create a second matrix that contains a specific percentage of the total of the first matrix at indexes that match the location of the points in the first matrix, and have the second matrix be zero everywhere else.
I have written code that can do this, but its painfully slow. I'm hoping someone might have some ideas on how to make this more efficient. The code I have written is below:
temp_array=original_array; % copy original array
ratio=0.6; % desired percentage total of original array
len=length(original_array); hgt=height(original_array); % Create empty array
dummy=zeros(len, hgt);
total=ratio*sum(sum(original_array));
running_tot=0;
while running_tot<total
temp_val = max(max(temp_array)); % Find max value of input
[y_val, x_val]=find(temp_array==temp_val); % Pull indicies
dummy(y_val, x_val)=temp_val; % Put max value in dummy array
temp_array(y_val, x_val)=0; % Delete max value
running_tot=running_tot+temp_val;
end
This preserves the original array and contains the relevant data in the array titled "dummy." But it's egregiously slow - I'd like to make it faster. I've considered reversing the way the loop works and deleting the minimum values rather than keeping the maximum values, but there's no way to tell if the min(min(temp_matrix)>0, which would get the loop stuck.
Any thoughts on how I might go about increasing the efficency of this code? Maybe a matrix-based method that I haven't thought of?
Thanks!

Accepted Answer

Matt J
Matt J on 9 Aug 2021
Edited: Matt J on 9 Aug 2021
temp_array=original_array; % copy original array
ratio=0.6; % desired percentage total of original array
total=ratio*sum(original_array(:));
u=unique(original_array);
idx=find(cumsum(u,'reverse')<total,1);
thresh=u(idx);
temp_array(temp_array>=thresh)=0;
dummy=original_array-temp_array;
  1 Comment
Matt
Matt on 9 Aug 2021
That works perfectly! It took me a little while to work out
idx=find(cumsum(u,'reverse')<total,1);
thresh=u(idx);
but I think I've got it figured out. It probably would have taken me quite a while to work out using cumsum. Thanks for your help!

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!