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?
21 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Doug Hull
el 16 de Jun. de 2011
Comentada: Walter Roberson
el 27 de Ag. de 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 comentarios
Walter Roberson
el 27 de Ag. de 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.
Respuesta aceptada
Matt Fig
el 16 de Jun. de 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 comentarios
Walter Roberson
el 16 de Jun. de 2011
To account for values outside the span of roundTargets, you would need
vRounded = interp1(roundTargets,roundTargets,v,'nearest','extrap')
Más respuestas (2)
Teja Muppirala
el 16 de Jun. de 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 comentario
Sean de Wolski
el 16 de Jun. de 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 comentario
Matt Fig
el 16 de Jun. de 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.
Ver también
Categorías
Más información sobre Matrix Indexing en Help Center y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!