What I love about this is there are three perfectly good answers, all doing this in a slightly different way. Each of them has the possibility to be the best solution under different constraints (memory, time, ease of development, etc...)
How do I round to the nearest arbitrary, enumerated value in MATLAB?
19 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
Doug Hull
il 16 Giu 2011
Commentato: Walter Roberson
il 27 Ago 2015
If I have values:
v = [0.1 2.2 1.6 7.3 10];
and I want all my values to be rounded to the nearest value in this list:
roundTargets = [0 2.7 8 11.1];
then I would want to make a function that would convert each value in v to the nearest value in roundTargets.
So this function would return me:
vRounded = [0 2.7 2.7 8 11.1];
Any clever ways to do this?
[Yes, I know how to do this. When I get questions from users that make good posts here, I like to put them out for the world to find.]
3 Commenti
Walter Roberson
il 27 Ago 2015
The three solutions are shown below -- interp1, histc, bsxfun
Note: Doug Hull moved on to a different career so he will not be back to respond.
Risposta accettata
Matt Fig
il 16 Giu 2011
One approach:
roundTargets = [0 2.7 8 11.1];
v = [0.1 2.2 1.6 7.3 10];
vRounded = interp1(roundTargets,roundTargets,v,'nearest')
3 Commenti
Walter Roberson
il 16 Giu 2011
To account for values outside the span of roundTargets, you would need
vRounded = interp1(roundTargets,roundTargets,v,'nearest','extrap')
Più risposte (2)
Teja Muppirala
il 16 Giu 2011
I believe HISTC is the fastest and most memory efficient way to solve this problem for large cases.
v = 10*rand(1,1000000);
roundTargets = [0 sort(10*rand(1,10000)) 10];
%%%histc
tic
[~,Index1] = histc(v,[-Inf interp1(1:numel(roundTargets),roundTargets,0.5 + (1:numel(roundTargets)-1)) Inf]);
vRounded1 = roundTargets(Index1);
timehistc = toc
%%%interp1
tic
vRounded2 = interp1(roundTargets,roundTargets,v,'nearest');
timeinterp1 = toc
isequal(vRounded1,vRounded2)
%%%bsxfun will run out of memory
tic
[~,idx] = min(bsxfun(@(x,y)abs(x-y),v,roundTargets.')); %index of closest
vRounded = roundTargets(idx); %extract values
timebsxfun = toc
1 Commento
Sean de Wolski
il 16 Giu 2011
[~,idx] = min(bsxfun(@(x,y)abs(x-y),v,roundTargets.')); %index of closest
vRounded = roundTargets(idx); %extract values
Keywords?
minimum, absolute, difference, element by element, comparison, index
1 Commento
Matt Fig
il 16 Giu 2011
You are too fast! I was about to post this with the warning that it could take a ton of memory for large problems because of the intermediate array.
Vedere anche
Categorie
Scopri di più su Matrix Indexing in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!