write result as matrix form - matlab

let us consider following matrix
a=[1 2 3;2 3 4;3 4 5;4 5 7]
a =
1 2 3
2 3 4
3 4 5
4 5 7
let us consider it's svd
[U E V]=svd(a)
U =
-0.2738 -0.8708 -0.0062 -0.4082
-0.3984 -0.2552 -0.3309 0.8165
-0.5230 0.3605 -0.6557 -0.4082
-0.7020 0.2159 0.6786 0.0000
E =
13.5093 0 0
0 0.6482 0
0 0 0.2797
0 0 0
V =
-0.4032 0.8699 0.2841
-0.5437 0.0220 -0.8390
-0.7361 -0.4928 0.4641
if consider kronecker product of columns of U and V matrix
kron(U(:,1),V(:,1))
ans =
0.1104
0.1489
0.2015
0.1606
0.2166
0.2932
0.2109
0.2843
0.3849
0.2831
0.3817
0.5167
but it is returning as vector form,but i need matrix form,so how can i transform it to matrix insider kron product?maybe i should you reshape command,but could you help me to do it?thanks in advance

i have consider following change as Divakar adviced and it works fine
X=kron(U(:,1),V(:,1)')
X =
0.1104 0.1489 0.2015
0.1606 0.2166 0.2932
0.2109 0.2843 0.3849
0.2831 0.3817 0.5167
thanks my friend for your help

Related

Matlab how to distribute a matrix elements randomly

hi everyone how to make a matrix randomly distributed to another matrix n,
m = [ 1 1 3 3 3 4 4 6 6 7 7 7];
n = zeros(3,10);
the same value must in the sequence, ex : 4 4 4, 7 7 7.result reqiured can be something like {or other combinations):
distributed_matrix =
0 1 1 0 7 7 7 0 0 0
0 0 3 3 3 4 4 0 0 0
6 6 6 0 0 0 0 0 0 0
thank you...
If you do not impose any constraint on the order at which the elements of m are distributed, then randsample might help:
ridx = randsample( numel(n), numel(m) ); %// sample new idices for elelemtns
n(ridx) = m;
Looking into the additional constraints, things get a bit more messy.
For identifying the sequences and their extent in m, you can:
idx = [1 find(diff(m)~=0)+1];
extent = diff([idx numel(m)+1]); %// length of each sequence
vals = m(idx); %// value of each sequence
Once you have the sequqnces and their length you can randomly shuffle them and then distribute along the lines...
If I understand your question correctly, the possible solution is
m = [ 1 1 3 3 3 4 4 6 6 7 7 7];
n = zeros(3,10);
p= randperm(numel(n)); % generate the random permutation
n(p(1:length(m)))= m % assign the elments of m to the elements with indices taken
% from the first length(m) numbers of random permutation

Find if 2 vectors have 4 consecutive identical elements

I am trying to compare 2 vectors to discover if they share 4 consecutive values.
For example
w = [6 7 8 9 10 11 12 13 14]
v = [5 6 7 8 9]
Has 4 consecutive values 6 7 8 9
But
x = [6 7 8 9 10 11 12 13 14]
y = [6 7 1 2 3 4 5 6 13 14]
has four identical values (6 7 13 14) but they aren't consecutive.
The code I am currently using is:
if length(intersect(v, w)) >= 4
condition = true;
but this doesn't test for consecutive elements, so it would return true for both cases listed above whereas I want it to only return true for the first case.
Can somebody please help me find a way to test for identical consecutive elements rather than just identical elements.
Building on Marcos' answer:
Create all possible search vectors from your initial search (i.e. [5 6 7 8] [6 7 8 9]) - however we will make it a 3D matrix which will be m-by-1-by-n
n = 4;
m = numel(v)-n+1;
V = permute(v(bsxfun(#plus,(0:m-1)',1:n)),[1,3,2])
Check if any of these sub-vectors are a subset of the vector being searched
check = sum(any(bsxfun(#eq, V, w),3),2) >= n;
match = squeeze(V(check,:,:))' %'// The ' is debatable here, it depends on how many matches you get
you can compare
bsxfun(#eq, w,v')
Resulting with
ans =
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0
As you can see four consecutive matching elements form a diagonal of length 4.
To find the location of this diagonal you can conv2 with a 4 diagonal filter (eye(4)):
[rr cc] = find( conv2( single(bsxfun(#eq, [1 2 3 w],v')), eye(4), 'same' ) == 4 )
compensating for the center of the filter
loc_in_w = cc - 1
loc_in_v = rr - 1
yielding
loc_in_w =
1
loc_in_v =
2
which are the first index of the sequence in w and v respectively.
This method can work with more than one occurrence of a 4-substring of v in w...
I haven't meddled in matlab for ages, but my "general" approach to this in computing terms would be splitting the problem into a needle-and-haystack solution with two parts:
Create all possible search vectors from your initial search (i.e. [5 6 7 8] [6 7 8 9])
Check if any of these sub-vectors are a subset of the vector being searched.
Basically just two set-operations in a row.
You could convert your vectors to strings, and use strfind.
If x and y are your vectors:
x_str = mat2str(x);
y_str = mat2str(y);
n = strfind(x_str(2:end-1), y_str(2:end-1))
Note that you have to remove the first and last characters of the string version, as they correspond to the square brackets of the vectors.

Multiplying a small matrix by a big matrix

I'm trying to multiply every element in a small matrix (let's say 2x2) with every position in a big matrix (let's say 4x4), element by element.
So I want:
1 2 3 4 1 0 3 0
1 0 1 2 3 4 0 0 0 0
0 0 'x' 1 2 3 4 = 1 0 3 0
1 2 3 4 0 0 0 0
The small matrix is applied as many times as it fits, and the multiplication is element by element. I've tried a bunch of loops, but that doesn't feel right in MATLAB, there must be prettier ways of doing it?
One possibility is to use repmat to repeat the small matrix as many times as necessary:
C = repmat(A,size(B,1)/size(A,1),size(B,2)/size(A,2)).*B
Another possibility, which avoids repmat: cut up the large matrix, arrange the pieces in the third and fourth dimensions, and use bsxfun to do the multiplication:
[m n] = size(A);
[M N] = size(B);
T = permute(reshape(B,M,n,[]), [2 1 3]);
T = permute(reshape(T,n,m,[],size(T,3)),[2 1 3 4]);
C = cell2mat(squeeze(mat2cell(bsxfun(#times,T,A),m,n,ones(1,M/m),ones(1,N/n))));
(The two lines T = ... do the cutting, and are due to A. Donda.)
The advantage of this approach is that, if memory is an issue, you can overwrite B instead of defining T, thus saving memory:
[m n] = size(A);
[M N] = size(B);
B = permute(reshape(B,M,n,[]),[2 1 3]);
B = permute(reshape(B,n,m,[],size(B,3)),[2 1 3 4]);
C = cell2mat(squeeze(mat2cell(bsxfun(#times,B,A),m,n,ones(1,M/m),ones(1,N/n))));
If you have the image processing toolbox, you can try blkproc:
>> A = magic(4)
A =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
>> B = [1 0; 0 0];
>> C = blkproc(A,size(B),#(x) x.*B)
C =
16 0 3 0
0 0 0 0
9 0 6 0
0 0 0 0

Create matrix in Matlab enumerating coordinates

Is there an efficient way (e.g., without using for loops manually) to create a matrix in Matlab that enumerates the 2-D coordinates of a matrix of a given size?
For example, if I'm given an m x n matrix, I want the resulting mn x 2 matrix to be as follows:
1 1
1 2
1 3
...
1 n
2 1
2 2
...
m 1
m 2
...
m n
Thanks in advance!
mat = [1 2;3 4;5 6;7 8;9 10];
[m,n] = size(mat);
vec = [kron(1:m,ones(1,n)); kron(ones(1,m),1:n)]'
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
5 2
Robert P. has a correct (and elegant) answer with a nifty use of kron, but just for fun here's the alternative with ndgrid,
>> mat=zeros(5,2);
>> [nn,mm] = ndgrid(1:size(mat,2),1:size(mat,1))
>> vec = [mm(:) nn(:)]
vec =
1 1
1 2
2 1
2 2
3 1
3 2
4 1
4 2
5 1
5 2

How to group rows with same column values?

Given the matrix with coordinates in 3D space and values for two variables (say a and b) in two matrices I would like to merge rows for same points into a common matrix.
To clearly explain the matter, let's say we have matrices
A=[posX, posY, posZ, a]
and
B=[posX, posY, posZ, b]
and would like to combine them into
AB = [posX, posY, posZ, a, b]
for example
A = [0 0 1 1; 0 1 0 4; 5 0 12 8];
B = [0 0 0 5; 0 1 0 3; 5 11 7 7];
would give
AB = [0 0 0 0 5; 0 0 1 1 0; 0 1 0 4 3; 5 0 12 8 0; 5 11 7 0 7];
In order to do that I first created
ATemp = [A, zeros(length(A,0)]
and
BTemp = [B(:, [1 2 3]), zeros(length(B),1), B(:,4)]
and then tried to use functions accumarray and grpstats but haven't managed to form the AB matrix.
I would be very thankful if anyone suggested the way to get the desired matrix.
AB=union(A(:,1:3),B(:,1:3),'rows');
AB(ismember(AB,A(:,1:3),'rows'),4)=A(:,4);
AB(ismember(AB(:,1:3),B(:,1:3),'rows'),5)=B(:,4)
[edit] This solution is only valid if each (x,y,z)-point occurs only once in each matrix. If there are several, there is a dimension mismatch in the second line (and/or the third).