How can I speedup this for loop and ismember?
    8 views (last 30 days)
  
       Show older comments
    
    Omar Ali Muhammed
 on 3 Mar 2021
  
    
    
    
    
    Commented: Omar Ali Muhammed
 on 5 Mar 2021
            Due to the large size of the arrays, the  following suffers from extremly slow execution. Is it possible to speedup this code. Vout need to be modified by Vin according to specific locations pointed to by indx1 and indx2. In order to retrieve back the values of Vin from Vout, modification need to be down sequentialy starting from 1 to L Where some of these indices are distributed randomly between indx1 and indx2. 
e=1; a=1; b=1; N=4;
L=262144;  K=786432;
Vin=rand(1,L);
Vout=rand(1,K); 
Q=randperm(K);
for r=Q,
  if ismember(e,indx1)
    Vout(r)=Vin(indx1(a));
    a=a+1;
    e=e+1;
  elseif ismember(e,indx2) 
    Vout(r)=Vin(indx2(b));
    b=b+1;
    e=e+N;
  else
    Vout(r)=1;
    e=e+N;
  end
  if e>L
    break;
  end
end
10 Comments
  Paul Hoffrichter
 on 5 Mar 2021
				But in your example, K/L = 3. As I already mentioned, if, for example, length( indx1 ) = length( indx1 ) = K/2 - 1, this satisifies your requirement that size(indx1)+size(indx2) Less than K. In this case, the length of indx1 is larger than L. If all the values in indx1 is in the range of 1 to L, then there must be duplicates. But you said that indx1 has unique distinct and sorted vectors of indices.
The model you are presenting to us does not appear to be consistent for these reasons.
Accepted Answer
  Jan
      
      
 on 4 Mar 2021
        
      Edited: Jan
      
      
 on 4 Mar 2021
  
      Without having working inputs, we cannot run the function. Then it is not possible to improve the code reliably. Except for one detail: "e" is a scalar. Then ismember is an overkill. Faster:
if any(e == indx1)    
If the elements of indx1 and indx2 are "small" integers, a lookup table can be faster:
LUT = zeros(1, L, 'uint8');
LUT(indx1) = 1;
LUT(indx2) = 2;   % do indx1 and indx2 share elements?! 
for r = Q
  switch LUT(e)
      case 0
          Vout(r) = 1;
          e       = e + N;
      case 1
          Vout(r) = Vin(indx1(a));
          a = a + 1;
          e = e + 1;
      case 2
          Vout(r) = Vin(indx2(b));
          b = b + 1;
          e = e + N;
  end
end
As said already, I cannot check if this is faster. Are indx1 and indx2 sorted? Are they unique integers?
I assume there is a vectorized approach also.
0 Comments
More Answers (0)
See Also
Categories
				Find more on Matrix Indexing in Help Center and File Exchange
			
	Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

