2014-10-03 133 views
1

我將數據組織爲2個矩陣'時間'和'數據'。我想查找「數據」矩陣第一列的峯 - 峯值。我試圖通過遍歷數據點,一次500個點,並找到每個區間內的最大值和最小值。通過將兩個值的絕對值相加來找到峯值。查找時間間隔內的峯間值MATLAB

峯= ABS(MAXV)+ ABS(MINV)

這些值然後保存到Excel電子表格(如果它們比1500大)在那裏他們可以在事後來看。但是,數據矩陣大約有1798824行,這個過程非常繁瑣。

有沒有更好的方法來編寫這段代碼來加速這個過程?循環看起來好嗎?如果'if'條件沒有被滿足,我試圖找到一種直接進行下一次迭代的方法,但是我不確定如何在MATLAB中做到這一點。

%maxV=maximum thrust value 
%minV=minimum thrust value 
%maxI=index of maximum thrust 
%minI=index of minimum thrust 
%peakV=peak thrust value 
%peakT=time at which peak thrust value occurred 

d=dir('*');%Creates matrix d which contains all the file names in the folder. 
d=d(~[d.isdir]);% removes folders from the list (if some exist) 
d={d.name}.';%removes the locations of the files, leaving only the names. 
nf=numel(d);%calculates the variables in d 
j=zeros([1,15]); %creates starting matrix to which the peak result, indexes and values can be added to 

for i=3:nf 


[time,data,sensors]=IMO_read_time(d{i},1); %executes function that reads binary and gives data in 3 matrices(time,data,sensors) 

nrows=size(data,1); %number of data rows in matrix A 
peakvalues=round((nrows/500)); %number of peak results for sampling frequency of 500Hz 

for p=1:peakvalues %range of possible peak results 
    for n=1:500:nrows %number of data points to be read(interval of 500) 
     k=n+499;  %stating end value to be read in each interval 
     if k<=nrows %end value must be smaller than number of rows in data 

     [maxV maxI]=max(data(n:k,1)); %finds maxV and maxI within 500 data points 
     [minV minI]=min(data(n:k,1)); %finds maxV and maxI within 500 data points 

     maxT=time(maxI,1); %finds time of maximum value 
     minT=time(minI,1); %finds time of minimum value 

     peakV=abs(maxV)+abs(minV); %finds peak to peak between maxV and minV 

     if peakV>1500 


    Real_maxT=datevec(datenum(1970,1,1)+(maxT/86400)); %converts UNIX time into UPS format 
    Real_minT=datevec(datenum(1970,1,1)+(minT/86400)); %converts UNIX time into UPS format 


    M=[peakV maxI minI Real_maxT Real_minT]; %creates matrix M with values of interest 
    format long 

    Newj=[j; M]; %adds M onto matrix j to create matrix Newj 
    j=Newj; %j then becomes Newj for next iteration 

    ind=find(j(:,1),1,'last'); %gives the index of the last value of matrix j 
    p=sprintf('A%d',ind); %gives the row number that the data will be written to in excel  spreadsheet 
    xlswrite('20131221_PeakValues_trial1', M, 1, p); %saves matrix M in excel spreadsheet, sheet1, row n 

     end; 

     end; 

    end 
end 

+0

如果你有它的工具箱,'findpeaks'可能對你有用。 – nkjt 2014-10-03 11:09:02

+0

謝謝你的回答,但不幸的是我沒有工具箱。也許我必須爲此得到它。 – 2014-10-03 11:15:24

+1

一般說明;你在循環中增長'j'',你不需要'newJ',並且如果你把所有東西都存儲在'j'中,那麼把'xlswrite'放在循環的外面,這樣你就不必一直搞清楚了在哪裏寫新的數據。更具體的將取決於你的山峯的形狀。 – nkjt 2014-10-03 12:27:48

回答

1

拆卸循環導致該代碼塊:

nrows=size(data,1); %number of data rows in matrix A 
peakvalues=round((nrows/500)); %number of peak results for sampling frequency of 500Hz 

dataBlocks = reshape(data(1:500*peakvalues),500,peakvalues); 

[maxV,maxIdx] = max(dataBlocks); 
[minV,minIdx] = min(dataBlocks); 
peakV = abs(maxV) + abs(minV); 

maxT = time(maxIdx + ((1:peakvalues)-1)*500,1); 
minT = time(minIdx + ((1:peakvalues)-1)*500,1); 

interestingIdx = (peakV>1500); 

upsMaxT = datevec(datenum(1970,1,1)+(maxT(interestingIdx)/86400)); %converts UNIX time into UPS format 
upsMinT = datevec(datenum(1970,1,1)+(minT(interestingIdx)/86400)); %converts UNIX time into UPS format 

M = [peakV(interestingIdx)' maxIdx(interestingIdx)' minIdx(interestingIdx)' upsMaxT upsMinT]; 

xlswrite('20131221_PeakValues_trial1', M, 1); 

附加說明:您遍歷一個p,但我不明白爲什麼做到這一點。其次,你給這個p後面的分配一個字符串值在的循環中。


編輯:我不認爲你的第一個循環,但由於它遍歷要被讀取的文件這是一個不容易去除。

+0

這段代碼看起來比我的整潔,謝謝!唯一的問題是,它不是更快,因爲xls寫入仍在發生。 – 2014-10-03 13:45:57

+0

我剛剛意識到:您可以通過一次寫入完整的M來減少對xlswrite的調用,因此我更新了代碼。這實際上應該會加快很多。 – MeMyselfAndI 2014-10-03 14:36:19

+0

我嘗試了新版本的代碼,速度快了很多,但我不得不調整maxT和minT部分,但我最終得到的時間看起來不正確。 – 2014-10-06 09:05:35