How can I use from ismember - matlab

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

Related

How to replace this for loop with matrix operations in matlab

I know that writing a for loop in Matlab is typically not efficient.
Now I am trying to replace a nested for loop with a better option.
Here is the nested loop,
for i = 1: size(A,1)
for j = 1: size(B,1)
S(i,j, :) = c*(A(i,:)*a - B(j,:)*b);
end
end
What operation should I use? (I was thinking about Cartesian product implementation)
Try the following
AA = permute(A * a, [1, 3, 2]);
BB = permute(B * b, [3, 1, 2]);
CC = c * bsxfun(#minus, AA, BB);
nA = size(A,1);
nB = size(B,1);
Ar = repmat(A, nB, 1); %// repeat A along rows
Br = B(ceil(1/nA:1/nA:nB), :); %// stretch B along rows
S = c*(Ar*a-Br*b); %// do the computations
S = reshape(permute(S, [1 3 2]), nA, nB, []); %// put into shape
A=(1:20)'*ones(1,10);
size(A) % 20,10
a=ones(10,1)*(1:5);
size(a) %10,5
B=ones(3,1)*(1:20);
size(B) %3,20
b=ones(20,1)*(1:5);
size(b) %20,5
c=1;
Aa=A*a;
size(Aa) %20,5
Bb=B*b;
size(Bb) %3,5
na=size(Aa,1);
nb=size(Bb,1);
Ia=(1:na)'* ones(1,nb);
%Ia=1;2;3..nb;1;2;3..nb na times
Ia=reshape(Ia,na*nb,1);
%Ib=1;1;natimes;2;2;2 natimes...nb;nb;nb...natimes
Ib=ones(na,1)*(1:nb);
Ib=reshape(Ib,na*nb,1);
S=(Aa(Ia,:)-Bb(Ib,:))*c;
S=reshape(S,[na nb size(Aa,2)]);

Multiply each row of a matrix with its transposed self

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)(:))

Create Matrix using Matrix Indices

In matlab, how could you create a matrix M using its indices to populate the values? For example, say I want to create a 3x3 matrix M such that
M(i,j) = i+j --> [ 2 3 4; 3 4 5; 4 5 6]
I tried making vectors: x = 1:3', y = 1:3 and then
M = x(:) + y(:)
but it didn't work as expected.
Any thoughts on how this can be done?
Thanks!
UPDATE
The M I actually desire is:
M(i,j) = -2^(-i - j).
One way would be
x = 1:3;
z = ones(1,3);
N = z'*x + x'*z
M = -2 .^ -(z'*x + x'*z)
% Or simply
% M = -2 .^ -N
Output:
N =
2 3 4
3 4 5
4 5 6
M =
-0.250000 -0.125000 -0.062500
-0.125000 -0.062500 -0.031250
-0.062500 -0.031250 -0.015625
You should use bsxfun to find the sum:
M=bsxfun(#plus, (1:3).', 1:3)
and for the second formula:
M=-2.^(-bsxfun(#plus, (1:3).', 1:3))
bsxfun(#(x,y)(-2.^(-x-y)), (1:3).', 1:3)
This uses the Answer of Mohsen Nosratinia with the function you wished.

Obtain matrix of indices in octave / matlab

Given some multidimensional matrix A in Octave / Matlab,
What's the easiest way to get a matrix of the same size as A where all elements are replaced by their index along the k'th dimension
ie for the matrix
A =
ans(:,:,1) =
0.095287 0.191905
0.226278 0.749100
ans(:,:,2) =
0.076826 0.131639
0.862747 0.699016
I want a function f such that
f(A,1) =
ans(:,:,1) =
1 1
2 2
ans(:,:,2) =
1 1
2 2
f(A,2) =
ans(:,:,1) =
1 2
1 2
ans(:,:,2) =
1 2
1 2
and
f(A, 3) =
ans(:,:,1) =
1 1
1 1
ans(:,:,2) =
2 2
2 2
Also, given a sparse matrix B
What's the easiest way to get another sparse matrix of the same size where the nonzero elements are replaced by their index along the k'th dimension? (so same problem as above, but for only the nonzero elements)
Ideally I'm looking for a way which is well-vectorized for octave (meaning it doesn't explicitly loop over anything)
CLARIFICATION: For the sparse matrix one, I'm looking for a solution which does not involve creating a full size(B) matrix at any point
ndgrid() does what you want, although not in the format you are looking for. If you know the dims of the input A beforehand, you can use the following line to create the N-dimentional mesh grid:
% for matrix a where ndims(a) == 3
[x, y, z] = ndgrid (1:size(a,1), 1:size(a,2), 1:size(a,3));
% x is like f(a, 1)
% y is like f(a, 2)
% z is like f(a, 3)
You may be able to write a custom wrapper around ndgrid() to convert it to the function format you are looking for.
In case anyone's curious, since I didn't know about ndgrid, here's the answer I came up with:
function [y] = indices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = diag(1:n) * ones(size(y));
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction
function [y] = spindices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = spdiag(1:n) * spones(y);
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction

how to select specific index in 3rd matrix from third dimention in matlab

I know this is a simple question but difficult to formulate in one sentence to google the answer.So, I have a 3d matrix with size 2x2x3 like this
A(:,:,1) =[1 1; 1 1];
A(:,:,2) =[2 2; 2 2];
A(:,:,3) =[4 4; 4 4];
and matrix B with size 2x2
B = [ 1 2; 2 3];
What i need is to chose from each third dimension in A just one number using matrix B:
for i=1:2,
for j=1:2,
C(i,j) = A(i,j,B(i,j));
end
end
How to that in one line without a loop?
Not really a single line, but without a loop:
[I J] = ind2sub (size(B), 1:numel(B));
linInd = sub2ind (size (A), I, J, B(:)');
C = reshape (A(linInd), size(B));
Here is another variation:
[r,c,~] = size(A);
[J,I] = meshgrid(1:size(B,1), 1:size(B,2));
idx = reshape(I(:) + r*(J(:)-1) + r*c*(B(:)-1), size(B));
C = A(idx)