2013-03-28 7 views
2

Я написал код, который генерирует вектор возрастающей длины, который позже укладывается в строку матрицы после строки. Это пример того, как работает кодКак я могу векторизовать это для цикла в Matlab?

PPR=[0  2  3  5  6  8]; 
    AI=[ 0 0.7854 0.5236 0.3142 0.2618 0.1963]; 

    for ii=1:numel(PPR); 
     qp=0:PPR(ii); 
     xp(ii,1:PPR(ii)+1)=sin(AI(ii)*qp)+1  
    end 

Как я могу векторизовать этот цикл?

+0

Хотите, чтобы векторизовать его, так как он медленный? Если это так, вы должны, по крайней мере, сначала выполнить предварительное распределение, а затем сохранить столбец результатов, так как matlab является столбцом. – Justin

ответ

1

Здесь нет полностью Векторизованным способ построения матрицы - нет петель, нет arrayfun:

PPR=[0  2  3  5  6  8]; 
AI=[ 0 0.7854 0.5236 0.3142 0.2618 0.1963]; 


M = ones(length(PPR),PPR(end)+1); #% allocate proper sized matrix of ones 
r=1:length(PPR)-1; #% row indices for 1 element past the end of each row vector 
c=PPR(1:end-1)+2; #% corresponding column indices 
linear_index = sub2ind(size(M),r,c); #% create linear index from r,c 
M(linear_index)=nan; #% set those elements to NaN 
M2 = cumsum(M,2)-1; #% use cumsum to propagate the NaN values 
M3 = bsxfun(@times,M2,AI'); #%'#multiply each row by the appropriate AI value 
xp = sin(M3)+1 #% take the sine of the matrix 

Я использовал кучу временных переменные для ясности. Если вы хотите избежать захламления своего рабочего пространства, вы можете избежать их, поскольку они часто не используются более одного раза.

Также обратите внимание: это заполняет матрицу с помощью NaN, где вы не указали никакого другого значения. Если вы хотите заменить их другими стандартными (например, нулями или одними), что очень просто сделать в конце.

+0

+1 для интересного решения. Специально Нанское распространение является прохладным. Тем не менее, я тестировал все 3 кодекса с tic/toc (2012b, win7), а один OP с контуром лучше (мой хуже, как и ожидалось). JIT-компилятор на работе. – yuk

0

Здесь есть векторизованный код. Мне все еще приходилось использовать ARRAYFUN. Так что тест с tic/toc, если он быстрее, чем ваш цикл.

n = numel(PPR); % number of rows 
m = max(PPR)+1; % number of columns 
qp = arrayfun(@(x)[0:PPR(x) nan(1,m-PPR(x)-1)],1:n,'UniformOutput',0); 
qp = vertcat(qp{:}); 
a = ~isnan(qp); % to add ones later 
qp(~a) = 0; 
xp = sin(bsxfun(@times,AI',qp)) + a; 
Смежные вопросы