How can I normalize a vector to the range [-1;1]
I would like to use function norm
, because it will be faster.
Also let me
An extended answer that was built on the answer by Jonas is below. It allows for automated normalization based on if negative and positive numbers are present in the vector or manual selection of the type of normalization desired. Below the function is a test script.
Normalization function
function [vecN, vecD] = normVec(vec,varargin)
% Returns a normalize vector (vecN) and "de-nomralized" vector (vecD). The
% function detects if both positive and negative values are present or not
% and automatically normalizes between the appropriate range (i.e., [0,1],
% [-1,0], or [-1,-1].
% Optional argument allows control of normalization range:
% normVec(vec,0) => sets range based on positive/negative value detection
% normVec(vec,1) => sets range to [0,1]
% normVec(vec,2) => sets range to [-1,0]
% normVec(vec,3) => sets range to [-1,1]
%% Default Input Values
% Check for proper length of input arguments
numvarargs = length(varargin);
if numvarargs > 1
error('Requires at most 1 optional input');
end
% Set defaults for optional inputs
optargs = {0};
% Overwrite default values if new values provided
optargs(1:numvarargs) = varargin;
% Set input to variable names
[setNorm] = optargs{:};
%% Normalize input vector
% get max and min
maxVec = max(vec);
minVec = min(vec);
if setNorm == 0
% Automated normalization
if minVec >= 0
% Normalize between 0 and 1
vecN = (vec - minVec)./( maxVec - minVec );
vecD = minVec + vecN.*(maxVec - minVec);
elseif maxVec <= 0
% Normalize between -1 and 0
vecN = (vec - maxVec)./( maxVec - minVec );
vecD = maxVec + vecN.*(maxVec - minVec);
else
% Normalize between -1 and 1
vecN = ((vec-minVec)./(maxVec-minVec) - 0.5 ) *2;
vecD = (vecN./2+0.5) * (maxVec-minVec) + minVec;
end
elseif setNorm == 1
% Normalize between 0 and 1
vecN = (vec - minVec)./( maxVec - minVec );
vecD = minVec + vecN.*(maxVec - minVec);
elseif setNorm == 2
% Normalize between -1 and 0
vecN = (vec - maxVec)./( maxVec - minVec );
vecD = maxVec + vecN.*(maxVec - minVec);
elseif setNorm == 3
% Normalize between -1 and 1
vecN = ((vec-minVec)./(maxVec-minVec) - 0.5 ) *2;
vecD = (vecN./2+0.5) * (maxVec-minVec) + minVec;
else
error('Unrecognized input argument varargin. Options are {0,1,2,3}');
end
Script to test the function
% Define vector
x=linspace(0,4*pi,25);
y = sin(x);
ya=sin(x); yb=y+10; yc=y-10;
% Normalize vector
ya0=normVec(ya); yb0=normVec(yb); yc0=normVec(yc);
ya1=normVec(ya,1); yb1=normVec(yb,1); yc1=normVec(yc,1);
ya2=normVec(ya,2); yb2=normVec(yb,2); yc2=normVec(yc,2);
ya3=normVec(ya,3); yb3=normVec(yb,3); yc3=normVec(yc,3);
% Plot results
figure(1)
subplot(2,2,1)
plot(x,ya0,'k',x,yb0,'ro',x,yc0,'b^')
title('Auto Norm-Range')
subplot(2,2,2)
plot(x,ya1,'k',x,yb1,'ro',x,yc1,'b^')
title('Manual Norm-Range: [0,1]')
subplot(2,2,3)
plot(x,ya2,'k',x,yb2,'ro',x,yc2,'b^')
title('Manual Norm-Range: [-1,0]')
subplot(2,2,4)
plot(x,ya3,'k',x,yb3,'ro',x,yc3,'b^')
title('Manual Norm-Range: [-1,1]')
A simple solution is using ready MATLAB function :
mapminmax
Process matrices by mapping row minimum and maximum values to [-1 1]
Example :
x1 = [1 2 4; 1 1 1; 3 2 2; 0 0 0]
[y1,PS] = mapminmax(x1)
Denormalize that vector after normalization
x1_again = mapminmax('reverse',y1,PS)
An up-to-date answer would be to use the rescale function introduced in Matlab R2017b. To normalise the vector A
to the range -1:1
, you'd run:
A = rescale(A, -1, 1);
You could undo this by saving the minimum and maximum beforehand then running rescale again:
maxA = max(A(:));
minA = min(A(:));
A = rescale(A, -1, 1);
% use the normalised A
A = rescale(A, minA, maxA);
norm
normalizes a vector so that its sum of squares are 1.
If you want to normalize the vector so that all its elements are between 0 and 1, you need to use the minimum and maximum value, which you can then use to denormalize again.
%# generate some vector
vec = randn(10,1);
%# get max and min
maxVec = max(vec);
minVec = min(vec);
%# normalize to -1...1
vecN = ((vec-minVec)./(maxVec-minVec) - 0.5 ) *2;
%# to "de-normalize", apply the calculations in reverse
vecD = (vecN./2+0.5) * (maxVec-minVec) + minVec