How to perform mathematical operation in columns on certain elements and make the other elements zero??
16 views (last 30 days)
Show older comments
For example I have this matrix:
[0 0
0 0
1 0
2 7
5 8
3 11
4 12
2 9]
The min and max value of column one are (1,5) and column 2 are (7,12). I want to perform a specific operation a*b when the min value occurs in each column and perform a*(b-2) to its next value. similarly when max value occurs I want to perform a/b at max value and a/(b-2) to its next value. All the other values must remain zero.
Here
a=10; a*b=10; a*(b-2)=-10
b=1 a/b=10; a/(b-2)=-10
The new matrix should be like:
Ans=[ 0 0
0 0
10 0
-10 10
10 -10
-10 0
0 10
0 -10]
Can someone please help????thankyou in advance.
0 Comments
Accepted Answer
dpb
on 16 May 2020
Edited: dpb
on 17 May 2020
Don't try to get too fancy...sometimes just deadahead is the simplest and best (and probably fastest, besides)...
a=10; % constants and compute insertion vectors
b=1;
vMIN=[a*b;a*(b-2)];
vMAX=[a/b;a/(b-2)];
A(A==0)=nan; % prelim fixup to exclude 0 from min/max
for i=1:size(A,2) % engine for each column...
[~,imn]=min(A(:,i)); % location min, max
[~,imx]=max(A(:,i));
A(imn:imn+1,i)=vMIN; % replace element and next
A(imx:imx+1,i)=vMAX;
end
A(isnan(A)=0; % restore the zeros...
NB1: Must do search for locations and save before either substitution...
NB2: Presumes min/max is not in last row of A or will get out-of-bounds addressing error.
4 Comments
More Answers (1)
Stephen23
on 19 May 2020
Edited: Stephen23
on 20 May 2020
Something fancy...
>> M = [0,0;0,0;1,0;2,7;5,8;3,11;4,12;2,9]
M =
0 0
0 0
1 0
2 7
5 8
3 11
4 12
2 9
>> a = 10;
>> b = 1;
>> F = @(f,v) conv2(+(M==f(M./~~M,[],1)),[0;v],'same'); % requires >=R2016b
>> Q = F(@max,[a/b;a/(b-2)]) + F(@min,[a*b;a*(b-2)])
Q =
0 0
0 0
10 0
-10 10
10 -10
-10 0
0 10
0 -10
For earlier versions replace == with bsxfun.
5 Comments
Stephen23
on 20 May 2020
@dpb: With so much data-duplication going on, to be honest I was quite surprised at the speed: most of the operators in that anonymous function create a new array with the same size as the input data. This does take its toll on larger input arrays: your loop tends to be faster on the larger arrays I tried.
The fastest approach I found was to split the vector indexing in your solution into two scalars, i.e.:
A(imn,i) = a*b;
A(imn+1,i) = a*(b-2);
etc.
No doubt all of these results are highly dependent on the MATLAB version anyway, and writing something readable/understandable/maintainable is of course much preferred.
dpb
on 20 May 2020
" fastest approach I found was to split the vector indexing in your solution into two scalars"
The [;] operation has always been expensive. I get warnings about avoiding brackets all the time that I mostly ignore since not writing production code and I find them more legible...but if such code were buried in the bowels of a loop or iterative solution it then could be worth the less expressive form.
Interesting result...
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!