How does "/" really work on two row vectors? - matlab

I have the following basic observation:
[1 2 3 4]/[2 4 6 8] % output: 0.5
[1 2 3 4]/[2 3 4 5] % output: 0.7407
([1 2 3 4]*[2 4 6 8] % error of course)
It does not look for me as A*inv(B) kind of operation (nor like mrdivide on timeseries which would work like [1 2 3 4]./[2 4 6 8] if Im not mistaken).
Now, my question is, what operation does "/" define on two row vectors with the same length?
UPDATE:
#user1884905 gave the idea that a/b on two row vectors might minimise norm(b*x - a). So far it seemed to work on some numeric tests. If it is true, can you give some official reference behind this please?

Yes, it seems I was right. From MathWorks mrdivide
"If A is a rectangular m-by-n matrix with m ~= n, and B is a row vector with n elements or a matrix with n columns, then x = B/A returns a least-squares solution of the system of equations x*A = B."

Related

How to add vectors of different length in MATLAB

I'm trying to do the following:
Let's say I have:
x1=[7];
x2=[3 4];
x3=[1 -1 5];
x4=[2 5 -1 3];
and I want to add them together.
I know it's not possible to add vectors of different dimensions, but what I'm trying to achieve is a new vector having:
v=[2 5+1 -1-1+3 3+5+4+7];
I tried to pad the relevant vectors with zeros, to get:
x1=[0 0 0 7];
x2=[0 0 3 4];
x3=[0 1 -1 5];
x4=[2 5 -1 3];
and then the addition will be natural, but couldn't find a way to do it.
Of course, I'm looking for an iterative method of doing that, meaning, every vector xi is the result of the i'th iteration, where the number of iterations, n, is known in advance. (in the above example n=4)
My first thought would be something like
x1 = [zeros(1, 4 - length(x1)) x1];
Where you would substitute max(all_your_arrays) for 4 in the above line. If your arrays are in cell arrays you should be able to easily adapt that to a loop.

nth permutation of a vector in MATLAB

Suppose I have a vector of integers like this:
A = [1 2 3]
What I need is nth permutation of vector A. As we now a vector of n numbers has n! permutation, For example some permutation of A is:
[1 2 3]
[1 3 2]
[2 1 3]
[2 3 1]
...
Is there any built-in function for calculating nth permutation? if not, can anyone please offer me a efficient algorithm for calculate it? Any suggestion would be highly appreciated
I found my answer from #Divakar comment (special thanks to #Divakar)
What I need is:
% this my vector 1, 2, 3 , ..., N
A = 1 : N;
P = perms(A);
% nth permutation of A is nth row of P
nthPerm = P(n, :);
If A is just the trivial sequence 1:N, as #Divakar said, the command
perms(1:N)
produces the permutations you need.
If A is an array whose content is generic and whose length is N, perms can be used to obtain the indices allowing the permutations, i.e.
A_permutations = A(perms(1:N))
Example:
given
A =
3 7 9
A(perms(1:3))
9 7 3
9 3 7
7 9 3
7 3 9
3 7 9
3 9 7
perms(v) works for the n! case,
http://www.mathworks.de/matlabcentral/fileexchange/11462-npermutek/content/npermutek.m
works for the n^n or n^k case.
If you like doing stuff in less lines of code, you can also do:
A=1:N;
nthPerm=getfield(perms(A),{n,A})
Note that this is only valid if A=1,2,3,...,N. For different values of A, you would have to change this into:
A=1:N;
nthPerm=getfield(perms(A),{n,1:length(A)})

Matlab matrices dimension

