concatenate each Row with another row in matlab? - matlab

I've a matrix 4X4 trying to concatenate rows like this :
1 with 2
1 with 3
1 with 4
2 with 3
2 with 4
3 with 4
at the end I have 6 even rows separately
Dear ((thefourtheye )) ,this Below is output of final code I will repeat one row if you can review
newline =
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
newline =
1 1 1 1
2 2 2 2
4 4 4 4
5 5 5 5
newline =
1 1 1 1
2 2 2 2
5 5 5 5
6 6 6 6
newline =
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
newline =
2 2 2 2
3 3 3 3
5 5 5 5
6 6 6 6
newline =
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6

more or less manually...
new = [old(1,:) old(2,:); old(1,:) old(3,:); old(1,:) old(4,:); old(2,:) old(3,:); old(2,:) old(4,:); old(3,:) old(4,:)]
but you should write a function if you need to repeat in other scenarios

% Your original array is yourmat, it is square
newmat = [];
for n=1:length(yourmat)
for m=n+1:length(yourmat)
newline = yourmat(n, :) + yourmat(m, :); % Is this what you meant by concatenate?
newmat = [newmat; newline];
end
end

You should be able to easily do this with nested for loops and then store them however you want, but I chose to just store them into a cell array
someMatrix = rand(4)
storage = {}
iter = 1
newMatrix = zeros(2,length(someMatrix));
for ii = 1:length(someMatrix)
for jj = i+1:length(someMatrix)
newMatrix(1,:) = someMatrix(ii,:);
newMatrix(2,:) = someMatrix(jj,:);
storage{iter} = newMatrix
iter = iter + 1;
end
end

Related

Matlab: How to enumerate the possible ways of forming pairs from a list

