LibettenRadler
LibettenRadler

Reputation: 115

How to normalize a matrix of 3-D vectors

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

Answers (2)

Eitan T
Eitan T

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

Cris Luengo
Cris Luengo

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

Related Questions