Reputation: 115
I have a 512x512x3 matrix that stores 512x512 three-dimensional vectors. What is the best way to normalize all those vectors, so that my results are 512x512 vectors with length that equals 1?
At the moment I use for loops, but I don't think that is the best way in MATLAB.
Upvotes: 2
Views: 3581
Reputation: 32920
If the vectors are Euclidean, the length of each is the square root of the sum of the squares of its coordinates. To normalize each vector individually so that it has unit length, you need to divide its coordinates by its norm. For that purpose you can use bsxfun
:
norm_A = sqrt(sum(A .^ 2, 3)); %// Calculate Euclidean length
norm_A(norm_A < eps) == 1; %// Avoid division by zero
B = bsxfun(@rdivide, A, norm_A); %// Normalize
where A
is your original 3-D vector matrix.
EDIT: Following Shai's comment, added a fix to avoid possible division by zero for null vectors.
Upvotes: 4
Reputation: 60454
The existing answer is very much outdated. Since R2016b, bsxfun
is no longer useful, element-wise binary operators automatically expand singleton dimensions. So instead of
B = bsxfun(@rdivide, A, norm_A);
you can do
B = A ./ norm_A;
And since R2017b, there is the function vecnorm
, which computes the norm of the vectors in a matrix. So instead of
norm_A = sqrt(sum(A .^ 2, 3));
you can do
norm_A = vecnorm(A, 2, 3); % 3 is the dimension along which to compute
This simplifies the operations sufficiently to make a one-liner readable:
B = A ./ vecnorm(A, 2, 3);
Upvotes: 0