Creating a matrix of ones and zeros with location of ones based on array value
    17 vues (au cours des 30 derniers jours)
  
       Afficher commentaires plus anciens
    
    Melissa Moore
 le 8 Avr 2019
  
    
    
    
    
    Modifié(e) : madhan ravi
      
      
 le 9 Avr 2019
            I need to acheive the following without a loop (for speed):
I have a vertical array where the value of each row tells me which column in a matrix of zeros should be replaced with a one.
For example, if I input:
y = [2; 3];
Then I want MATLAB to produce output:
Y = [0,1,0; 0, 0, 1];
I can acheive the desired output with the following for loop:
Y = zeros(2,3);
for j = 1:3
    Y(:,j) = (y==j);
end
In reality, my matrices are much larger and I want to avoid using for loops for speed. Is there anyway I can do this without a for loop?
1 commentaire
  madhan ravi
      
      
 le 9 Avr 2019
				
      Modifié(e) : madhan ravi
      
      
 le 9 Avr 2019
  
			@ Melissa Moore :Are you interested in a faster solution still? If yes another solution can be proposed.
Réponse acceptée
  Kevin Rawson
      
 le 8 Avr 2019
        One possible way is:
    Y = zeros(length(y), max(y));
    Y(sub2ind(size(Y), (1:length(y))', y)) = 1;
0 commentaires
Plus de réponses (2)
  A. Sawas
      
 le 8 Avr 2019
        
      Modifié(e) : A. Sawas
      
 le 8 Avr 2019
  
      The best solution I can think of is to use a for loop but will be faster than the one you showed because it will do one scalar assignment in each iteration compared to a vector assignment.
for j=1:2
    Y(j,y(j)) = 1;
end
1 commentaire
  Kevin Rawson
      
 le 8 Avr 2019
				
      Modifié(e) : Kevin Rawson
      
 le 8 Avr 2019
  
			A. Sawas, your method is faster for small arrays, but not for large arrays. I'm using your 10,000x10,000 example with y assigned to the diagonal (see code above). 
Sawas method (run 10000 times):
tic;
for i=1:10000
    for j=1:length(y)
        Y(j,y(j)) = 1;
    end
end; 
toc;
%Elapsed time is 1.682664 seconds.
Rawson method (run 10000 times):
tic; 
for i=1:10000
    Y(ind2sub(1:length(y), y)) = 1; 
end
toc;
%Elapsed time is 0.596671 seconds.
  Melissa Moore
 le 8 Avr 2019
        3 commentaires
  Kevin Phung
      
 le 8 Avr 2019
				Is Melissa's solution a valid solution?... IMO, I is a diagonal matrix where there are already existing 1's. And this is not what you want.
A. Sawas's is valid and more efficient.
  Kevin Rawson
      
 le 8 Avr 2019
				
      Modifié(e) : Kevin Rawson
      
 le 9 Avr 2019
  
			However, as A. Sawas pointed out, this is an extremely slow operation, ~700 times slower than A. Sawas' method, and ~1988 times slower than my method for a 10,000x10,000 array.
Voir également
Catégories
				En savoir plus sur Loops and Conditional Statements dans Help Center et File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




