Reshape 59x16 double into 236x4? - matlab

How can I reshape a matrix in MATLAB, preferably using reshape?
A simple matrix setup:
A = [1 4 7 10; 2 5 8 11; 3 6 9 12]
that I want to reshape into
B = [1 4; 2 5; 3 6; 7 10; 8 11; 9 12]
I've tried numerous settings of reshape, but I cannot figure it out.
1 2 3 4
5 6 7 8
reshaped into
1 2
5 6
3 4
7 8

You can use reshape and permute:
reshape(permute(reshape(A,size(A,1),2,[]),[1 3 2]),[],2)
Thanks to #LuisMendo that suggests a modification to the answer to avoid depending on the size of A.

If I understand the transformation properly it is:
A = [1 4 7 10; 2 5 8 11; 3 6 9 12]
B = A(:,1:end/2);
B = [B;A(:,end/2+1:end)];
Is this correct?
EDIT:
Or the general case:
function [B] = elefaaant(A,n)
[a,b] = size(A);
if mod(b,n) ~= 0
error('Cannot reshape')
end
B = zeros(a*n,b/n);
fac = b/n;
for i = 1:n
B((i-1)*a+1:i*a,:) = A(:,(i-1)*fac+1:i*fac);
end

B = A(:,1:end/2);
B = [B;A(:,end/2+1:end)];
C = B(:,1:end/2);
C = [C;B(:,end/2+1:end)];
Maybe it can be done in a simpler way, but seems to work.

Related

permutation of separate rows of matrix

