2011-07-12 9 views
0

Je voudrais vectoriser ces deux lignes de code. J'ai récemment appris la vectorisation. Je sais comment vectoriser la ligne sumsurface mais je ne sais pas comment inclure la déclaration if, je voudrais vraiment vectoriser l'ensemble pour la boucle et m'en débarrasser. Je veux vectoriser pour améliorer l'exécution le code que j'ai en ce moment fonctionne très lentement. J'ai préalloué les tableaux, ce qui aide à améliorer l'exécution. J'avais oublié de le faire auparavant. Si je pouvais obtenir de l'aide, ce serait très apprécié.Comment vectoriser en Matlab?

pH = linspace(2,12, 6000); 
for j = 1:300 
    nAsp = randi([10, 30],[1,1]);%865 
    nGlu = randi([12, 38],[1,1]);%1074 
    nLys = randi([11, 33],[1,1]);%930 
    nArg = randi([10, 30],[1,1]);%879 
    nCys = randi([2, 8],[1,1]); %214 
    nTyr = randi([5, 17],[1,1]); %462 
    nHis = randi([4, 12],[1,1]); %360 

    for i = 1: len; 

     sumsurface(i) = (nAsp).*(-(10.^((pH(i)-asp))./(10.^((pH(i)-asp))+1)))+ (nGlu).*(-(10.^((pH(i)-glu))./(10.^((pH(i)-glu))+1)))+(nCys).*(-(10.^((pH(i)-cys))./(10.^((pH(i)-cys))+1)))+ (nTyr).* (-(10.^((pH(i)-tyr))./(10.^((pH(i)-tyr))+1)))+ (nHis).*(1./(10.^((pH(i)-his))+1))+ (nLys).*(1./(10.^((pH(i)-lys))+1))+ (nArg).*(1/(10.^((pH(i)-arg))+1)); 
     if sumsurface(i) < .01 && sumsurface(i) > -.01 
      %disp(sumsurface(i)); 
      disp(pH(i)); 
      x(1+end) = pH(i); 
      aspl(1+end) = nAsp; 
      glul(1+end) = nGlu; 
      cysl(1+end) = nCys; 
      tyrl(1+end) = nTyr; 
      hisl(1+end) = nHis; 
      lysl(1+end) = nLys; 
      argl(1+end) = nArg;     

     end 
    end  
end 

Répondre

1

Voici une vectorisation possible:

%# data 
len = 6000; 
pH = linspace(2,12, len); 

%# some constants (fill your values here) 
asp = 0; glu = 0; cys = 0; tyr = 0; his = 0; lys = 0; arg = 0; 

%# random parameters for each iteration 
num = 300; 
nAsp = randi([10 30], [num 1]); 
nGlu = randi([12 38], [num 1]); 
nLys = randi([11 33], [num 1]); 
nArg = randi([10 30], [num 1]); 
nCys = randi([2 8] , [num 1]); 
nTyr = randi([5 17] , [num 1]); 
nHis = randi([4 12] , [num 1]); 

params = [nAsp nGlu nCys nTyr nHis nLys nArg]; 
M = [ 
    - 10.^(pH-asp) ./ (1 + 10.^(pH-asp)) 
    - 10.^(pH-glu) ./ (1 + 10.^(pH-glu)) 
    - 10.^(pH-cys) ./ (1 + 10.^(pH-cys)) 
    - 10.^(pH-tyr) ./ (1 + 10.^(pH-tyr)) 
    1 ./ (1 + 10.^(pH-his)) 
    1 ./ (1 + 10.^(pH-lys)) 
    1 ./ (1 + 10.^(pH-arg)) 
]; 

%# iterations 
sumsurface = zeros(num,len); 
x = cell(num,1); p = cell(num,1); 
for j=1:num 
    sumsurface(j,:) = params(j,:)*M; 

    idx = abs(sumsurface(j,:)) < 0.01; 
    if any(idx) 
     x{j} = pH(idx); 
     p{j} = params(j,:); %# [aspl glul cysl tyrl hisl lysl argl] 
    end 
end 

Après l'exécution du code, les réseaux cellulaires x et p contiendra, pour chaque itération, la pH et params respectivement qui satisfont votre équation: -0.01<sumsurface<0.01 (s'ils existent).

3

Vous pouvez vectoriser l'ensemble de l'algorithme. Je ne vais pas coder tout pour vous, mais voici quelques conseils pour vous aider à démarrer:

  • Utilisez REPMAT pour créer un tableau qui contient autant de copies de pH comme il y a des itérations, à savoir len.
  • Modifier toutes les variables commençant par n des scalaires aux vecteurs. Par exemple, nAsp = randi([10, 30], [len, 1])
  • Utilisez FIND pour déterminer les indices de sumsurface correspondant à vos critères, c'est-à-dire index = find(sumsurface < 0.01 & sumsurface > -0.01);.
  • Créez vos vecteurs souhaités en utilisant index, par ex. aspl = nAsp(index);
  • Rincer. Répéter.
+0

J'ai mis à jour mon code, j'ai réalisé que j'avais omis une partie importante. J'ai un double pour la boucle mais les longueurs des vecteurs sont différentes. Je ne veux pas que le vecteur pH ait la même longueur que le vecteur nAsp = randi ([10, 30], [len, 1]). Sera-t-il encore possible de le vectoriser? merci pour les pointeurs –

Questions connexes