Matlab(the same cell in different matrix) - matlab

I have two matrix A and B. Suppose I would like to find in each row of matrix A the smallest number, and for the same cell that this number is in Matrix A, do find the corresponding number of the same cell in matrix B. For example the number in matrix A will be in the position A(1,3), A(2,9)...and I want the corresponding number in B(1,3), B(2,9)... Is it possible to do it, or I am asking something hard for matlab. Hope someone will help me.

What you can do is use min and find the minimum across all of the rows for each column. You would actually use the second output in order to find the location of each column per row that you want to find. Once you locate these, simply use sub2ind to access the corresponding values in B. As such, try something like this:
[~,ind] = min(A,[],2);
val = B(sub2ind(size(A), (1:size(A,1)).', ind));
val would contain the output values in the matrix B which correspond to the same positions as the minimum values of each row in A. This is also assuming that A and B are the same size. As an illustration, here's an example. Let's set A and B to be a random 4 x 4 array of integers each.
rng(123);
A = randi(10, 4, 4)
B = randi(10, 4, 4)
A =
7 8 5 5
3 5 4 1
3 10 4 4
6 7 8 8
B =
2 7 8 3
2 9 4 7
6 8 4 1
6 7 3 5
By running the first line of code, we get this:
[~,ind] = min(A,[],2)
ind =
3
4
1
1
This tells us that the minimum value of the first row is the third column, the minimum value of the next row is the 4th column, and so on and so forth. Once we have these column numbers, let's access what the corresponding values are in B, so we would want row and columns (1,3), (2,4), etc. Therefore, after running the second statement, we get:
val = B(sub2ind(size(A), (1:size(A,1)).', ind))
val =
8
7
6
6
If you quickly double check the accessed positions in B in comparison to A, we have found exactly those spots in B that correspond to A.

A = randi(9,[5 5]);
B = randi(9,[5 5]);
[C,I] = min(A');
B.*(A == repmat(C',1,size(A,2)))
example,
A =
2 1 6 9 1
2 4 4 4 2
5 6 5 5 5
9 3 9 3 6
4 5 6 8 3
B =
3 5 6 8 1
9 2 9 7 1
5 6 6 5 6
4 6 1 4 5
5 3 7 1 9
ans =
0 5 0 0 1
9 0 0 0 1
5 0 6 5 6
0 6 0 4 0
0 0 0 0 9
You can use it like,
B(A == repmat(C',1,5))
ans =
9
5
5
6
6
5
4
1
1
6
9

Related

How to take union of matrix rows that are represented by another vector?

I want to take the union of some of the rows of a matrix x. The row numbers of the rows whose union has to be taken are given by vector r. Is there any built-in function in MATLAB that can do it?
x = [1 2 4 0 0;
3 6 5 0 0;
7 8 10 12 9;
2 4 6 7 0;
3 4 5 8 12];
r = [1, 3, 5];
I think this will work for you - first, take the submatrix x(r,:) with the rows you want, and then find all the unique values in it:
unique(x(r,:))
ans =
0
1
2
3
4
5
7
8
9
10
12
You could do it like this
>>> union(union(x(r(1),:),x(r(2),:)),x(r(3),:))
ans =
0 1 2 3 4 5 7 8 9 10 12
or set up a for loop that iterates over the vector r to compute all the unions

MATLAB - Frequency of an array element with a condition

I need some help please. I have an array, as shown below, 6 rows and 5 columns, none of the elements in any one row repeats. The elements are all single digit numbers.
I want to find out, per row, when a number, let's say 1 appears, I want to keep of how often the other numbers of the row appear. For example, 1 shows up 3 times in rows one, three and five. When 1 shows up, 2 shows up one time, 3 shows up two times, 4 shows up two times, 5 shows up one time, 6 shows up two times, 7 shows up one time, 8 shows up three times, and 9 shows up zero times. I want to keep a vector of this information that will look like, V = [3,1,2,2,1,2,1,3,0], by starting with a vector like N = [1,2,3,4,5,6,7,8,9]
ARRAY =
1 5 8 2 6
2 3 4 6 7
3 1 8 7 4
6 5 7 9 4
1 4 3 8 6
5 7 8 9 6
The code I have below does not give the feedback I am looking for, can someone help please? Thanks
for i=1:length(ARRAY)
for j=1:length(N)
ARRAY(i,:)==j
V(j) = sum(j)
end
end
Using indices that is in A creae a zero and one 6 * 9 matrix that [i,j] th element of it is 1 if i th row of A contains j.
Then multiply the zero and one matrix with its transpose to get desirable result:
A =[...
1 5 8 2 6
2 3 4 6 7
3 1 8 7 4
6 5 7 9 4
1 4 3 8 6
5 7 8 9 6]
% create a matrix with the size of A that each row contains the row number
rowidx = repmat((1 : size(A,1)).' , 1 , size(A , 2))
% z_o a zero and one 6 * 9 matrix that [i,j] th element of it is 1 if i th row of A contains j
z_o = full(sparse(rowidx , A, 1))
% matrix multiplication with its transpose to create desirable result. each column relates to number N
out = z_o.' * z_o
Result: each column relates to N
3 1 2 2 1 2 1 3 0
1 2 1 1 1 2 1 1 0
2 1 3 3 0 2 2 2 0
2 1 3 4 1 3 3 2 1
1 1 0 1 3 3 2 2 2
2 2 2 3 3 5 3 3 2
1 1 2 3 2 3 4 2 2
3 1 2 2 2 3 2 4 1
0 0 0 1 2 2 2 1 2
I don't understand how you are approaching the problem with your sample code but here is something that should work. This uses find, any and accumarray and in each iteration for the loop it will return a V corresponding to the ith element in N
for i=1:length(N)
rowIdx = find(any(A == N(i),2)); % Find all the rows contain N(j)
A_red = A(rowIdx,:); % Get only those rows
V = [accumarray(A_red(:),1)]'; % Count occurrences of the 9 numbers
V(end+1:9) = 0; % If some numbers don't exist place zeros on their counts
end

How do I extract the odd and even rows of my matrix into two separate matrices in scilab?

I'm very new to scilab syntax and can't seem to find a way to extract the even and odd elements of a matrix into two separate matrix, suppose there's a matrix a:
a=[1,2,3,4,5,6,7,8,9]
How do I make two other matrix b and c which will be like
b=[2 4 6 8] and c=[1 3 5 7 9]
You can separate the matrix by calling row and column indices:
a=[1,2,3,4,5,6,7,8,9];
b=a(2:2:end);
c=a(1:2:end);
[2:2:end] means [2,4,6,...length(a)] and [1:2:end]=[1,3,5,...length(a)]. So you can use this tip for every matrix for example if you have a matrix a=[5,4,3,2,1] and you want to obtain the first three elements:
a=[5,4,3,2,1];
b=a(1:1:3)
b=
1 2 3
% OR YOU CAN USE
b=a(1:3)
If you need elements 3 to 5:
a=[5,4,3,2,1];
b=a(3:5)
b=
3 2 1
if you want to elements 5 to 1, i.e. in reverse:
a=[5,4,3,2,1];
b=a(5:-1:1);
b=
1 2 3 4 5
a=[1,2,3,4,5,6,7,8,9];
b = a(mod(a,2)==0);
c = a(mod(a,2)==1);
b =
2 4 6 8
c =
1 3 5 7 9
Use mod to check whether the number is divisible by 2 or not (i.e. is it even) and use that as a logical index into a.
The title is about selecting rows of a matrix, while the body of the question is about elements of a vector ...
With Scilab, for rows just do
a = [1,2,3 ; 4,5,6 ; 7,8,9];
odd = a(1:2:$, :);
even = a(2:2:$, :);
Example:
--> a = [
5 4 6
3 6 5
3 5 4
7 0 7
8 7 2 ];
--> a(1:2:$, :)
ans =
5 4 6
3 5 4
8 7 2
--> a(2:2:$, :)
ans =
3 6 5
7 0 7

Find the rows of a matrix with conditions concerning the values of certain columns in matlab

As the title says, I want to find all rows in a Matlab matrix that in certain columns the values in the row are equal with the values in the previous row, or in general, equal in some row in the matrix. For example I have a matrix
1 2 3 4
1 2 8 10
4 5 7 9
2 3 6 4
1 2 4 7
and I want to find the following rows:
1 2 3 4
1 2 3 10
1 2 4 7
How do I do something like that and how do I do it generally for all the possible pairs in columns 1 and 2, and have equal values in previous rows, that exist in the matrix?
Here's a start to see if we're headed in the right direction:
>> M = [1 2 3 4;
1 2 8 10;
4 5 7 9;
2 3 6 4;
1 2 4 7];
>> N = M; %// copy M into a new matrix so we can modify it
>> idx = ismember(N(:,1:2), N(1,1:2), 'rows')
idx =
1
1
0
0
1
>> N(idx, :)
ans =
1 2 3 4
1 2 8 10
1 2 4 7
Then you can remove those rows from the original matrix and repeat.
>> N = N(~idx,:)
N =
4 5 7 9
2 3 6 4
this will give you the results
data1 =[1 2 3 4
1 2 8 10
4 5 7 9
2 3 6 4
1 2 4 7];
data2 = [1 2 3 4
1 2 3 10
1 2 4 7];
[exists,position] = ismember(data1,data2, 'rows')
where the exists vector tells you wheter the row is on the other matrix and position gives you the position...
a less elegant and simpler version would be
array_data1 = reshape (data1',[],1);
array_data2 = reshape (data2',[],1);
matchmatrix = zeros(size(data2,1),size(data1,1));
for irow1 = 1: size(data2,1)
for irow2 = 1: size(data1,1)
matchmatrix(irow1,irow2) = min(data2(irow1,:) == data1(irow2,:))~= 0;
end
end
the matchmatrix is to read as a connectivity matrix where value of 1 indicates which row of data1 matches with which row of data2

how to split a matrix of size 88x88 in 4 parts in matlab

so far i have done
Declare a random Matrix M of size 88 x 88
Type of M should be uint8 (all values should be between 0 to 255).
Spilt the Matrix into 4 parts: p1, p2, p3, p4
Transpose all parts
Concatenate all these four parts into new matrix N
Approach #1
If you have the Image Processing Toolbox, you can use blockproc for a pretty straight-forward solution to this -
fun = #(block_struct) transpose(block_struct.data);
N = blockproc(M, [size(M,1)/2 size(M,2)/2], fun)
Approach #2
Let's suppose you have an input matrix of size m x n and you would like to partition it into dim1p parts along the rows and dim2p parts along the columns, so that each block is of size m/dim1p x n/dim2p and you would like transpose them and finally concatenate them back to form a 2D array. This could be thought of as a general case of what you had proposed in the question.
To solve such a case with performance in mind, you can use this -
[m,n] = size(M); %// Get size
dim1p = 2; %// number of parts to be partitioned along dimension-1 (rows)
dim2p = 2; %// number of parts to be partitioned along dimension-2 (columns)
%// Split and transpose, resulting in a 3D array
A = reshape(permute(reshape(M, m, n/dim2p, []), [2 1 3]), n/dim2p, m/dim1p, []);
%// Join the 3D slices back into a 2D array for the desired output
nrows = n*dim1p/dim2p;
N = reshape(permute(reshape(permute(A,[1 3 2]),nrows,dim2p,[]),[1 3 2]),nrows,[])
Sample run (assuming M as 9 x 8 sized and partitioning it into 3 and 4 parts along the rows and columns respectively so that each block is of size 3 x 2) -
M =
5 6 2 6 4 2 1 3
2 8 8 1 3 8 3 7
5 1 6 8 4 1 6 8
6 5 7 3 3 6 7 1
4 3 9 3 2 2 5 3
4 9 5 7 6 2 2 1
7 6 2 5 9 3 5 6
8 9 5 6 9 6 7 1
1 1 3 3 4 9 1 3
dim1p =
3
dim2p =
4
N =
5 2 5 2 8 6 4 3 4 1 3 6
6 8 1 6 1 8 2 8 1 3 7 8
6 4 4 7 9 5 3 2 6 7 5 2
5 3 9 3 3 7 6 2 2 1 3 1
7 8 1 2 5 3 9 9 4 5 7 1
6 9 1 5 6 3 3 6 9 6 1 3
You are not much clear in the question, Maybe this helps,
M = uint8(randi([0 255],[88 88]));
p1 = M(1:end/2 ,1:end/2 );
p2 = M(1:end/2 ,end/2+1:end);
p3 = M(end/2+1:end,1:end/2 );
p4 = M(end/2+1:end,end/2+1:end);
N = [p1' p2';p3' p4'];
Another approach would be to use mat2cell to split up the matrix into a 2 x 2 grid of cells, transpose each of the cell's contents using cellfun, then piece them all together using cell2mat. Therefore:
[rows, cols] = size(M);
C = mat2cell(M, [rows/2, rows/2], [cols/2, cols/2]);
D = cellfun(#transpose, C, 'uni', 0);
out = cell2mat(D);
Minor note: This only works when the rows and columns are both even.