2014-02-16 1 views
0

Размеры этой проблемы: model.nlf = 4. Каждый {r} Куу или Куу Гамма - это 500 × 500 матриц данных.Избегание for-loops в матричных операциях с элементами ячеек

Как подавить цикл? моя интуиция идет на использование cellfun с функцией для logdet.

logDetKuu = 0; 
for r=1:model.nlf, 
    if isfield(model, 'gamma') && ~isempty(model.gamma) 
     [model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(model.KuuGamma{r}); 
     model.logDetKuu{r} = logdet(model.KuuGamma{r}, model.sqrtKuu{r}); 
    else 
     [model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(model.Kuu{r}); 
     model.logDetKuu{r} = logdet(model.Kuu{r}, model.sqrtKuu{r}); 
    end 
    logDetKuu = logDetKuu + model.logDetKuu{r}; 
end 

Благодарен за указатели. Спасибо

Следующий вопрос: Можно ли векторизовать следующие типы петель на элементах ячейки? nlf = 4; nout = 16; каждый KuuinvKuy {1,1} является 150x650

for k =1: model.nout, 
    for r =1: model.nlf, 
     model.KuuinvKuy{r,k} = model.Kuuinv{r}*model.Kyu{k,r}'; 
    end 
end 
+0

Чтобы ответить на ваш последующий вопрос: пожалуйста, перестаньте беспокоиться о векторизации! Как уже говорилось, ваш внутренний цикл состоит из вычислений на больших матрицах, которые Matlab уже делает как можно быстрее. Накладные расходы для небольшой петли совершенно ничтожны по сравнению с этим. Не тратьте время на оптимизацию кода, если профайлер говорит вам, что он работает медленно. –

+0

Спасибо, Bas. Дело принято. Этот цикл отмечен красным, а не только розовым, профилировщиком, и именно поэтому я пытаюсь изменить эффективность программирования этих массивов ячеек. – user2015897

+0

Вы должны видеть массивы ячеек, как крошечную матрицу указателей 4x16. Индексирование должно быть довольно быстрым. Что должно стоить время, так это вычисление матрицы 150x650. Но проверьте сами: разделите длинное выражение в своем for-loop на отдельные части: 'temp1 = model.Kuuinv {r}; temp2 = model.Kyu {k, r}; temp2 = temp2 '; temp3 = temp1 * temp2; model.KuuinvKuy {r, k} = temp3; ', каждый на отдельной строке и снова запустить профайлер. Если сюрпризов нет, большинство времени следует потратить на последнюю строку. В этом случае нет никакой надежды ускорить его, умножение матрицы должно быть супер-быстрым. –

ответ

1

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

if isfield(model, 'gamma') && ~isempty(model.gamma) 
    myKuu = model.KuuGamma; 
else 
    myKuu = model.Kuu; 
end 

logDetKuu = 0;  
for r=1:model.nlf, 
    [model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(myKuu{r}); 
    model.logDetKuu{r} = logdet(myKuu{r}, model.sqrtKuu{r}); 
    logDetKuu = logDetKuu + model.logDetKuu{r}; 
end 
+0

Сокращенное время выполнения до 1/3 от исходного времени исполнения. – user2015897

+0

Приятно слышать, но я немного удивлен. Если я правильно понимаю ваш код, время выполнения должно быть основано на математике на больших матрицах размером 500x500, все остальное (for-loop, индексирование массива ячеек) должно быть незначительным по сравнению с этим. –

 Смежные вопросы

  • Нет связанных вопросов^_^