【问题标题】:Finding peak-to-peak values in time intervals MATLAB在时间间隔内查找峰峰值 MATLAB
【发布时间】:2014-11-28 10:41:50
【问题描述】:

我将数据组织成 2 个矩阵,“时间”和“数据”。我想找到“数据”矩阵第一列的峰峰值。我试图通过遍历数据点来做到这一点,一次 500 个点,并在每个间隔内找到最大值和最小值。将两个值的绝对值相加即可找到峰值。

峰值=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

结束

【问题讨论】:

  • 如果你有它的工具箱,findpeaks 可能对你有用。
  • 感谢您的回答,但很遗憾我没有工具箱。也许我必须为此得到它。
  • 一般说明;你在循环中增长j,你不需要newJ,如果你把所有的东西都存储在j中,把xlswrite放在循环之外,这样你就不必一直弄清楚在哪里写入新数据。更多细节取决于峰的形状。
  • 我没有发现任何问题或提高速度的简单方法。您可能希望使用peakV = maxV - minV 计算峰值,以考虑maxV 为负数或minV 为正数的可能性。这是一个有趣的问题,我会再考虑一下
  • 正如@nkjt 所说,尽可能将xlswrite 移到循环之外。 xlswrite 是一个非常很慢的函数,每次调用可能需要半秒时间。

标签: matlab for-loop


【解决方案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 分配一个字符串值。


编辑:我没有考虑您的第一个循环,但是这个循环不容易删除,因为它循环了要读取的文件。

【讨论】:

  • 这段代码看起来比我的简洁很多,谢谢!唯一的问题是它并没有更快,因为 xls 写入仍在进行中。
  • 我刚刚意识到:您可以通过一次编写完整的 M 来减少对 xlswrite 的调用,因此我更新了代码。这实际上应该加快很多。
  • 我尝试了新版本的代码,速度快了很多,但我不得不调整 maxT 和 minT 部分,但最后得到的时间看起来不正确。
  • 你能解释一下 maxT = time0(maxIdx + ((1:peakvalues)-1)*500,1);这部分是什么意思?它说索引超出了矩阵维度
  • 我猜这是由 round 函数引起的 - 你应该用 floor 替换它(它向零舍入,因此忽略最后一个少于 500 个元素的块)。代码 sn-p 所做的是将maxIdx 转换为正确的时间索引以获得maxT。由于data的reshape,我们需要移动时间数组的索引值(没有reshape)。
猜你喜欢
  • 2015-02-24
  • 2017-02-22
  • 1970-01-01
  • 2015-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-13
  • 2020-11-17
相关资源
最近更新 更多