How to effectively vectorize the following MATLAB code, which performs permutation of each row of matrix R by indices in corresponding row of matrix P?
for i = 1:size(P,1)
pP(i,:) = R(i,P(i,:));
end
example:
P = [3 2 1;
3 1 2;
2 3 1;
2 1 3;
1 2 3;
1 3 2]
R = [6 5 4;
6 4 5;
5 6 4;
5 4 6;
4 5 6;
4 6 5]
produce following matrix pR:
4 5 6
5 6 4
6 4 5
4 5 6
4 5 6
4 5 6
One approach with bsxfun -
nrows = size(R,1)
pP = R(bsxfun(#plus,[1:nrows]',(P-1)*nrows))
Or with ndgrid -
[m,n] = size(R)
pP = R(sub2ind([m n],ndgrid(1:m,1:n),P))
Or replace ndgrid(1:m,1:n) with repmat: repmat([1:m]',[1 n]) or with meshgrid:meshgrid(1:m,1:n).'.
This might not be the best way to do it, but you could do something like:
IND1 = P(:,1)
Q(:,1) = diag(R(:,IND));
and repeat for P(:,2), P(:,3) in a similar fashion.
You can use arrayfun to avoid the loop but probably won't gain in performance if that it is the reason for vectorizing it:
cell2mat(arrayfun(#(k) R(k, P(k,:)), (1:size(P,1)).', 'uni', 0))

Repeat each row of a matrix

I have variable A of size m by n. I want to generate B of size m by m*n, such as below example.
Example:
A = [1 2 3;
4 5 6;
7 8 9]
Should result with
B = [1 2 3 4 5 6 7 8 9;
1 2 3 4 5 6 7 8 9;
1 2 3 4 5 6 7 8 9]
Is there any way to do that without using loop? m and n is variable.
You should use the repmat Matlab funtion:
B = repmat(A,M,N) creates a large matrix B consisting of an M-by-N
tiling of copies of A. The size of B is [size(A,1)*M, size(A,2)*N].
The statement repmat(A,N) creates an N-by-N tiling.
For your specific case one solution may be:
A=A';
B=repmat(A(:)',3,1);
And for the general case one solution may be:
A_aux=reshape(A',1,size(A,1)*size(A,2));
B=repmat(A_aux,size(A,1),1);
Repmat is indeed the way to go here, as mentioned by #Nerea. This solution should give the same answer as his, but personally I consider it to be a bit more elegant:
B=repmat(reshape(A',1,[]),size(A,1),1);
To include a quite fast bsxfun solution:
A = [1 2 3 4;
5 6 7 8;
9 10 11 12]
A = A.' %'
B = bsxfun(#plus,zeros(size(A,2),1),A(:).')
or use kron, but its surely slower:
A = A.'
B = kron(A(:),ones(1,size(A,2))).'
B =
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
No repmats
[m n] = size(A);
B = ones(m,1) * reshape( A.', 1, [] );
One approach
with repmat, reshape and permute combo!
out = repmat(reshape(permute(A,[3 2 1]),1,[]),size(A,1),1,1);
or Another approach without reshape but becomes a 2 liner
out1 = permute(A,[3 2 1]);
out = repmat(out1(:).',size(A,1),1,1);

How do I re organize the rows of a matrix using a vector in Octave?

I am trying to achieve something stupid here and I am struck at this one point.
Say I have a matrix X which is 5 * 3 and I have a vector B which is 5 * 1
X = [6 5 3;
4 5 6;
3 8 9;
7 8 9;
1 2 3]
B = [1;
5;
4;
2;
3]
How do I reorganize my X using B to get the order of indexes as indicated in B.
What I want to happen is ..
X = someoperation(X, B)
and X should be
X = [6 5 3;
1 2 3;
7 8 9;
4 5 6;
3 8 9]
I could write a function to do this but I see that inbuilt function are faster than functions that I write.
You don't need any functions, this is a simple case of subscript indexing, a basic feature of the language:
X(B,:)

How to take the rows of a matrix and save them in a cell array with MATLAB

this is my question:
I have this matrix A:
A=[1 2 3; 4 5 NaN; 6 8 9];
And I want to make something like this:
[B] = somefuntion(A)
Where B will have the next information:
B={[1 2 3];[4 5 NaN];[6 8 9]};
I hope that you can help me, thanks by the way!.
A=[1 2 3; 4 5 NaN; 6 8 9];
C = mat2cell(A,ones(1,size(A,1)),size(A,2))
Results:
C{1}=[ 1 2 3];
C{2}=[ 4 5 NaN];
C{3}=[ 6 8 9];
Couldn't you just use a simple loop?
for i = 1:size(A,2);
B{i} = A(i,:);
end
B = B';

How do I Combine two equal sized vectors element wise in MatLab?

I have two vectors:
a = [1 3 5 7 9];
b = [2 4 6 8 10];
That I need to combine together element wise. Meaning that I need the first element of vector a, then the first element of vector b, second of a, second of b, and so forth until I get the following:
combined = [1 2 3 4 5 6 7 8 9 10]
How do I do this within MatLab?
Edit
I ran a test of the top three answers (Josh, Marc, & Kronos) and compared the time it took to run them. I ran each 100 times after doing a 10 iteration warmup. The vectors created were exactly the same size in length (16e+6) and were random values ranging from 1 to 100:
Test Results
Test: Total Time (100 runs): Avg Time Per Exec:
Josh B 21.3687 0.2137
Marc C 21.4273 0.2143
Kronos 31.1897 0.3119
It appears that both Josh's and Marc's solutions are similar in execution time.
a = [1 3 5 7 9];
b = [2 4 6 8 10];
temp = [a; b];
combined = temp(:)';
This can be done by the following:
a = [1 3 5 7 9];
b = [2 4 6 8 10];
combinedSize = size(a, 2) * 2;
combined(1:2:combinedSize) = a;
combined(2:2:combinedSize) = b;
This is obviously assuming that your vectors are exactly the same size. If by chance you want to merge two vectors that are not the same size then you can do the following:
combinedSize = max(size(a, 2), size(b, 2)) * 2;
combined = NaN(1,combinedSize);
combined(1:2:size(a,2)*2) = a;
combined(2:2:size(b,2)*2) = b;
This will place a NaN for the remaining elements of the smaller vector. For example, given the following sample vectors:
a = [1 3 5 7 9 11];
b = [2 4 6 8];
will result in the combined vector:
combined =
1 2 3 4 5 6 7 8 9 NaN 11 NaN
Place the vectors below eachother in a matrix and use reshape. For example:
>> A=[1 2 3]
A =
1 2 3
>> B=[4 5 6]
B =
4 5 6
>> C=reshape([A;B],1,size(A,2)+size(B,2))
C =
1 4 2 5 3 6
It's straightforward to generalize to more than 2 vectors.
You can also give a try to looping, for example:
a=[1 2 3 4 5];
b=[11 12 13 14 15];
for i = 1:N
{
if (i%2==0)
{ c[i] = b[i]; }
else
{ c[i] = a[i]; }
This shall work!
All the answers above only work if the two vectors have the same number of elements. The following will work even if they have different number of elements:
>>
A = [1 3 5];
B = [2 4 6 7 8];
C = [1 3 5 7 8];
D = [2 4 6];
AB = nan(1,2*max(numel(A),numel(B)));
CD = nan(1,2*max(numel(C),numel(D)));
AB(2*(1:length(A))) = A;
AB(1+2*(1:length(B))) = B;
CD(2*(1:length(C))) = C;
CD(1+2*(1:length(D))) = D;
>>
AB = AB(~isnan(AB))
CD = CD(~isnan(CD))
The result would be:
AB =
1 2 3 4 5 6 7 8
CD =
1 2 3 4 5 6 7 8