I'm trying to reshape an array, perform an operation and then reshape it back to the original. See example of the output I'm trying to get. I can get a and b but I'm having trouble getting c to look like a again.
Step 1) (the original array)
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
Step 2) (reshape and perform some operation)
1,1,1,2,2,2,3,3,3,4,4,4,5,5,5
Step 3) (array is reshaped back to the original size to look like step 1) this is what I want
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
I can get the variables a and b but I'm not sure how to reshape c from b to look like a again see example code and output below
a=[repmat(1,[1,3]);repmat(2,[1,3]);repmat(3,[1,3]);repmat(4,[1,3]);repmat(5,[1,3])]
[rw,col]=size(a)
b=reshape(a',1,rw*col)
c=reshape(b,rw,col)
a=
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
b=1,1,1,2,2,2,3,3,3,4,4,4,5,5,5
c =
1 2 4
1 3 4
1 3 5
2 3 5
2 4 5
Ps: I'm using Octave 4.0 which is like Matlab.
MATLAB and Octave use column-major ordering so you'll need to reshape the result with that in mind. The data will be filled down the columns first but you want it to fill the columns first. To achieve this, you can specify the number of columns as the number of rows provided to reshape and then transpose the result
c = reshape(b, 3, []).'
Or more flexibly
c = reshape(b, flip(size(a))).'
Related
I can "Vectorize" the circshift command but I'm having trouble adding dimensions to it.
See code below with working FOR loop that I'm trying to vectorize using dimensions
clear all,clf reset,tic,clc , close all
function [outMat] = vectcircshift(vectToShift,shiftVector)
%This function generates a matrix where each row is a circshift of the
%original vector from the specified interval in the shiftVector;
%
%Inputs
%vectToShift: is the original vector you want to circshift multiple times
%shiftVector: is the vector of the circshift sizes;
%
%Outputs
%outMat: is a matrix were every row is circshift by the amount in the
% shiftVector
[n,m]=size(vectToShift);
if n>m
inds=(1:n)';
i=toeplitz(flipud(inds),circshift(inds,[1 0]));
outMat=vectToShift(i(shiftVector,:));
outMat=circshift(outMat,[0,-1]); %shift to include original signal first
else
inds=1:m;
i=toeplitz(fliplr(inds),circshift(inds,[0 1]));
outMat=vectToShift(i(shiftVector,:));
outMat=circshift(outMat,[0,-1]); %shift to include original signal first
end
end
%%----Working FOR LOOP below I'm trying to vectorize.
ndim=0;
ndim_tot=[1:3] %total dimensions
for ndim=1:length(ndim_tot)
ndim=ndim+0
if ndim==1
array_sort(ndim,:)=circshift(ndim_tot,[0 ndim-1]) %start at row of sort array
else
array_sort(ndim,:)=circshift(ndim_tot,[0 mod(-ndim,length(ndim_tot))+1]) %next start of row of sort array
endif
array_sort= array_sort(ndim,:)
array_dim(:,:,ndim)=vectcircshift([1:5],array_sort)
endfor
I tired the syntax below but that logic won't work.
ndim_tot=[1:3]; %number of dimensions
array_dim2(:,:,ndim_tot)=vectcircshift([1:5],[1:3])
I get an error nonconformant arguments(op1 is 0x0x1, op2 is 3x5)
My goal is to create a multidimensional array that circshifts a signal / array and also creates and shifts it in multiple dimensions.
Example: of what the multidimensional array would look like
if I start with a signal / array a1=[1 2 3 4 5]
I'm trying to have it create.
array_dim(:,:,1)=
[
1 2 3 4 5
5 1 2 3 4
4 5 1 2 3
]
array_dim(:,:,2)=
[
5 1 2 3 4
4 5 1 2 3
1 2 3 4 5
]
array_dim(:,:,3)=
[
4 5 1 2 3
1 2 3 4 5
5 1 2 3 4
]
Please note: the the numbers won't be sequential I just used it as an example to help explain things a little easier.
PS: I'm using Octave 4.2.2
Not clear why you are shifting in mod 3, but here is a loop assignment using shift
a1=[1 2 3 4 5];
array_dim=zeros(3,5,3);
for i=0:2
array_dim(:,:,i+1)=[shift(a1,i);
shift(a1,mod(i+1,3));
shift(a1,mod(i+2,3))];
endfor
array_dim
and the output fits your example
array_dim =
ans(:,:,1) =
1 2 3 4 5
5 1 2 3 4
4 5 1 2 3
ans(:,:,2) =
5 1 2 3 4
4 5 1 2 3
1 2 3 4 5
ans(:,:,3) =
4 5 1 2 3
1 2 3 4 5
5 1 2 3 4
For example, I have a matrix A (Figure 1). When the variable n = 2, I want it to be transformed to the matrix B. The red rectangle shows the transformation rule of every column. According to this rule, when the n = 3, it can become the matrix C.
I have written a script using a for loop method, but it is a waste of time when the matrix A is very large (e.g. 11688* 140000). Is there an efficient way to solve this problem?
Figure 1:
Here is a way using reshape and implicit expansion:
result = reshape(A((1:size(A,1)-n+1) + (0:n-1).', :), n, []);
For example assume that n = 3. Implicit expansion is used to extract indices of rows:
row_ind = (1:size(A,1)-n+1) + (0:n-1).';
The following matrix is created:
1 2
2 3
3 4
Extract the desired rows of A:
A_expanded = A(row_ind, :)
When the matrix row_ind is used as an index it behaves like a vector:
1
2
1 2 3
2 3 -> 2
3 4 3
4
A_expanded =
3 5 7
6 8 9
2 6 3
6 8 9
2 6 3
1 2 1
Now A_expanded can be reshaped to the desired size:
result = reshape(A_expanded, n, []);
>>result =
3 6 5 8 7 9
6 2 8 6 9 3
2 1 6 2 3 1
If you have the Image Processing Toolbox you can use im2col as follows:
result = im2col(A, [n 1], 'sliding');
I have a 2D matrix and want to sort rows and columns based on two other vectors i.e. one for ordering rows another for ordering columns in MATLAB
Example: A (Matrix to order)
0 1 2 3 4
1 1 8 9 7
2 3 4 6 2
3 1 2 0 8
Row Vector (Order for sorting rows of matrix A)
1
4
2
3
And column vector
1 5 4 2 3
Modified A
0 4 3 1 2
3 8 0 1 2
1 7 9 1 8
2 2 6 3 4
How about:
ModifiedA=A(RowVector,ColumnVector);
Note: Matab's indexing starts at 1 not at 0, adapt your indexing vectors accordingly.
In MATLAB, you can use the second output of sort to get the 1-based indexes that MATLAB is looking for (in this case you could have just added 1, but using sort works even if the row and column vectors are not consecutive).
[~,rowIdx] = sort(rowVector);
[~,colIdx] = sort(colVector);
And then you can apply the indexing operation to the matrix:
modifiedA = A(rowIdx, colIdx);
This question already has answers here:
Element-wise array replication in Matlab
(7 answers)
A similar function to R's rep in Matlab [duplicate]
(4 answers)
Closed 8 years ago.
Let's say, I have:
A=[1 2; 3 4];
I want to use repmat that return:
B = [1 1 2 2; 1 1 2 2; 3 3 4 4; 3 3 4 4]
Kindly need your help. Thank you
I do not know a method using repmat but here is a method using kron
kron([1 2 ; 3 4],[1 1;1 1])
ans =
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
An alternative which uses repmat is
A=[1 2; 3 4];
cell2mat(arrayfun(#(x)repmat(x,2,2),A,'UniformOutput',false))
ans =
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
arrayfun is used to evaluate each element in A using the anonymous function #(x)repmat(x,2,2) which replicates that single element into a 2x2 matrix.
The result of arrayfun is a 2x2 cell array where each element is a 2x2 matrix. We then convert this cell array into a matrix via cell2mat.
Let the data be defined as
A = [1 2; 3 4];
R = 2; %// number of repetitions of each row
C = 2; %// number of repetitions of each column. May be different from R
Two possible approaches are as follows:
The simplest method is to use indexing:
B = A(ceil(1/R:1/R:size(A,1)), ceil(1/C:1/C:size(A,2)));
If you really want to do it with repmat, you need to play with dimensions using permute and reshape: move original dimensions 1, 2 to dimensions 2, 4 (permute); do the repetition along new dimensions 1, 3 (repmat); collapse dimensions 1, 2 into one dimension and 3, 4 into another dimension (reshape):
[r c] = size(A);
B = reshape(repmat(permute(A, [3 1 4 2]), [R 1 C 1]), [r*R c*C]);
Example result for R=2, C=3 (obtained with any of the two approaches):
B =
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
I have got a question regarding all the combinations of matrix-rows in Matlab.
I currently have a matrix with the following structure:
1 2
1 3
1 4
2 3
2 4
3 4
Now I want to get all the possible combinations of these "pairs" without using a number twice in the same row:
1 2 3 4
1 3 2 4
1 4 2 3
And it must be possible to make it with n-"doublecolumns". Which means, when my pair-matrix goes for example until "5 6", i want to create the matrix with 3 of these doublecolumns:
1 2 3 4 5 6
1 2 3 5 4 6
1 2 3 6 4 5
1 3 2 4 5 6
1 3 2 5 4 6
....
I hope you understand what I mean :)
Any ideas how to solve this?
Thanks and best regard
Jonas
M = [1 2
1 3
1 4
2 3
2 4
3 4]; %// example data
n = floor(max(M(:))/2); %// size of tuples. Compute this way, or set manually
p = nchoosek(1:size(M,1), n).'; %'// generate all n-tuples of row indices
R = reshape(M(p,:).', n*size(M,2), []).'; %// generate result...
R = R(all(diff(sort(R.'))),:); %'//...removing combinations with repeated values