I normalize a vector V in MATLAB as following:
normalized_V = V/norm(V);
however, is it the most elegant (efficient) way to normalize a vector in MATLAB?
This question is related to
matlab
vector
performance
I took Mr. Fooz's code and also added Arlen's solution too and here are the timings that I've gotten for Octave:
clc; clear all;
V = rand(1024*1024*32,1);
N = 10;
tic; for i=1:N, V1 = V/norm(V); end; toc % 7.0 s
tic; for i=1:N, V2 = V/sqrt(sum(V.*V)); end; toc % 6.4 s
tic; for i=1:N, V3 = V/sqrt(V'*V); end; toc % 5.5 s
tic; for i=1:N, V4 = V/sqrt(sum(V.^2)); end; toc % 6.6 s
tic; for i=1:N, V1 = V/norm(V); end; toc % 7.1 s
tic; for i=1:N, d = 1/norm(V); V1 = V*d;end; toc % 4.7 s
Then, because of something I'm currently looking at, I tested out this code for ensuring that each row sums to 1:
clc; clear all;
m = 2048;
V = rand(m);
N = 100;
tic; for i=1:N, V1 = V ./ (sum(V,2)*ones(1,m)); end; toc % 8.2 s
tic; for i=1:N, V2 = bsxfun(@rdivide, V, sum(V,2)); end; toc % 5.8 s
tic; for i=1:N, V3 = bsxfun(@rdivide, V, V*ones(m,1)); end; toc % 5.7 s
tic; for i=1:N, V4 = V ./ (V*ones(m,m)); end; toc % 77.5 s
tic; for i=1:N, d = 1./sum(V,2);V5 = bsxfun(@times, V, d); end; toc % 2.83 s
tic; for i=1:N, d = 1./(V*ones(m,1));V6 = bsxfun(@times, V, d);end; toc % 2.75 s
tic; for i=1:N, V1 = V ./ (sum(V,2)*ones(1,m)); end; toc % 8.2 s
The only problem you would run into is if the norm of V is zero (or very close to it). This could give you Inf or NaN when you divide, along with a divide-by-zero warning. If you don't care about getting an Inf or NaN, you can just turn the warning on and off using WARNING:
oldState = warning('off','MATLAB:divideByZero'); % Return previous state then
% turn off DBZ warning
uV = V/norm(V);
warning(oldState); % Restore previous state
If you don't want any Inf or NaN values, you have to check the size of the norm first:
normV = norm(V);
if normV > 0, % Or some other threshold, like EPS
uV = V/normV;
else,
uV = V; % Do nothing since it's basically 0
end
If I need it in a program, I usually put the above code in my own function, usually called unit (since it basically turns a vector into a unit vector pointing in the same direction).
By the rational of making everything multiplication I add the entry at the end of the list
clc; clear all;
V = rand(1024*1024*32,1);
N = 10;
tic; for i=1:N, V1 = V/norm(V); end; toc % 4.5 s
tic; for i=1:N, V2 = V/sqrt(sum(V.*V)); end; toc % 7.5 s
tic; for i=1:N, V3 = V/sqrt(V'*V); end; toc % 4.9 s
tic; for i=1:N, V4 = V/sqrt(sum(V.^2)); end; toc % 6.8 s
tic; for i=1:N, V1 = V/norm(V); end; toc % 4.7 s
tic; for i=1:N, d = 1/norm(V); V1 = V*d;end; toc % 4.9 s
tic; for i=1:N, d = norm(V)^-1; V1 = V*d;end;toc % 4.4 s
Fastest by far (time is in comparison to Jacobs):
clc; clear all;
V = rand(1024*1024*32,1);
N = 10;
tic;
for i=1:N,
d = 1/sqrt(V(1)*V(1)+V(2)*V(2)+V(3)*V(3));
V1 = V*d;
end;
toc % 1.5s
I don't know any MATLAB and I've never used it, but it seems to me you are dividing. Why? Something like this will be much faster:
d = 1/norm(V)
V1 = V * d
Source: Stackoverflow.com