Code optimization (3 line function)
    7 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
    Ronald van den Berg
 il 28 Gen 2015
  
    
    
    
    
    Commentato: Titus Edelhofer
    
 il 28 Gen 2015
            I need a function that efficiently applies a reflective bound to a signal: when the signal reaches the bound, it stays there until the signal increases again (example below).
I wrote a short function that applies such a bound to all signals in a matrix (code below).
My question is: does someone know a way to speed up this code? I'm applying it to matrices of size 5000x5000, which takes about a second per matrix. Since i have to do this on thousands of matrices, it would be nice to speed up the function. Thanks!
function Y = reflect(Y,b)
% apply reflecting bound to signals in matrix Y; columns are signals, rows time steps
mhist = zeros(1,size(Y,2));        % history of shifts applied in prev time steps
for ii=1:size(Y,1)                 % loop over time steps
    m = max(b-Y(ii,:)-mhist,0);       % compute required shift for current time step 
    Y(ii,:) = Y(ii,:) + mhist + m;    % apply shift
    mhist = mhist + m;                % add shift to history
end
Here is an example of its output (red=original, black=after applying reflective bound at Y=-50):

The plot was produced using the following code:
rng(1); 
X=0:.1:100; 
Y=cumsum(normrnd(0,5,size(X)))-X; 
plot(X,Y,'r'); 
hold on; 
plot(X,reflect(Y',-50),'k-'); 
plot([X(1) X(end)],[-50 -50],'b');
2 Commenti
  luc
 il 28 Gen 2015
				Pre-allocating matrices with nan vallues.
m, Y and mhist change within the loop, you know their final size so before entering the loop try to create them and fill them with nan vallues.
function:nan(3,3)=[nan nan nan;nan nan nan;nan nan nan]
Risposta accettata
  Sean de Wolski
      
      
 il 28 Gen 2015
        
      Modificato: Sean de Wolski
      
      
 il 28 Gen 2015
  
      If you have MATLAB Coder, this could be a potentially good candidate for C code generation and MEXing. It involves a loop with a persistent state that's updated on each iteration, something compiled languages are often faster with.
If you don't, post a zip file with the matrix and I'll benchmark it for you.
Più risposte (1)
  Titus Edelhofer
    
 il 28 Gen 2015
        Hi,
one thing that comes to my mind: can you swap rows and columns, i.e., transpose your input matrix?
function Y = reflect(Y,b)
% apply reflecting bound to signals in matrix Y; columns are signals, rows time steps
mhist = zeros(size(Y,1),1);        % history of shifts applied in prev time steps
for ii=1:size(Y,2)                 % loop over time steps
  m = max(b-Y(:,ii)-mhist,0);       % compute required shift for current time step 
  Y(:,ii) = Y(:,ii) + mhist + m;    % apply shift
  mhist = mhist + m;                % add shift to history
end
That should be faster, since MATLAB likes columns better than rows ...
Titus
2 Commenti
  Titus Edelhofer
    
 il 28 Gen 2015
				I'm curious to see the speed up you gain with the MEX/MATLAB Coder approach. And yes, matrices are stored columnwise in MATLAB (you see this e.g. with
A = magic(4);
A(:)
Therefore both from programming standpoint but also from memory access (cache!) working on columns is faster.
Titus
Vedere anche
Categorie
				Scopri di più su Loops and Conditional Statements in Help Center e File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!