Multiply each row of a matrix with its transposed self - matlab

The formula I have to translate to Octave/Matlab goes something like this:
\sum (v_i - m) (v_i - m)^T
I have a matrix, and I need to take each row, subtract m from it and then multiply it with its own transpose. I wrote the inner part as a function:
function w = str(v, m)
y = v - m
w = y * transpose(y)
end
My matrix is like this
xx = [1 2 3 4 5; 1 2 3 4 5; 1 2 3 4 5]
Now I have no idea how to apply this function to each row in a matrix and then sum them up to a new matrix. Maybe someone can help me here.
EDIT: The result is not the dot product. I'm looking for v * v^T, which has a matrix as result!

Probably you need this
X = bsxfun( #minus, A, m );
Y = X'* X;

Suppose the matrix is A, then the solution is
total = sum(sum((A-m).*(A-m),2));
A.*A is an element wise multiplication, hence sum(A.*A,2) returns a column vector, with each element being the self dot product of each row in A.
If m is a vector then, it is slightly more complicated.
[p,~]=size(A);
total = sum(sum((A-repmat(m,p,1)).*(A-repmat(m,p,1)),2));
Cheers.

In the end, I wrote this:
function w = str(v, m)
y = v - m;
w = y' * y;
end
y = zeros(5,5);
for i=1:12
y = y + str(A(i,:), m);
end
Surely not the most elegant way to do this, but it seems to work.

You can subtract the mean using bsxfun
>> v_m = bsxfun( #minus, v, m );
For the sum of outer product of all vectors you can use bsxfun again
>> op = bsxfun( #times, permute( v, [3 1 2]), permute( v, [1 3 2] ) );
>> op = sum( op, 3 );

There are two ways to solve this issue:
Assume A is your matrix:
sum(drag(A' * A))
will do the job. However, it is slightly more efficient with the following:
sum((A .* A)(:))

Related

There is a function in Matlab to create a matrix, where each element is the same function of matrix indexes?

For example, a matrix where each value at row r and column c is
a=[r^2+c^2]
like a=[1, 4; 4; 18]
or
A=[F(r,c)]
A=[F(1,1) F(1,2) F(1,3);
F(2,1) F(2,2) F(2,3);
F(3,1) F(3,2) F(3,3)]
or
A(r,c)=F(r,c)
Mehtod 1
You can do it manually. First, create two matrices for rows and columns indices (suppose the matrix is n x m):
R = repmat((1:n).',[1, m]);
C = repmat((1:m),[n, 1]);
Then, write the function base on these two:
result = R.^2 + C.^2; % F(x,y) = x^2 + y^2
Or define the function inline and apply it on those two:
F = #(x,y)(x.^2 + y.^2);
result = F(R,C);
Mehtod 2
By #Cris Luengo, you can do it the first part by the meshgird function as well. Hence, we can generate R and C like the following:
[C,R] = meshgrid(1:n, 1:m)

What is a quick way to compute the euclidean norm of two sets of vectors?

I know that MATLAB works better when most or everything is vectorized. I have two set of vectors X and T. For every vector x in X I want to compute:
this is because I want to compute:
which can be easily expressed as MATLAB linear algebra operations as I wrote above with a dot product. I am hoping that I can speed this up by having those vectors, instead of computing each f(x) with a for loop. Ideally I could have it all vectorized and compute:
I've been think about this for some time now, but it doesn't seem to be a a nice way were a function takes two vectors and computes the norm between each one of them, with out me having to explicitly write the for loop.
i.e. I've implemented the trivial code:
function [ f ] = f_start( x, c, t )
% Computes f^*(x) = sum_i c_i exp( - || x_i - t_i ||^2)
% Inputs:
% x = data point (D x 1)
% c = weights (K x 1)
% t = centers (D x K)
% Outputs:
% f = f^*(x) = sum_k c_k exp( - || x - t_k ||^2)
[~, K] = size(t);
f = 0;
for k=1:K
c_k = c(k);
t_k = t(:, k);
norm_squared = norm(x - t_k, 2)^2;
f = f + c_k * exp( -1 * norm_squared );
end
end
but I was hoping there was a less naive way to do this!
I think you want pdist2 (Statistics Toolbox):
X = [1 2 3;
4 5 6];
T = [1 2 3;
1 2 4;
7 8 9];
result = pdist2(X,T);
gives
result =
0 1.0000 10.3923
5.1962 4.6904 5.1962
Equivalently, if you don't have that toolbox, use bsxfun as follows:
result = squeeze(sqrt(sum(bsxfun(#minus, X, permute(T, [3 2 1])).^2, 2)));
Another method just for kicks
X = [1 2 3;
4 5 6].';
T = [1 2 3;
1 2 4;
7 8 9].';
tT = repmat(T,[1,size(X,2)]);
tX = reshape(repmat(X,[size(T,2),1]),size(tT));
res=reshape(sqrt(sum((tT-tX).^2)).',[size(T,2),size(X,2)]).'

How can I use from ismember

Assuming
A=[32512199.30 5401000.29 347.33
32512199.69 5401000.45 347.39
32512199.67 5401001.32 353.58
32512199.96 5401001.50 346.99
32512196.71 5401001.69 346.62 ]
and
B=[32512199.30 5401000.29 347.33
32512199.69 5401000.45 347.39
32512199.67 5401001.32 347.00
32512198.85 5401000.91 347.25
32512196.71 5401001.69 346.87 ]
I want using ismember extract the rows that have same X and Y and different Z. X is first column, Y is the second and Z is third.
in A and B I want extract from A 32512199.67 5401001.32 353.58 and 32512196.71 5401001.69 346.62 OR from B 32512199.67 5401001.32 347.00 and 32512196.71 5401001.69 346.87
How can I do it?
inds = find(~ismember(A, B, 'rows'));
new_inds = find(ismember(A(inds, 1:2), B(:, 1:2), 'rows'));
inds(new_inds)
First find the row indices of desired match using ismember and find. Then extract those rows from A/B to XA/XB
row_idx = find ( ismember( ismember(A,B), [1 1 0], 'rows') )
XA = A(row_idx,:)
XB = B(row_idx,:)
Output:
row_idx =
3
5
XA =
3.2512e+07 5.4010e+06 3.5358e+02
3.2512e+07 5.4010e+06 3.4662e+02
XB =
3.2512e+07 5.4010e+06 3.4700e+02
3.2512e+07 5.4010e+06 3.4687e+02

Can I do the following fast in Matlab?

I have three matrices in Matlab, A which is n x m, B which is p x m and C which is r x n.
Say we initialize some matrices using:
A = rand(3,4);
B = rand(2,3);
C = rand(5,4);
The following two are equivalent:
>> s=0;
>> for i=1:3
for j=1:4
s = s + A(i,j)*B(:,i)*C(:,j)';
end;
end
>> s
s =
2.6823 2.2440 3.5056 2.0856 2.1551
2.0656 1.7310 2.6550 1.5767 1.6457
>> B*A*C'
ans =
2.6823 2.2440 3.5056 2.0856 2.1551
2.0656 1.7310 2.6550 1.5767 1.6457
The latter being much more efficient.
I can't find any efficient version for the following variant of the loop:
s=0;
for i=1:3
for j=1:4
x = A(i,j)*B(:,i)*C(:,j)';
s = s + x/sum(sum(x));
end;
end
Here, the matrices being added are normalized by the sum of their values after each step.
Any ideas how to make this efficient like the matrix multiplication above? I thought maybe accumarray could help, but not sure how.
You can do it efficiently with bsxfun:
aux1 = bsxfun(#times, permute(B,[1 3 2]), permute(C,[3 1 4 2]));
aux2 = sum(sum(aux1,1),2);
s = sum(sum(bsxfun(#rdivide, aux1, aux2),3),4);
Note that, because of the normalization, the result is independent of A, assuming it doesn't contain any zero entries (if it does the result is undefined).

Matlab Generating a Matrix

I am trying to generate a matrix in matlab which I will use to solve a polynomial regression formula.
Here is how I am trying to generate the matrix:
I have an input vector X containing N elements and an integer d. d is the integer to know how many times we will add a new column to the matrix we are trying to generate int he following way.
N = [X^d X^{d-1} ... X^2 X O]
O is a vector of same length as X with all 1's.
Everytime d > 2 it does not work.
Can you see any errors in my code (i am new to matlab):
function [ PR ] = PolyRegress( X, Y, d )
O = ones(length(X), 1)
N = [X O]
for j = 2:d
tmp = power(X, j)
N = [tmp N]
end
%TO DO: compute PR
end
It looks like the matlab function vander already does what you want to do.
The VANDER function will only generate powers of the vector upto d = length(X)-1. For a more general solution, you can use the BSXFUN function (works with any value of d):
N = bsxfun(#power, X(:), d:-1:0)
Example:
>> X = (1:.5:2);
>> d = 5;
>> N = bsxfun(#power, X(:), d:-1:0)
N =
1 1 1 1 1 1
7.5938 5.0625 3.375 2.25 1.5 1
32 16 8 4 2 1
I'm not sure if this is the order you want, but it can be easily reversed: use 0:d instead of d:-1:0...