Given any number. Lets say for example 5, I need to generate a matrix similar to this:
1 2 3 4 5
2 2 3 4 5
3 3 3 4 5
4 4 4 4 5
5 5 5 5 5
How to generate a matrix similar to this using Matlab?
I'd use bsxfun:
n = 5;
matrix = bsxfun(#max, 1:n, (1:n).');
An alternative (probably slower) is to use ndgrid:
n = 5;
[ii, jj] = ndgrid(1:n);
matrix = max(ii, jj);
Nothing will ever beat bsxfun as used by Luis Mendo., but for the sake of reminding people of the existence of Matlab's gallery function, here another approach:
n = 5;
A = gallery('minij',n)
B = n + 1 - A(end:-1:1,end:-1:1)
A =
1 1 1 1 1
1 2 2 2 2
1 2 3 3 3
1 2 3 4 4
1 2 3 4 5
B =
1 2 3 4 5
2 2 3 4 5
3 3 3 4 5
4 4 4 4 5
5 5 5 5 5
Related
The easiest way to explain the question is by an example:
>> A = [1 5; 1 5; 1 6; 1 6; 1 6; 1 6; 1 7; 2 5; 2 6; 2 6; 2 6; 2 7; 2 7; 2 8]
A =
1 5
1 5
1 6
1 6
1 6
1 6
1 7
2 5
2 6
2 6
2 6
2 7
2 7
2 8
What I want to have as output is something similar to
result =
1 6 4
1 5 2
2 6 3
2 7 2
Which means top two frequent pairs for each value in first column. So most frequent pairs came with 1 are 6 and 5 and most frequent pairs came with 2 are 6 and 7. 3rd column shows frequency of pairs.
I use matlab 2016 in linux.
You could use unique and histc to count the frequency of occurrence of each row. Then using frequency, you can proceed with your calculations.
[unique_rows,~,ind] = unique(A,'rows');
counts = histc(ind,unique(ind));
Now, you could combine the frequency count and sort them.
arr = [unique_rows,counts];
[sorted,~]=sortrows(arr,[1 -3])
sorted =
1 6 4
1 5 2
1 7 1
2 6 3
2 7 2
2 5 1
2 8 1
Given the matrix I = [1,2;3,4], I would like to duplicate the elements to create a matrix I2 such that:
I2 = [1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4]
Other than using repmat, what other methods or functions are available?
Use kron:
>> N = 3 %// Number of times to replicate a number in each dimension
>> I = [1,2;3,4];
>> kron(I, ones(N))
ans =
1 1 1 2 2 2
1 1 1 2 2 2
1 1 1 2 2 2
3 3 3 4 4 4
3 3 3 4 4 4
3 3 3 4 4 4
This probably deserves some explanation in case you're not aware of what kron does. kron stands for the Kronecker Tensor Product. kron between two matrices A of size m x n and B of size p x q creates an output matrix of size mp x nq such that:
Therefore, for each coefficient in A, we take this value, multiply it with every value in the matrix B and we position these matrices in the same order as we see in A. As such, if we let A = I, and B be the 3 x 3 matrix full of ones, you thus get the above result.
Using indexing:
I = [1, 2; 3, 4]; %// original matrix
n = 3; %// repetition factor
I2 = I(ceil(1/n:1/n:size(I,1)), ceil(1/n:1/n:size(I,2))); %// result
One-liner with bsxfun -
R = 3; %// Number of replications
I2 = reshape(bsxfun(#plus,permute(I,[3 1 4 2]),zeros(R,1,R)),R*size(I,1),[])
Sample run -
I =
3 2 5
9 8 9
I2 =
3 3 3 2 2 2 5 5 5
3 3 3 2 2 2 5 5 5
3 3 3 2 2 2 5 5 5
9 9 9 8 8 8 9 9 9
9 9 9 8 8 8 9 9 9
9 9 9 8 8 8 9 9 9
I have some matrix :
A = [ 1 2 3 4 5 6;
1 2 3 4 5 6]
B = [ 6 5 4 3 2 1;
6 5 4 3 2 1]
C = [ 1 2 3 4 5 6;
1 2 3 4 5 6]
what is code to make this following matrix:
Result = [1 2 9 9 10 11 5 5 5 6;
1 2 9 9 10 11 5 5 5 6]
Note : Actually the above matrix is sum of 3 matrix above which had been already rearranged like as the following matrix. #sum is sum which is based on column.
1 2 3 4 5 6
1 2 3 4 5 6
6 5 4 3 2 1
6 5 4 3 2 1
1 2 3 4 5 6
1 2 3 4 5 6
And. I sum first row by first row, and second row by second row.
To do what you say above:
Result = zeros(size(A) + [0,4]);
Result(:,1:size(A,2)) = A;
Result(:,3:end-2) = Result(:,3:end-2) + B;
Result(:,5:end) = Result(:, 5:end) + C;
The point is, you can select a subregion of a matrix, and assign another matrix to it. You just have to make sure both sides of the assignment are the same shape.
Very Simple Question that i couldn't find easily on the web so i thought i would ask here:
You can make a 1D linear array like this:
1:10 = 1 2 3 4 5 6 7 8 9 10
1:2:10 = 1 3 5 7 9
How can you easily initialise a 2D array ie.
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
and also the same thing but for columns:
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
Should be a command to do it in one line.
v = 1:5;
A = repmat(v, 4, 1);
B = repmat(v', 1, 4);
A and B will have what you need.
Another option is to use MATLAB indexing as follows:
v = 1:5;
A = v(ones(4, 1), :);
v = [1:5]';
B = v(:, ones(1, 4));
Alternatively i have learned that you can use meshgrid:
meshgrid(1:4, 1:4) =>
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
Thanks for the help and upvotes.
For a matrix A (4 rows, 1000 columns). I want to group the columns of the matrix A which have the same value for the third line. so I must have sub matrix with a third row that contains the same value.
for example:
if:
A =
1 4 5 2 2 2 2 1 1 5
1 4 5 4 4 2 2 4 5 2
3 3 3 3 4 1 3 5 3 4
4 5 5 5 4 1 5 5 5 5
then
A1 =
1 4 5 2 2 1
1 4 5 4 2 5
3 3 3 3 3 3
4 5 5 5 5 5
A2 =
2 5
4 2
4 4
4 5
A3 =
2
2
1
1
the result can be in the form of a cell.
here's one possible hack (warning: I haven't been able to check this):
A =
1 4 5 2 2 2 2 1 1 5
1 4 5 4 4 2 2 4 5 2
3 3 3 3 4 1 3 5 3 4
4 5 5 5 4 1 5 5 5 5
specialRow=3;
unqCols = unique(A(specialRow,:));
numUnq = length(unqCols);
sepMats{numUnq}=[];
for i=1:numUnq
sepMats{i} = A(:,A(specialRow,:)==unqCols(i));
end
In the example you shown, there are 4 unique elements in the 3rd row, so you should obtain 4 submatrices, but you only show 3 ?
Here is one way:
clear all;
%data
A = [1 4 5 2 2 2 2 1 1 5;
1 4 5 4 4 2 2 4 5 2;
3 3 3 3 4 1 3 5 3 4;
4 5 5 5 4 1 5 5 5 5
]
%engine
row = 3;
b = unique(A(row,:));
r = arrayfun(#(i) A(:,A(row,:)==b(i)),1:length(b), 'UniformOutput',false);
r{:}
You can make the assignment in a single line using ACCUMARRAY:
A = [1 4 5 2 2 2 2 1 1 5;
1 4 5 4 4 2 2 4 5 2;
3 3 3 3 4 1 3 5 3 4;
4 5 5 5 4 1 5 5 5 5
];
out = accumarray(A(3,:)', (1:size(A,2)), [], #(x){A(:,x)} );
With this, out{i} contains all columns of A where the third row of A equals i (and empty in case there is no valid column).
If you want out{i} to contain columns corresponding to the i-th smallest unique value in the third row of A, you can use GRP2IDX from the statistics toolbox first:
[idx,correspondingEntryInA] = grp2idx(A(3,:)'); %'#
out = accumarray(idx, (1:size(A,2)), [], #(x){A(:,x)} );
Here, out{i} contains the columns corresponding to correspondingEntryInA(i).