# [SciPy-user] mapminmax function?

Robert Kern robert.kern@gmail....
Sun Jan 4 17:11:33 CST 2009

```On Sun, Jan 4, 2009 at 17:54, Scott MacDonald
<scott.p.macdonald@gmail.com> wrote:
> Oops, I guess that information would have been helpful.  The description:
>
> %   MAPMINMAX processes matrices by normalizing the minimum and maximum
> values
> %   of each row to [YMIN, YMAX].
>
> %   MAPMINMAX(X,YMIN,YMAX) takes X and optional parameters,
> %     X - NxQ matrix or a 1xTS row cell array of NxQ matrices.
> %     YMIN - Minimum value for each row of Y. (Default is -1)
> %     YMAX - Maximum value for each row of Y. (Default is +1)
> %   and returns,
> %     Y - Each MxQ matrix (where M == N) (optional).
> %     PS - Process settings, to allow consistent processing of values.
>
> %    Examples
> %
> %   Here is how to format a matrix so that the minimum and maximum
> %   values of each row are mapped to default interval [-1,+1].
> %
> %     x1 = [1 2 4; 1 1 1; 3 2 2; 0 0 0]
> %     [y1,ps] = mapminmax(x1)
> %
> %   Next, we apply the same processing settings to new values.
> %
> %     x2 = [5 2 3; 1 1 1; 6 7 3; 0 0 0]
> %     y2 = mapminmax('apply',x2,ps)

<sigh> Every time I manage to forget why I hate Matlab, they make a
function with a schizoid argument spec like this.

No, there's nothing floating around that does this. Here's a quick
implementation. It needs robustifying (it doesn't handle the
all-values-equal case), but it doesn't overload the function's
arguments. Sometimes objects really are the solution.

In [1]: import numpy as np

In [3]: class MapMinMaxApplier(object):
def __init__(self, slope, intercept):
self.slope = slope
self.intercept = intercept
def __call__(self, x):
return x * self.slope + self.intercept
def reverse(self, y):
return (y-self.intercept) / self.slope
....:
....:

In [11]: def mapminmax(x, ymin=-1, ymax=+1):
....:     x = np.asanyarray(x)
....:     xmax = x.max(axis=-1)
....:     xmin = x.min(axis=-1)
....:     if (xmax==xmin).any():
....:         raise ValueError("some rows have no variation")
....:     slope = ((ymax-ymin) / (xmax - xmin))[:,np.newaxis]
....:     intercept = (-xmin*(ymax-ymin)/(xmax-xmin))[:,np.newaxis] + ymin
....:     ps = MapMinMaxApplier(slope, intercept)
....:     return ps(x), ps
....:

In [12]: x1 = np.array([[1.,2,4], [1,1,2], [3,2,2],[0,0,1]])

In [14]: y1, ps = mapminmax(x1)

In [15]: y1
Out[15]:
array([[-1.        , -0.33333333,  1.        ],
[-1.        , -1.        ,  1.        ],
[ 1.        , -1.        , -1.        ],
[-1.        , -1.        ,  1.        ]])

In [16]: ps(x1)
Out[16]:
array([[-1.        , -0.33333333,  1.        ],
[-1.        , -1.        ,  1.        ],
[ 1.        , -1.        , -1.        ],
[-1.        , -1.        ,  1.        ]])

In [17]: ps.reverse(y1)
Out[17]:
array([[ 1.,  2.,  4.],
[ 1.,  1.,  2.],
[ 3.,  2.,  2.],
[ 0.,  0.,  1.]])

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
-- Umberto Eco
```