I am new to matlab and just wondering if you guys can help me out with this problem.
For instance, I have two matrices:
A = [X1 X2 X3 X4]
B = [Y1; Y2; Y3]
now what I really want to achieve is to multiply these two matrices in this way:
[X1Y1 X2Y1 X3Y1 X4Y1;
X1Y2 X2Y2 X3Y2 X4Y2;
X1Y3 X2Y3 X3Y3 X4Y3;
.... and so on]
I tried using A(1,:).*B(:,1) but matlab is saying that matrix dimensions must agree.
I just don't know how to manipulate this on matlab but in excel is possible.
This is a simple outer product. kron is not needed (although it will work.) bsxfun is wild overkill, although will yield what you have asked for. repmat is inappropriate, because while it will help you do what you wish, it replicates the arrays in memory, using more resources than are needed. (Avoid using inefficient programming styles when there are good ones immediately at your disposal.)
All you need use is the simple * operator.
A is a row vector. B a column vector.
C = B*A
will yield the result C(i,j)=B(i)*A(j), which is exactly what you are looking for. Note that this works because B is 3x1 and A is 1x4, so the "inner" dimensions of B and A do conform.
In MATLAB, IF you are unsure if something works, TRY IT!
A = [1 2 3 4];
B = [1;2;3];
C = B*A
ans =
1 2 3 4
2 4 6 8
3 6 9 12
See that kron did indeed work, although I'd bet that use of kron here is probably less efficient than is the simple outer product multiply.
C = kron(B,A)
C =
1 2 3 4
2 4 6 8
3 6 9 12
As well, bsxfun will work here too, although since we are using a general tool to do something that a basic operator will do, I'd bet it is slightly less efficient.
C = bsxfun(#times,B,A)
C =
1 2 3 4
2 4 6 8
3 6 9 12
The WORST choice is repmat. Again, since it artificially replicates the vectors in memory FIRST, it must go out and grab big chunks of memory in the case of large vectors.
C = repmat(B,1,4).*repmat(A,3,1)
C =
1 2 3 4
2 4 6 8
3 6 9 12
I suppose for completeness, you could also have used meshgrid or ndgrid. See that it is doing exactly what repmat did, but here it explicitly creates new matrices. Again, this is a poor programming style when there are good tools to do exactly what you wish.
[BB,AA] = ndgrid(B,A)
BB =
1 1 1 1
2 2 2 2
3 3 3 3
AA =
1 2 3 4
1 2 3 4
1 2 3 4
C = BB.*AA
C =
1 2 3 4
2 4 6 8
3 6 9 12
What you need to understand is exactly why each of these tools COULD have been used for the job, and why they are different.
In Matlab there is * and .* and they are very different.
* is normal matrix multiplication which is what you want i.e. B*A, note the B must come first as the inner dimension must match. You can multiply a column by a row but not a row by a column (unless they have the same number of elements).
.* is element by element multiplication in which case the matrices must be exactly the same size and shape so for example [1 2 3].*[4 5 6] = [1*4 2*5 3*6] = [4 10 18]
Do not do a ".*". You should rather do a "*".
The ".*" is for index by index multiplication and should have given you [X1Y1 X2Y2 X3Y3] were they vectors have been equal in size.
If you do the regular multiplication "*", this is actually matrix multiplication.
I think you just need to transpose one of the vectors. You are multiplying a column vector (A(1,:)) with a row vector (B(:,1)). This should work:
C = A(1,:).*B(:,1)';

How to do rank-1 factorization in MATLAB?

I have a matrix M of dimensions 6x6 and it has rank 1. How can I factorize it into two matrices of dimensions 6x1 (say A) and 1x6 (say B) so that M=A*B.
take the largest eigen vector and multiply it by the largest eigenvalue :
A=[1 2 3 4]'*[1 2 3 4]
A =
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
[v,e] = eigs(A,1);
sqrt(e)*v
ans =
-1.0000
-2.0000
-3.0000
-4.0000
of course, the result is good only up to a sign change.
EDIT:
if you assume that the two vectors can be different:
A=[1 2 3 4]'*[5 6 7 8]
[uu,ss,vv]=svd(A);
u=uu(:,1)*ss(1,1)
v=vv(:,1)
assert(norm(u*v'-A)<1E-10)
Now the solution is even less unique. You are determining 2*n values based on only n. This is one solution among many.
For example, look at this other even simpler solution (which will assume your matrix is perfectly rank 1) :
aa=A(:,:)./repmat(A(1,:),[size(A,1),1]);
bb=A(:,:)./repmat(A(:,1),[1,size(A,2)]);
u=aa(:,1);
v=bb(1,:)'*A(1);
assert(norm(u*v'-A)<1E-10)
it produces a totally different result, but that still factorizes the matrix. If you want non-negative factorizations only to slightly reduce the space of possible results, I'd suggest you ask a new question!
If it has rank 1, then all columns/rows are multiples of the first column/row (or indeed of any non-zero column/row). i.e.:
m = M(:,1);
M = [ a*m, b*m, c*m, d*m, e*m, f*m ];
Hopefully you can take it from there.

How to efficiently access/change one item in each row of a matrix

I have a matrix A with size (nr,nc), a vector of column indices B (so B has size (nr,1) and every element in B is an integer between 1 and nc), and I want to do something to every element in A that is of the form A(i,B(i)) for i between 1 and nr, efficiency being the key concern.
For concreteness, say C is a vector of size (nr,1), the goal is to do
for i=1:nr
A(i,B(i))=A(i,B(i))+C(i)
end
more efficiently. The context is usually that nr>>nc (because when nr is large vectorization is efficient for many operations). I have gotten a factor 3 speedup by using an indicator function approach:
for k=1:nc
A(:,k)=A(:,k)+(k==B).*C
end
Are there other ways (more efficient hopefully) to do this?
I guess this is similar to many questions on double-indexing, but it's concretely one I run into all the time.
Use linear indexing:
idx = sub2ind(size(A), 1:nr, B');
A(idx) = A(idx) + C';
or (edited version with one less transpose)
idx = sub2ind(size(A), (1:nr)', B);
A(idx) = A(idx) + C;
One way would be to use linear indexing of the matrix. You will need a vector v holding the offsets of the first element in each line, then index using A(v + B). For example:
>A=[1 2 3; 4 5 6; 7 8 9]
A =
1 2 3
4 5 6
7 8 9
>B = [1 2 3] % we want the 1st element of row 1, 2nd of row 2, 3rd of row 3
>ii = [0 3 6] + B
>a(ii)
1 5 9
Note: As groovingandi had shown, it is also possible (and more readable) to use sub2ind to generate the ii linear indices vector. The idea is essentially the same.