Suppose I have a list of length 2k, say {1,2,...,2k}. The number of possible ways of grouping the 2k numbers into k (unordered) pairs is n(k) = 1*3* ... *(2k-1). So for k=2, we have the following three different ways of forming 2 pairs
(1 2)(3 4)
(1 3)(2 4)
(1 4)(2 3)
How can I use Matlab to create the above list, i.e., create a matrix of n(k)*(2k) such that each row contains a different way of grouping the list of 2k numbers into k pairs.
clear
k = 3;
set = 1: 2*k;
p = perms(set); % get all possible permutations
% sort each two column
[~, col] = size(p);
for i = 1: 2: col
p(:, i:i+1) = sort(p(:,i:i+1), 2);
end
p = unique(p, 'rows'); % remove the same row
% sort each row
[row, col] = size(p);
for i = 1: row
temp = reshape(p(i,:), 2, col/2)';
temp = sortrows(temp, 1);
p(i,:) = reshape(temp', 1, col);
end
pairs = unique(p, 'rows'); % remove the same row
pairs =
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
1 3 2 6 4 5
1 4 2 3 5 6
1 4 2 5 3 6
1 4 2 6 3 5
1 5 2 3 4 6
1 5 2 4 3 6
1 5 2 6 3 4
1 6 2 3 4 5
1 6 2 4 3 5
1 6 2 5 3 4
As someone think my former answer is not useful, i post this.
I have the following brute force way of enumerating the pairs. Not particularly efficient. It can also cause memory problem when k>9. In that case, I can just enumerate but not create Z and store the result in it.
function Z = pair2(k)
count = [2*k-1:-2:3];
tcount = prod(count);
Z = zeros(tcount,2*k);
x = [ones(1,k-2) 0];
z = zeros(1,2*k);
for i=1:tcount
for j=k-1:-1:1
if x(j)<count(j)
x(j) = x(j)+1;
break
end
x(j) = 1;
end
y = [1:2*k];
for j=1:k-1
z(2*j-1) = y(1);
z(2*j) = y(x(j)+1);
y([1 x(j)+1]) = [];
end
z(2*k-1:2*k) = y;
Z(i,:) = z;
end
k = 3;
set = 1: 2*k;
combos = combntns(set, k);
[len, ~] = size(combos);
pairs = [combos(1:len/2,:) flip(combos(len/2+1:end,:))];
pairs =
1 2 3 4 5 6
1 2 4 3 5 6
1 2 5 3 4 6
1 2 6 3 4 5
1 3 4 2 5 6
1 3 5 2 4 6
1 3 6 2 4 5
1 4 5 2 3 6
1 4 6 2 3 5
1 5 6 2 3 4
You can also use nchoosek instead of combntns. See more at combntns or nchoosek

Given a number, Generate a series of 'L' shaped matrix with MATLAB

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

Unique combinations of a beaded necklace [duplicate]

This question already has answers here:
Generate all possible combinations of the elements of some vectors (Cartesian product)
(4 answers)
Closed 8 years ago.
So I'm writing a program to determine the unique combinations of a beaded necklace, but I can't seem to get it right. The rules are you can't have the same necklace forwards and backwards, and you can't have the same necklace with one bead being slid around to the other end. I've attached some pictures to clarify.
I wrote the code for it, and I thought I had achieved what I was trying to do, but it's not working correctly.
n = [1 2 3 4 2 4];
% green = 1
% blue = 2
% yellow = 3
% red = 4
p = perms(n);
total = max(size(p));
for i = 1:max(size(p))
q = p;
q(i) = [];
for j = 1:max(size(q))
if isequal(p(i),fliplr(q(j)))
total = total - 1;
elseif isequal(p(i),circshift(q(j),[1,1]))
total = total - 1;
elseif isequal(p(i),circshift(q(j),[length(q(j))-1,length(q(j))-1]))
total = total - 1;
end
disp(total)
end
end
Logically, this makes sense to me, but I could just be crazy.
If the problem size is small, you can vectorize all the comparisons (using bsxfun):
n = [1 2 3 4 2 4];
%// green = 1
%// blue = 2
%// yellow = 3
%// red = 4
N = numel(n);
p = perms(n).'; %'// generate all permutations
p2 = NaN([size(p) N+1]); %// this will store permutations with flips and shifts
p2(:,:,1) = p; %// original
p2(:,:,2) = flipud(p); %// flips
for k = 1:N-1
p2(:,:,2+k) = circshift(p,k); %// circular shifts
end
eqElem = bsxfun(#eq, p, permute(p2, [1 4 2 3]));
eqMat = squeeze(any(all(eqElem, 1), 4)); %// 1 if equal
remove = any(tril(eqMat, -1), 1); %// remove permutations that are "similar"
%// to a previous one, where "similar" means "equal up to circular shifts or
%// flips"
result = p(:,~remove).'; %'// all valid arrangements; one per row
resultNum = size(result, 1); %// number of arrangements
Results:
result =
1 3 2 2 4 4
1 3 2 4 4 2
1 3 2 4 2 4
1 3 4 2 2 4
1 3 4 2 4 2
1 3 4 4 2 2
1 2 3 2 4 4
1 2 3 4 2 4
1 2 3 4 4 2
1 2 2 3 4 4
1 2 2 4 4 3
1 2 2 4 3 4
1 2 4 3 2 4
1 2 4 3 4 2
1 2 4 2 3 4
1 2 4 2 4 3
1 2 4 4 2 3
1 2 4 4 3 2
1 4 4 3 2 2
1 4 4 2 2 3
1 4 4 2 3 2
1 4 3 4 2 2
1 4 3 2 2 4
1 4 3 2 4 2
1 4 2 3 2 4
1 4 2 3 4 2
1 4 2 2 3 4
1 4 2 2 4 3
1 4 2 4 2 3
1 4 2 4 3 2
resultNum =
30
You should do p = unique(p,'rows') before any loops. To see why, call perms([1 1 1]) at the command line.
There are a few issues here:
1) p, the perms, is a 2D matrix, so to get each perm you need to do p(i,:) to get the row. p(i) is just a single number.
2) You don't remove wrong answers from your list, so you will check against them twice. For example, say the first in the list is [1 2 3 4 2 4]; and the second is [4 2 4 3 2 1];. The fliplr check will compare these two combinations twice, once in the first loop around, once in the second.
3) If you want to make sure that any permutation which is a rotation is excluded (not just moving one bead around), you'll need some more circshift.
Consider using ismember with rows option again to compare a single row (e.g. a flipped version of the row you're checking) to an entire matrix.

How to sum matrix which had been already rearranged

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.

I want to group the columns of the matrix A which have the same value for the third line in Matlab

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).