Как векторизовать в Matlab? - PullRequest
0 голосов
/ 12 июля 2011

Я хотел бы векторизовать эти две строки кода. Я только недавно узнал о векторизации. Я знаю, как векторизовать строку sumsurface, но я не уверен, как включить оператор if, мне бы очень хотелось векторизовать весь цикл for и избавиться от него. Я хочу векторизовать, чтобы улучшить время выполнения кода, который у меня сейчас есть, работает очень медленно. Я предварительно выделил массивы, которые помогают улучшить время выполнения. Я забыл сделать это ранее. Если бы я мог получить какую-либо помощь, это было бы очень ценно.

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 

Ответы [ 2 ]

3 голосов
/ 12 июля 2011

Вы можете векторизовать весь алгоритм.Я не собираюсь кодировать все это для вас, но вот несколько указателей для начала:

  • Используйте REPMAT , чтобы создать массив, который содержит столько копий pH, поскольку есть итерации, т.е. len.
  • Измените все эти переменные, начиная с n, со скаляров на векторы.Например, nAsp = randi([10, 30], [len, 1])
  • Используйте НАЙТИ , чтобы определить индексы sumsurface, которые соответствуют вашим критериям, т.е. index = find(sumsurface < 0.01 & sumsurface > -0.01);.
  • Создайте нужные вам векторы, используя index, например aspl = nAsp(index);
  • Промыть.Повторите.
1 голос
/ 14 июля 2011

Вот одна из возможных векторизаций:

%# 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

После выполнения кода массивы ячеек x и p будут содержать для каждой итерации pH и params соответственно, которые удовлетворяют вашему уравнению: -0.01<sumsurface<0.01 (если они существуют).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...