Проблема в Matlab, предварительно распределяющей с комплексом для цикла - PullRequest
0 голосов
/ 22 июля 2010

Я довольно новичок в Matlab, но для своей работы мне нужно импортировать ОГРОМНЫЙ набор данных и организовать его определенным образом.Я написал код, который будет делать это, но очень неэффективно (это только мой третий основной кусок кода, и это занимает несколько часов).Matlab говорит мне, что я могу предварительно распределить свои переменные (на самом деле около пятидесяти раз), но у меня возникают проблемы с поиском, как это сделать, потому что я не уверен, к какой матрице будут добавляться данные для каждой итерации в цикле for.Сам код, вероятно, объясняет это лучше, чем я.
(Это всего лишь небольшая часть, но, надеюсь, покажет мою проблему)

for x= 1:length(firstinSeq)
            for y= 1:length(littledataPassed-1)
                if firstinSeq(x,1)== littledataPassed(y,1) && firstinSeq(x,2)== littledataPassed(y,2) 
                        switch firstinSeq(x,3)
                            case 0
                                for z= 0:1000
                                    w= y+z;  
                                    if firstinSeq(x,4)== littledataPassed(w,4) 
                                        if littledataPassed(w,6)== 1 && firstinSeq(x,2)== littledataPassed(w,2) && littledataPassed(w,5)== 0 
                                            msgLength0= [msgLength0; firstinSeq(x,:) littledataPassed(w,:)];
                                            break
                                        else continue
                                        end
                                    else msgLength0= [msgLength0; firstinSeq(x,:) [0 0 0 0 0 0]];  
                                        break
                                    end
                                end
                            case 1
                                for z= 0:1000
                                    w= y+z; 
                                    if firstinSeq(x,4)== littledataPassed(w,4) %if sequence not the same, terminate
                                        if littledataPassed(w,6)== 1 && firstinSeq(x,2)== littledataPassed(w,2) && littledataPassed(w,5)== 0
                                            msgLength1= [msgLength1; firstinSeq(x,:) littledataPassed(w,:)];
                                            break
                                        else continue
                                        end
                                    else msgLength1= [msgLength1; firstinSeq(x,:) [0 0 1 0 0 0]]; 
                                        break        
                                    end
                                end
                            case 2
                                for z= 0:1000
                                    w= y+z;
                                    if firstinSeq(x,4)== littledataPassed(w,4)
                                        if littledataPassed(w,6)== 1 && firstinSeq(x,2)== littledataPassed(w,2) && littledataPassed(w,5)== 0
                                            msgLength2= [msgLength2; firstinSeq(x,:) littledataPassed(w,:)];
                                            break
                                        else continue
                                        end
                                    else msgLength2= [msgLength2; firstinSeq(x,:) [0 0 2 0 0 0]];
                                        break
                                    end
                                end
                                for z= 0:1000
                                    w= y+z;
                                    if firstinSeq(x,4)== littledataPassed(w,4)
                                        if littledataPassed(w,6)== 1 && firstinSeq(x,2)== littledataPassed(w,2) && littledataPassed(w,5)== 1
                                            msgLength2= [msgLength2; firstinSeq(x,:) littledataPassed(w,:)];
                                            break
                                        else continue
                                        end
                                    else msgLength2= [msgLength2; firstinSeq(x,:) [0 0 2 0 1 0]];  
                                        break
                                    end
                                end

любые мысли о том, как я мог бы предварительно выделить эти переменные (msgLength0,1,2 и т.д.)?У них нет данных, добавленных для каждого значения в цикле, и я не уверен в конечном размере для каждого прогона.На данный момент у меня есть восемь вариантов переключения, что делает эту программу очень медленной.

Ответы [ 2 ]

1 голос
/ 23 июля 2010

Вы можете векторизовать обработку в каждом случае коммутатора, найдя индексы записей в блоке 1000 элементов, которые соответствуют вашим критериям, а затем добавив их к msgLength0 одним махом. Ниже приведена векторизованная версия кода case 0:

indexStop = find(firstinSeq(x,4) != littledataPassed(y:y+1000,4), 1, 'first');
if isempty(indexStop)
   indexStop = 1000;
end
indexProcess = find(littledataPassed(y:y+indexStop,6) == 1 & ...
   littledataPassed(y:y+indexStop,2) == firstinSeq(x,2) & ...
   littledataPassed(y:y+indexStop,5) == 0);
msgLength0 = [msgLength0; firstinSeq(x,:) littledataPassed(y+indexProcess-1,:); [0 0 0 0 0 0]];

Векторизация внешних циклов также может значительно сократить время выполнения. Я не знаю достаточно о ваших данных, чтобы предложить конкретный подход, но, возможно, использование функций reshape и / или repmat для создания массивов, над которыми вы можете работать векторно, может быть способом идти.

1 голос
/ 22 июля 2010

Если я правильно прочитал ваш код, то одна из переменных msgLengthN будет расширена для каждой поездки через самый внутренний цикл?Если это так, то возникает мысль о том, что вы можете предварительно выделить массив с именем msgLengthAll и заполнить его по мере необходимости, убедившись, что в каждой записи есть значение для различия между 0, 1, 2 и т. Д.

Если вы не знаете заранее, сколько места выделено для msgLengthAll, то вы можете либо:

  • Один раз отсканировать входной файл, чтобы определить его размер и другие массивы., нужно быть.Нет никакого позора при чтении больших файлов более одного раза для их обработки, и это может сэкономить вам много времени.ИЛИ
  • Проникайте в какую-то причудливую схему распределения, при которой сначала вы делаете предположение о том, сколько места потребуется msgLengthAll, затем, когда он заполняется, выделяете больше памяти.Существует множество способов решить, сколько еще выделить в каждой точке расширения: фиксированный размер или, возможно, столько, сколько уже выделено (т.е. удвоить распределение при каждом расширении).Это, конечно, потенциально довольно сложно.

Вы читаете файл построчно и обновляете переменные в памяти по мере продвижения?Или вы читаете весь файл, а затем сортируете вещи в памяти?Насколько большой ОГРОМНЫЙ?Сколько у вас оперативной памяти?

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