6

I'm hoping there is a MATLAB function similar to this Arduino function: http://arduino.cc/en/Reference/map

Basically I have a time based variable with 67 data points ranging from 0 to 1.15, and I want to map that from 0 to 100% (so, 101 data points). In Arduino that would look something like:

map(value, fromLow, fromHigh, toLow, toHigh)

I can use interp1 in MATLAB to get me the 101 data points, but I just get 101 data points between 0 and 1.15. I know I can just multiply each value by 100/1.15, but this is inexact. Is there a more elegant way to do this in MATLAB that I'm overlooking?

(This post looked hopeful, but it's not what I'm looking for: Map function in MATLAB?)

Thanks

Community
  • 1
  • 1
dustynrobots
  • 311
  • 4
  • 8
  • 20
  • 3
    On Arduino reference page you linked to they even provide code for the `map` function at the bottom: `(x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;`. Note that this function appears to be implemented with integer math, so you'll need to do that in Matlab as well if you want to replicate the function completely. – horchler Jul 12 '13 at 23:35
  • I know I can write my own function based on the Arduino code, my question is if there is something already built in to MATLAB that can do this. Thanks. – dustynrobots Jul 12 '13 at 23:47

3 Answers3

0

you can use linspace, for example

linspace(0,1.15,101)

will get you 101 points spread uniformly between the limits 0 and 1.15.

bla
  • 25,846
  • 10
  • 70
  • 101
  • Thanks, that doesn't really work for me though. I have both an x and f(x). Time is x, and for one particular case I have 67 data points that span 0 to 1.15, and I want to map them to be 101 data points spanning 0 to 100. Then each of the initial x points has a corresponding f(x). So I guess it's a two step problem: First, interpolate x and f(x) to have the correct number of data points, then "stretch" the x vector from the initial range to the desired range. – dustynrobots Jul 12 '13 at 23:50
  • I don't see how this would be any thing more than a vectorized version of `y = map(value, fromLow, fromHigh, fromLow, fromHigh);`, i.e., mapping from a range to the same exact range. – horchler Jul 12 '13 at 23:51
  • I'm sorry, I didn't understand your question then. let me try to reanswer it in a short while. It seems though that all you need is `interp1`, in what way what you get is inexact? – bla Jul 13 '13 at 00:01
  • Okay thanks! The inexact part is just the scaling if I approximate 100/1.15, but if I just use the fraction explicitly I should be fine. – dustynrobots Jul 13 '13 at 12:45
0

If you have neural networks toolbox available, then you can try mapminmax function. By default, function maps to [-1 1] interaval and gets input bounds from data. But I believe that filling settings structure with your values and then calling mapminmax should help.

akademi4eg
  • 109
  • 4
  • Oh cool that looks almost perfect, and I do have that toolbox. The only thing I can't figure out is how to set the PS (processing settings), because if I could set that to standardize to a certain number of values, I would be set. Thanks! – dustynrobots Jul 13 '13 at 12:44
  • You can fill `PS` with your data. There are 10 fields in it. But, following simple example with only 5 fields worked for me. `x = [1 2 3]; ps = struct('yrange', 1, 'ymin', 0, 'no_change', 0, 'xrange', 2, 'xmin', 1); y = mapminmax('apply', x, ps);` So, you can have several precreated structures for each case you need. – akademi4eg Jul 14 '13 at 17:09
0

My FEX submission maptorange can do exactly that. It takes initial value(s), the range from which they originate, and the range onto which they should be mapped, and returns the mapped value(s). In your example, that would be:

maptorange(values, [0 1.15], [0 100]);

(This is assuming linear mapping. The script can also map along an exponential function.)

To go from 67 to 101 values, you would indeed need interpolation. This can be done either before or after mapping.

lrkrol
  • 39
  • 3