Is it possible to delete elements from matlab matrix? - matlab

I have a matlab matrix in the form
A = [1 2 3 4 5 6; 1 1 2 2 3 3; 1 2 3 3 2 1]
Is it possible to delete the 4th, 5th and 6th columns of the matrix A so that the result would be:
A = [1 2 3; 1 1 2; 1 2 3]

This would do it:
A(:,4:6)=[];

octave-3.4.0:1> A = [1 2 3 4 5 6; 1 1 2 2 3 3; 1 2 3 3 2 1]
A =
1 2 3 4 5 6
1 1 2 2 3 3
1 2 3 3 2 1
octave-3.4.0:2> A = A(:,1:3)
A =
1 2 3
1 1 2
1 2 3

Related

convert For syntax to a faster way in Matlab

I have below code and I want to convert it to a faster way but I don't how I can convert For syntax to a faster way in Matlab.
If user count is 5 and item count is 2 and time count is 4, I want to create this matrix:
1 1 1
1 1 2
1 1 3
1 1 4
1 2 1
1 2 2
1 2 3
1 2 4
2 1 1
2 1 2
2 1 3
2 1 4
...
result=zeros(userCount*itemCount*timeCount,4);
j=0;
for i=1:userCount
result(j*itemCount*timeCount+1:j*itemCount*timeCount+itemCount*timeCount,1)=ones(itemCount*timeCount,1)*i;
j=j+1;
end
j=0;
h=1;
for i=1:userCount*itemCount
result(j*timeCount+1:j*timeCount+timeCount,2)=ones(timeCount,1)*(h);
j=j+1;
h=h+1;
if h>itemCount
h=1;
end
end
j=0;
for i=1:userCount*itemCount
result(j*timeCount+1:j*timeCount+timeCount,3)=1:timeCount;
j=j+1;
end
for i=1:size(subs,1)
f=(result(:,1)==subs(i,1)& result(:,2)==subs(i,2));
result(f,:)=[];
end
What you are describing is to enumerate permutations for three independent linear sets. One way to achieve this would be to use ndgrid and unroll each output into a single vector:
userCount = 5; itemCount = 2; timeCount = 4;
[X,Y,Z] = ndgrid(1:timeCount,1:itemCount,1:userCount);
result = [Z(:) Y(:) X(:)];
We get:
result =
1 1 1
1 1 2
1 1 3
1 1 4
1 2 1
1 2 2
1 2 3
1 2 4
2 1 1
2 1 2
2 1 3
2 1 4
2 2 1
2 2 2
2 2 3
2 2 4
3 1 1
3 1 2
3 1 3
3 1 4
3 2 1
3 2 2
3 2 3
3 2 4
4 1 1
4 1 2
4 1 3
4 1 4
4 2 1
4 2 2
4 2 3
4 2 4
5 1 1
5 1 2
5 1 3
5 1 4
5 2 1
5 2 2
5 2 3
5 2 4

Find column vectors contained in B but not in A - MATLAB

I have matrix A of size 10x100 and matrix B with size 10x200.
How to find the column vectors contained in B but not in A? ( A and B do not have the same number of columns)
to elaborate #Cheery's comment with an example.
A=[1;4];
B=[1 2 4;4 5 6];
C=setdiff(B',A','rows')';
more details see http://www.mathworks.com/help/matlab/ref/setdiff.html
You can also use bsxfun here -
Bout = B(:,all(any(bsxfun(#ne,B,permute(A,[1 3 2])),1),3))
Sample run -
A =
2 2 2 2 2
2 2 1 1 1
1 1 2 1 3
B =
3 2 3 2 1 2 2
3 1 3 1 1 1 3
2 3 1 2 1 2 3
Bout =
3 3 1 2
3 3 1 3
2 1 1 3

MATLAB Matrix Transformation

I need to transform a matrix:
X = [1 2; 3 4]
X = 1 2
3 4
to
X = [1 2; 1 2; 1 2; 3 4; 3 4; 3 4]
X = 1 2
1 2
1 2
3 4
3 4
3 4
and do this operation for a matrix with any number of rows.
How can I achieve this in MATLAB?
Here is a nice and easy way to do this using kron
kron(X,[1 1 1]')
this produces
1 2
1 2
1 2
3 4
3 4
3 4

Sorting and randomising a matrix according to a particular constraint

I have a 32 x 3 matrix as follows:
A =
[ 1 1 1;
1 1 2;
1 1 3;
1 1 4;
1 1 5;
1 1 6;
1 1 7;
1 1 8;
1 2 1;
1 2 2;
1 2 3;
1 2 4;
1 2 5;
1 2 6;
1 2 7;
1 2 8;
2 1 1;
2 1 2;
2 1 3;
2 1 4;
2 1 5;
2 1 6;
2 1 7;
2 1 8;
2 2 1;
2 2 2;
2 2 3;
2 2 4;
2 2 5;
2 2 6;
2 2 7;
2 2 8]
What I need to do is randomise the order of the rows, while keeping the row values together, however, this needs to be constrained such that for A(:, 4), every 8 rows contain only the numbers 1 - 8. So for example, you could have something like:
A(1:8, :) =
[ 1 2 4;
1 1 5;
2 1 6;
1 1 8;
2 2 1;
2 1 2;
2 1 7;
1 1 3]
The occurrence of 1 and 2 in the first two columns needs to be random, 1 - 8 needs to be randomised for every 8 values of the third column. Initially I tried to use the function randswap within a loop with an added constraint, but this has only led to an infinite loop. Also important that the rows stay together as the 1s and 2s in the first two columns need to appear alongside the last column an equal number of times. Someone suggested the following, but it doesn't quite work out..
m = size(A,1);
n = 1:8;
out = 1;
i2 = 1;
while ~all(ismember(1:8,out)) && i2 < 100
i1 = randperm(m);
out = A(i1(n),:);
i2 = i2 + 1;
end
If all you need is to get one set of 8 rows out of A, you can construct the result like this:
out = [randi([1,2],[8,2]),randperm(8)']
out =
2 1 5
2 1 2
2 1 1
1 2 7
2 2 6
1 1 8
2 2 3
1 1 4
If you need to randomize all of A, you can do the following:
%# calculate index for the 1's and 2's
r = rand(8,4);
[~,idx12] = sort(r,2);
%# calculate index for the 1's through 8's
[~,idx8] = sort(r,1);
%# use idx8 to shuffle idx12
idx8into12 = bsxfun(#plus,idx8,[0 8 16 24]);
%# now we can construct the output matrix
B = [1 1;1 2;2 1;2 2];
out = [B(idx12(idx8into12),:),idx8(:)];
out =
1 1 7
1 2 3
1 2 1
2 1 8
2 1 5
2 2 4
2 2 2
2 1 6
1 1 3
1 2 7
1 1 1
1 2 8
1 2 4
1 1 5
2 2 6
2 1 2
1 1 8
2 1 7
1 2 5
2 1 1
1 2 6
2 1 3
1 1 2
1 1 4
2 1 4
2 2 7
2 2 8
2 2 3
1 2 2
1 1 6
2 2 5
2 2 1
If you do unique(out,'rows'), you'll see that there are indeed 32 unique rows. Every 8 rows in out have the numbers 1 through 8 in the third column.

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