0

I have an array:

[0.0182, 0.5238, -0.0205, 1.1683, 0.9684, 0.9722, 0.5677, 0.9043, 0.0025, ...
 0.9986, 0.4088, 0.5483, -0.0082, 0.5659]

I want to set new numbers in range of [0 0.5 1] for the above array. For example, 0.5238 is nearer to 0.5 than 1, so it should be set to 0.5 rather than 1. 0.0025 is closer to 0 than 0.5, so it should be set to 0, and so on. As a result, new array should be:

[0, 0.5, 0, 1, 1, 1, 0.5, 1, 0, 1, 0.5, 0.5, 0, 0.5]

How is it possible in MATLAB? Is there any function?

John Dvorak
  • 26,799
  • 13
  • 69
  • 83
BlueBit
  • 397
  • 6
  • 22

2 Answers2

1

I think that you want to use the round function with a scale factor:

x = [0.0182, 0.5238, -0.0205, 1.1683, 0.9684, 0.9722, 0.5677, 0.9043, 0.0025, 0.9986, 0.4088, 0.5483, -0.0082, 0.5659]

roundingScaling = 0.5;
round(x/roundingScaling )*roundingScaling 
Pursuit
  • 12,285
  • 1
  • 25
  • 41
  • Pretty good and efficient, but I'n not sure that this will be numerically stable for general sets of bounds -particularly those that don't have exact floating-point representations. – horchler Jul 16 '13 at 19:03
  • if my new boundary be [0 0.25 0.5 0.75 1]. Does it solution work? I mean, roundingScaling set to 0.25. because of 0.25 distance between numbers. – BlueBit Jul 16 '13 at 19:05
  • @BlueBit. Yes, it will work as `roundingScaling` is changed. – Pursuit Jul 16 '13 at 19:07
  • Check out my solution below, much simpler, and does not rely on the user changing a scaling factor. – MZimmerman6 Jul 16 '13 at 19:14
1

Something like this is a little bit better than assuming it as simple as 0.5. If you know the values that you want to round closest to.

valueToRoundTo = [0,0.5,1];
x = [0.0182, 0.5238, -0.0205, 1.1683, 0.9684, 0.9722, 0.5677, 0.9043, 0.0025, 0.9986, 0.4088, 0.5483, -0.0082, 0.5659];

for i = 1:numel(x)
    [~,idx] = min(abs(valueToRoundTo-x(i)));
    x(i) = valueToRoundTo(idx);
end

You can also do this in a very optimized way without the for loop

valueToRoundTo = [-0.5,0,0.5,1];
x = [0.0182, 0.5238, -0.0205, 1.1683, 0.9684, 0.9722, 0.5677, 0.9043, 0.0025, 0.9986, 0.4088, 0.5483, -0.0082, 0.5659];
[~,idx] = min(abs(bsxfun(@minus,x,valueToRoundTo.')));
rounded = valueToRoundTo(idx);
MZimmerman6
  • 8,445
  • 10
  • 40
  • 70
  • When i set 'valueToRound' to [0, 0.25, 0.5, 0.75, 1], This function works same as when it is [0,0.5,1]. Is it possible to work this function for any round values? – BlueBit Jul 16 '13 at 19:15
  • yes, it is just that none of your values are closer to 0.25 than they are 0 or 0.5, throw a 0.26 in there and you will see it gets rounded properly – MZimmerman6 Jul 16 '13 at 19:16
  • Basically I am just choosing the value that has the smallest absolute difference. Just very optimized and flexible. I recommend using the second solution that uses `bsxfun`. If you want to know more about how that works, read the documentation, just know that it removes the need for the for loop. This will improve performance considerably when working with large amounts of data. – MZimmerman6 Jul 16 '13 at 19:17