2015-05-08 2 views
1

Я борюсь с векторизации этого цикла парфоров. Я хочу полностью удалить цикл parfor из кода, поскольку он занимает много времени, чтобы выполнить, когда n велико. См. Код, вставленный ниже. Я буду признателен за любые советы/советы/помощь любому человеку на этом форуме, который может дать мне это. Спасибо заранее.Vectorize For-If-Elseif Loop

% Initialization and precomputations 
% w is an n x 1 vector 
% beta: any number larger than 0. Usually set to 1. 

f = zeros(n,1); 
x = w; 
y = w; 
rho = 1; 
v = f – (rho*y); 
rhow = rho*w; 
n = length(w); 

parfor i = 1 : n 

    if w(i) >= 0 
     if v(i) < -rhow(i) – beta – 1 
      x(i) = (-beta -1 -v(i))/rho; 

     elseif (-rhow(i) – beta – 1 <= v(i)) && (v(i) <= -rhow(i) + beta – 1) 
      x(i) = w(i); 

     elseif (-rhow(i) + beta – 1 < v(i)) && (v(i) < beta – 1) 
      x(i) = (beta – 1 -v(i))/rho; 

     elseif (beta – 1 <= v(i)) && (v(i) <= beta + 1) 
      x(i) = 0; 

     else 
      x(i) = (beta + 1 – v(i))/rho; 
     end 

    else 

     if v(i) < -beta -1 
      x(i) = (-beta -1 – v(i))/rho; 

     elseif (-beta – 1 <= v(i))&& (v(i) <= -beta + 1) 
      x(i) = 0; 

     elseif (-beta + 1 < v(i)) && (v(i) < -rhow(i) – beta + 1) 
      x(i) = (-beta + 1 – v(i))/rho; 

     elseif (-rhow(i) – beta + 1 <= v(i)) && (v(i) <= -rhow(i) + beta + 1) 
      x(i) = w(i); 

     else 
      x(i) = (beta + 1 – v(i))/rho; 
     end 

    end 
end 

ОБНОВЛЕНИЕ: Большое спасибо Hbderts за ваш ответ, это очень помогло мне. Это то, что я, наконец, придумал. Я все еще получаю что-то не так, потому что, когда я устанавливаю значения для переменных, я не получаю желаемого результата, как у меня с парфором. Можете ли вы помочь мне взглянуть на нее и сообщить мне, где я ошибался? Спасибо заранее.

cond1 = (w >= 0); 
cond2 = (w >= 0) & (v < -rhow-beta-1);  
x(cond2) = (-beta-1-v(cond2))/rho; 

cond3 = (w>=0)&(-rhow - beta -1 <= v) & (v <= -rhow + beta - 1); 
x(cond3) = w(cond3); 

cond4 = (w>=0) & (-rhow +beta - 1 < v) & (v < beta - 1); 
x(cond4) = (beta - 1 - v(cond4))/rho; 

cond5 = (w>=0) & (beta - 1 <= v) & (v <= beta + 1); 
x(cond5) = 0; 

cond6 = (~cond2); 
x(cond6) = (beta + 1 - v(cond6))/rho; 

cond7 = ((~cond1) & v < -beta -1); 
x(cond7) = (-beta -1 - v(cond7))/rho; 

cond8 = ((~cond1) & (-beta - 1 <= v) & (v <= -beta + 1)); 
x(cond8) = 0; 

cond9 = ((~cond1) & (-beta + 1 < v) & (v < -rhow - beta + 1)); 
x(cond9) = (-beta + 1 - v(cond9))/rho; 

cond10 = ((~cond1) & (-rhow - beta + 1 <= v) & (v <= -rhow + beta + 1)); 
x(cond10) = w(cond10); 

cond11 = (~cond1); 
x(cond11) = (beta + 1 - v(cond11))/rho; 
+5

ПОЖАЛУЙСТА, INDENT ВАМ КОД! Вы можете сделать это легко в Matlab CTRL + A; CTRL + I. Людям просто нужно начать программирование на питоне, чтобы узнать .... –

+2

@AnderBiguri Или начальная векторизация из набора, не нужно беспокоиться об отступлении;) – Divakar

+2

@Divakar Действительно. Но этот пример кода требует отступа. Это мой криптонит, я очень нервничаю с неподдельным кодом. –

ответ

4

Вы можете использовать логический вектор для индекса матрицы, как описано в MATLAB help страницах. Давайте сделаем простой пример:

A = [1 2 3 4]; 
ind = logical([0 1 0 1]); 
B = A(ind) 

B = 
    2 4 

Вы можете использовать эту систему, чтобы моделировать все разные случаи и отбрасывать цикл for. В первом случае, это было бы

x((w>=0)&(v<-rhow-beta-1)) = (-beta-1-v((w>=0)&(v<-rhow-beta-1)))/rho; 

Давайте посмотрим на термин x((w>=0)&(v<-rhow-beta-1)) подробно:

  • w>=0 создает логический вектор, содержащий 1 (истина), если соответствующая запись в w является >=0 и 0 (false) в противном случае.
  • v<-rhow-beta-1 также создает логический вектор, содержащий true или false.
  • & между этими терминами является логикой И. При этом мы имеем вектор, содержащий true для всех элементов, отвечающих обоим условиям, и false в противном случае.
  • С x(...) мы получаем все элементы от x, которые соответствуют обоим вышеперечисленным условиям.

Теперь у нас есть все элементы, которые мы хотим установить на первом этапе. Теперь нам нужно создать значения, к которым мы их установим. Часть (-beta-1-v(...))/rho такая же, как и раньше. С v(...), где ... - это те же условия, что и прежде, мы принимаем все соответствующие v, выполняем расчет с ними и сохраняем их в правильном положении x.

Мы можем повторить эту процедуру со всеми предложениями if-then-else, которые у вас есть. Для второго, это будет

x((w>=0) & (-rhow–beta–1<=v) & (v<=-rhow+beta–1)) = ... 
    w((w>=0) & (-rhow-beta-1<=v) & (v<=-rhow+beta-1)); 

И так далее ...