2

I have a vector:

vector = [1 2 3;4 5 6; 7 9 0]
vector =

     1     2     3
     4     5     6
     7     9     0

I want to take this and create a unit vector. We can get the magnitude by doing:

mag = sqrt(sum(vector'.^2))'

mag =

    3.7417
    8.7750
   11.4018

When we try to divide each element by the magnitude I get an error:

vector./mag
Error using  ./ 
Matrix dimensions must agree.

Essentially I must divide every vector element in each row by every row in the mag vector. How can I do this?

Kevin
  • 3,077
  • 6
  • 31
  • 77

5 Answers5

9

The other answers give the correct result but you can vectorize the calculation for faster calculation.

ret = bsxfun(@rdivide, vector, mag)

I recommend using the bsxfun, it is a very useful function for matrix calculation.

oro777
  • 1,110
  • 1
  • 14
  • 29
  • 2
    Just did a quick timing on bsxfun versus repmat in Octave: `>> tic; zeros(10000,10000) + repmat((1:10000)',1,10000); toc Elapsed time is 1.18 seconds.` `>> tic; bsxfun(@plus, zeros(10000,10000), (1:10000)'); toc Elapsed time is 0.726 seconds.` – stephematician Nov 24 '16 at 06:24
  • 4
    @stephematician `bsxfun` is always faster. See this related article: http://stackoverflow.com/questions/12951453/in-matlab-when-is-it-optimal-to-use-bsxfun – rayryeng Nov 24 '16 at 07:14
3

The problem is that, as the error message says, the dimensions of vector and mag don't match. You want to divide every element of the first row of vector by mag(1). What you need is repmat(), which "repeats copies of array". Writing

repmat(mag,1,3)

returns a 3x3 matrix such that every column is an exact copy of mag:

    3.7417    3.7417    3.7417
    8.7750    8.7750    8.7750
   11.4018   11.4018   11.4018

So you can use the one-liner:

vector./repmat(mag,1,3)
ans =

   0.26726   0.53452   0.80178
   0.45584   0.56980   0.68376
   0.61394   0.78935   0.00000

That way, the first row of vector, i.e., [1 2 3], is divided element-by-element by [3.7417 3.7417 3.7417]. In other words, every element of vector is divided by the correct magnitude.

jadhachem
  • 1,123
  • 2
  • 11
  • 19
2

A simple solution is the use of a for-loop:

vector = [1 2 3; 4 5 6; 7 9 0];
mag = sqrt(sum(vector'.^2))';
A = [];
for i = 1:numel(mag)
    A(i,:) = vector(i,:)./mag(i);
end
Gumboy
  • 467
  • 4
  • 8
  • A for loop is almost never the best option in Matlab when considering vector operations. – Bernhard Nov 24 '16 at 06:36
  • 1
    The problem here is not the for loop (which as you said it might give comparable results to bsxfun) but the preallocation of `A`. If you don't preallocate it will for sure be way slower. –  Nov 24 '16 at 11:48
2

You can use matrix operators in MATLAB:

result = diag(1./mag)*vector;

If dimension of mag can be too big you can use sparse version of it:

result = spdiags(1./mag,0,speye(numel(mag)))*vector;
Mohsen Nosratinia
  • 9,844
  • 1
  • 27
  • 52
1
vector = [1 2 3; 4 5 6 ;7 9 0] ;

[n,m]=size(vector);

for i=1:n
normv=norm(vector(i,:),2);
nvector(i,:)=vector(i,:)/normv;
end

the nvector will contain the normalized vector of each line

safa ahmed
  • 11
  • 2
  • Other than the explicit call to `norm` to find the magnitude, this answer isn't any different from the others seen so far here. – rayryeng Nov 24 '16 at 18:06