Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
guys I need to convert this data of the array :X=[1 5, 2 4, 2 5] using Matlab to this matrix :
[1 0 0 0 0]
[0 1 0 0 0]
[0 0 0 0 0]
[0 1 0 0 0]
[1 1 0 0 0]
where [1 5] are on the same column ,same for the rest [2 4,2 5].The size of the matrix [n n] is the maximum number in the array X, in which 5;
any suggestions? Thank you in advance.
Find n
X = [1 5; 2 4; 2 5];
n = max( X(:) );
M = zeros( n ); % n-by-n matrix
M( sub2ind( [n n], X(:,2), X(:,1) ) ) = 1
M =
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 1 0 0 0
1 1 0 0 0
Edit It is best to represent incidence / adjacency matrix of a graph using sparse matrix:
M = accumarray( {[X(:,2); X(:,1)], [X(:,1);X(:,1)]}, 1, [ n n], #(x) 1, 0, true )
M =
(1,1) 1
(5,1) 1
(2,2) 1
(4,2) 1
(5,2) 1
And
full(M) =
1 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 1 0 0 0
1 1 0 0 0
Related
How do you translate matrix of A [(N) x (N)] to matrix B [(2N) x (2N)], such that:
if A(i,j)>=0, then:
B(i,j) = [ A(i,j) 0
0 A(i,j)]
if A(i,j)<0, then:
B(i,j) = [ 0 A(i,j)
A(i,j) 0 ]
?
For example1 by:
1 2
3 4
I'm want to get:
1 0 2 0
0 1 0 2
3 0 4 0
0 3 0 4
For example2 by:
1 -2
3 -4
I'm want to get:
1 0 0 2
0 1 2 0
3 0 0 4
0 3 4 0
Use the Kronecker tensor product:
B = kron(A.*(A>=0), [1 0; 0 1]) + kron(A.*(A<0), [0 1; 1 0]);
Or maybe
B = kron(A.*(A>=0), [1 0; 0 1]) - kron(A.*(A<0), [0 1; 1 0]);
if you want all positive values (your examples and your original formulation don't agree on this)
very simple using logical conditions:
B=[A.*(A>=0), A.*(A<0) ; A.*(A<0), A.*(A>=0)];
for example,
A=[1 2 ; -3 4];
B =
1 2 0 0
0 4 -3 0
0 0 1 2
-3 0 0 4
Postscipt:
This answer was written to answer the question above in its initial forms:
How do you translate matrix of A [(N) x (N)] to matrix B [(2N) x (2N)], such that:
if A(i,j)>=0, then:
B(i,j) = [ A(i,j) 0
0 A(i,j)]
if A(i,j)<0, then:
B(i,j) = [ 0 A(i,j)
A(i,j) 0 ]
?
later the OP wrote down some examples that made clear what he\she were after.
Can someone help me with the following problem in Matlab? I have a first vector containing the elements values. For example,
[2 8 4 9 3].
And a second one with the desired places in a second vector. For example,
[0 0 1 0 0 0 0 1 1 0 0 1 0 0 1].
Now I want to put the values from the first vector on the positions of the second one to end up with
[0 0 2 0 0 0 0 8 4 0 0 9 0 0 3].
What is the most efficient way of doing this when the size of the vector can be very large. (then thousands of elements)?
You can consider the y values as logical indicators, then use logical indexing to set those values to the values in x.
x = [2 8 4 9 3];
y = [0 0 1 0 0 0 0 1 1 0 0 1 0 0 1];
y(logical(y)) = x;
Alternatively, you could use
y(y==1) = x;
Use self-indexing:
% Your values:
V = [2 8 4 9 3];
% The desired locations of these values:
inds = [0 0 1 0 0 0 0 1 1 0 0 1 0 0 1];
% index the indices and assign
inds(inds>0) = V
I have a 6X4 matrix M1 containing only zeros.
I also have two 1D arrays Y1 and Y2 each with length 4.The two arrays contain the desired index values. Now, I want to set(convert to 1) the elements of matrix M1 such that
M1(Y1:Y2) is equal to 1
for ex: Y1=[1 2 2 1] and Y2=[3 4 5 3]
then, M1 should be
1 0 0 1
1 1 1 1
1 1 1 1
0 1 1 0
0 0 1 0
0 0 0 0
I can do this using for loop. But is there any optimised way to do it? (I intend to use much bigger matrices)
use cumsum!
>> szM = size(M1);
>> M1( sub2ind( szM, Y1, 1:szM(2) ) ) = 1
M1 =
1 0 0 1
0 1 1 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
>> M1( sub2ind( szM, Y2+1, 1:szM(2) ) ) = -1
M1 =
1 0 0 1
0 1 1 0
0 0 0 0
-1 0 0 -1
0 -1 0 0
0 0 -1 0
>> M = cumsum(M,1)
M =
1 0 0 1
1 1 1 1
1 1 1 1
0 1 1 0
0 0 1 0
0 0 0 0
A pitfall:
If any of Y2 equals 6 than setting Y2+1 to -1 will exceed matrix dimension.
To fix this you can add two lines before setting to -1 the elements of M:
>> cols = 1:szM(2);
>> sel = Y2 < szM(1);
>> M1( sub2ind( szM, Y2(sel)+1, cols(sel) ) ) = -1
A spin-off for Pavan Yalamanchili's answer using bsxfun: (hover to see:)
using bsxfun without offsets:
M1 = bsxfun( #ge, (1:size(M1,1))', Y1 ) & bsxfun( #le, (1:size(M1,1))', Y2 );
There may be other techniques, but this uses element wise operations which are insanely parallel.
A very simple solution. Thanks #Shai
>> [rows, cols] = size(M);
>> Y1=[1 2 2 1]; Y2=[3 4 5 3];
>> M = bsxfun(#ge, (1:rows)', Y1) & bsxfun(#le, (1:rows)', Y2)
M =
1 0 0 1
1 1 1 1
1 1 1 1
0 1 1 0
0 0 1 0
0 0 0 0
Unnecessarily complicated code
[rows, cols] = size(M);
offsets = ((1 : cols) - 1) * rows
Y1 = offsets + Y1;
Y2 = offsets + Y2;
M = reshape(1:numel(M), rows, cols);
M = bsxfun(#ge, M, Y1) & bsxfun(#le, M, Y2);
I have a matrix A
1 1 0 0
0 1 0 0
1 0 0 1
0 0 1 0
0 0 0 0
0 1 1 1
1 1 0 0
1 0 0 0
0 0 0 1
I want this matrix to be split according to user's input say d = [1 2 3].
for i=2:length(d)
d(i) = d(i) + d(i-1); % d = [1 3 6]
end
This gives d = [1 (1+2) (1+2+3)] = d[1 3 6]. There are 9 rows in this matrix, calculate ceil of [(1/6)*9], [(3/6)*9] and [(6/6)*9]. Hence this gives [2 5 9]. First split up is first two rows , 2nd split up is next (5-2=3) 3 rows and third split is (9-5=4) 4 rows.
The output should be like:
The split up is: 1st split up->
1 1 0 0 % first 2 rows in matrix A
0 1 0 0
2nd split up->
1 0 0 1 % next 3 rows
0 0 1 0
0 0 0 0
3rd split up->
0 1 1 1 % next 4 rows
1 1 0 0
1 0 0 0
0 0 0 1
You can use mat2cell with input d = [1 2 3] to store the final splits in separate cell arrays
B = mat2cell(A, d+1, size(A,2));
or, to adapt it to your computation of the split row sizes:
d = [1 2 3];
c = cumsum(d); % [1, 3, 6]
s = ceil(size(A,1)*c/c(end)); % [2, 5, 9]
n = [s(1) diff(s)]; % [2, 3, 4]
B = mat2cell(A, n, size(A,2));
To display the splits you can add a command similar to:
cellfun(#disp, B)
Given a matrix A, I need to find the indices corresponding to the values 1 and 2. I could do this sequentially as follows:
>> B
B =
1 2 3
4 1 6
7 8 9
4 5 1
>> find(B==1)
ans =
1
6
12
>> find(B==2)
ans =
5
But if I do this kind of operation in a loop, Matlab will only use one core of my processor. How can I vectorise it, so that I obtain a matrix from find? I want this result:
>> my_find( B, [1 2] )
ans =
1 5
6 0
12 0
(or some other padding)
How can I obtain this?
Just don't use find
B==1
ans =
1 0 0
0 1 0
0 0 0
0 0 1
B==2
ans =
0 1 0
0 0 0
0 0 0
0 0 0
And then add or logical OR those together.
i.e.
(B==1) + (B==2)
ans =
1 1 0
0 1 0
0 0 0
0 0 1
or
(B==1) | (B==2)
ans =
1 1 0
0 1 0
0 0 0
0 0 1
[i, j] = ind2sub(size(B), find(logical(sum(bsxfun(#eq, B(:), [1 2]), 2))))