Create a matrix using elements of other vectors in matlab - matlab

I have two vectors a, b
a=[1; 2; 3; 4]
b=[1; 2; 3]
And I want to create a matrix which will look like this
c=[1 1; 2 1; 3 1; 4 1; 1 2; 2 2; 3 2; 4 2; 1 3; 2 3; 3 3; 4 3]

Here is yet another way!
c = [repmat(a,numel(b),1),sort(repmat(b,numel(a),1))]

I have a feeling that there is a much better way, still...
p1 = repmat(a,[numel(b),1]);
p2 = imresize(b,[numel(a)*numel(b) 1],'nearest');
answer = [p1 p2];
Found a better way:
[A,B] = meshgrid(a,b);
answer = [reshape(B,[],1) reshape(A,[],1)];
Chris Taylor suggests a more compact way:
[A B]=meshgrid(a,b); [B(:) A(:)];

Related

How to permutate over columns for each row in a matrix in MATLAB?

I have a matrix
A = [1,2;3,4];
I would like to generate a new matrix B, which contains all permutations over the columns for each row.
B = [1,2;2,1;3,4;4,3]
Is there a one-liner solution?
I could only think of a solution incorporating cell arrays, thus I'm not sure, if that is "efficient" at all. Also, have a look at the limitations of perms.
% Input.
A = [1, 2; 3, 4]
% Expected output.
B = [1, 2; 2, 1; 3, 4; 4, 3]
% Calculate output.
C = sortrows(cell2mat(cellfun(#(x) perms(x), mat2cell(A, ones(1, size(A, 1)), 2), 'UniformOutput', false)))
A =
1 2
3 4
B =
1 2
2 1
3 4
4 3
C =
1 2
2 1
3 4
4 3
I found a solution to my own question.
n = 2; % size of permutations
perm_index = perms(1:n); % index of the matrix to perm
perm_length = size(perm_index,1);
data = [3,4;5,6];
data_length = size(data,1);
output_length = perm_length* data_length;
output = reshape(data(:,perm_index), output_length,n);
%Final output
output = [4,3;6,5;3,4;5,6]
I couldn't find any one-liner solution. Hope this one is simpler enough:
A = [1, 2, 3; 4, 5, 6];
B = [];
for i=1:size(A,1)
B = [B ; perms(A(i, :))];
end
Read about the function nchoosek
A = [1 2 3 4] ;
B = nchoosek(A,2)

MATLAB : 3 dimensional matrix with multipication with a vector

I have A matrix which is 16x16x155460. I have a B vector which is 12955x1. I want to multiply each 1:16x1:16x1+12*n:12+12*nwith the elements of B(n). So my goal is to find the weighted sum of the A according to B. My way to do this as follows (I don't want to use for-loop and my method gives wrong answer, I could not obtain the 1:12 vectors which is consecutive) :
B = repmat(B,[1 16 16]);
B = permute(B,[2 3 1]);
B = repmat(B,[1 1 12]);
result = B.*(A);
As a small example n=2 :
A(:,:,1)=[1 2; 3 4]
A(:,:,2)=[1 2; 3 4]
A(:,:,3)=[1 2; 3 4]
A(:,:,4)=[1 2; 3 4]
B = [2,3]
Result would be:
result(:,:,1)=A(:,:,1)*B(1);
result(:,:,2)=A(:,:,2)*B(1);
result(:,:,3)=A(:,:,1)*B(2);
result(:,:,4)=A(:,:,2)*B(2);
If I understood the problem correctly, you can use the powerful trio of bsxfun, permute and reshape to solve it, like so -
[M,N,R] = size(A);
mult_out = bsxfun(#times,reshape(A,M,N,numel(B),[]),permute(B(:),[4 3 1 2]))
out = reshape(mult_out,M,N,[])

removing missing elements from a vector

I have a vector B=[1; 2; 1; 2; 3; 5; 6; 8; 9; 10]
where the elements a=[4 7] are missing.
I would like to map B to a "continuous" vector like
B_map=[1; 2; 1; 2; 3; 4; 5; 6; 7; 8]
removing the "missing" elements (4 7) and "scaling" the rest accordingly..
my problem is that depending on the number of missing elemenst (in this case 2) I have to scale the vector B of different amounts...
I think I figured it out...
a = sort(a);
B_map = B;
for i = 1:numel(a)
clear id_sub
id_sub = find(B >= a(i));
B_map(id_sub) = B_map(id_sub)-1;
end

Copy vector to vector in Matlab

I have a simple question about how can I copy a vector into another. I have a vector with a length of 66x1 and then, another with a length of 2151x1. I want to copy the values from the first one in a exactly position on the other. I've tried that but it doesn't work.
inter= 66x1
out= 2151x1
for i=1:numel(inter)
out(101:167)= inter(i)
end
Also I've tried this:
for inter=(1:66);
out(101:167)=inter;
end
And this:
for k= (101:167)
out(k)=inter(1:66);
end
Am I doing wrong? Thanks in advance,
Let's say your vectors are
a = [1; 2; 3];
b = [4; 5; 6; 7; 8; 9];
for simplicity.
There is no need to use loops. You can just go ahead and do it like this:
startIdx = 2; %101 in your case
finalIdx = startIdx + size(a,1) - 1; % 166 in your case
b(startIdx:finalIdx) = a;
Then b would be:
b =
4
1
2
3
8
9
A very important point here is the -1 in finalIdx. You need to substract 1 from the final index.

Flattening a matrix in MATLAB with indexes

I have a matrix X e.g = [a b; c d; e f].
I need to create another matrix listing the index positions and values of the matrix.
e.g. The output is E = [ 1 1 a ; 1 2 b ; 2 1 c ; 2 2 d ; 3 1 e ; 3 2 f ]
I have been trying to use a double for loop but even if it did work, that sounds like a bad idea.
So can anyone has a better idea to perform above task?
Here is the dumbest thing I could think of (Assuming that a,b,c,d,e,f are all scalars)
x = [1 2;3 4;5 6];
[i,j]=ind2sub(size(transpose(x)), 1:numel(x));
[j(:) i(:) reshape(transpose(x),[],1)]
However, I have a feeling that there might be an answer that is more elegant.
Nothing wrong with #Andrey's answer, but because I like to find reasons to use kron :)
A = [1 2; 3 4; 5 6];
[nrows, ncols] = size(A);
M = [kron([1 : nrows]', ones(ncols, 1))...
kron(ones(nrows, 1), [1 : ncols]')...
reshape(A', [], 1)]