如何使一个向量标准化/反规格化[-1;1]

时间:2022-03-30 15:58:39

How can I normalize a vector to the range [-1;1]

如何将一个向量标准化到这个范围[-1;1]

I would like to use function norm, because it will be faster.

我想用函数范数,因为它会更快。

Also let me know how I can denormalize that vector after normalization?

还可以让我知道如何在归一化后使这个向量变得规格化?

3 个解决方案

#1


26  

norm normalizes a vector so that its sum of squares are 1.

范数使一个向量标准化,使其平方和为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.

如果要使向量标准化,使其所有元素都在0和1之间,那么就需要使用最小值和最大值,然后再用它来重新规格化。

%# 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

#2


0  

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]')

#3


0  

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:

一个最新的答案将是使用在Matlab R2017b中引入的rescale函数。为了使向量A标准化到范围-1:1,你会跑:

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);

#1


26  

norm normalizes a vector so that its sum of squares are 1.

范数使一个向量标准化,使其平方和为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.

如果要使向量标准化,使其所有元素都在0和1之间,那么就需要使用最小值和最大值,然后再用它来重新规格化。

%# 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

#2


0  

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]')

#3


0  

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:

一个最新的答案将是使用在Matlab R2017b中引入的rescale函数。为了使向量A标准化到范围-1:1,你会跑:

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);