1

我以前从未深入研究过 Perl 的世界,我觉得它很混乱,需要一些帮助。在下面的代码中, calc() 部分返回“输入”超过“计数”样本的运行平均值。我想修改它,以便 calc() 返回样本集中的最大值。在此先感谢您的帮助!

sub calc
{
    my ($this, $dim, $input, $count) = @_;

    if ($count < 1)
    {
        warn "count=$count is less than 1.";
        return undef;
    }

    my $inputsum_in = $this->{inputsum};
    my ($inputcumsum, $inputsum_out) = PDL::CumulativeSumOver2($input, $inputsum_in);

    my $inputdelay = $this->delay('inputhistory', $input);
    my $inputdelaysum_in = $this->{inputdelaysum};
    my ($inputdelaycumsum, $inputdelaysum_out) = PDL::CumulativeSumOver2($inputdelay, $inputdelaysum_in);

    $this->{inputsum} = $inputsum_out;
    $this->{inputdelaysum} = $inputdelaysum_out;

    my $sampleno = $this->{sampleno};
    my $divider = $count;
    if($sampleno < $count)
    {
        my $last = $dim - 1;
        $divider = sequence($dim) + ($sampleno + 1);
        my $start = $count - $sampleno;
        $divider->slice("$start:$last") .= $count if $start <= $last;
        $this->{sampleno} = $sampleno + $dim;
    }
    return ($inputcumsum - $inputdelaycumsum) / $divider;
}
4

3 回答 3

6

怎么样

 $max = max($input);

PDL 原语

于 2012-08-24T16:01:23.683 回答
1

如果要查找某个值列表的最大值,则无需编写自己的子例程。perl v5.7.3 或更高版本已经附带了一个函数:

use List::Util qw(max); # core module since v5.7.3
use strict;
use warnings;

print max(1 .. 10);  # prints 10
于 2012-08-24T15:55:30.970 回答
0

编辑:这是我认为你需要的循环。

  1. 从传感器读取输入数据
  2. 将新数据附加到存储的数据
  3. 丢弃多余的数据
  4. 评估

这就是我的做法。

my $storedData = pdl;  
# $storedData is now a vector containing one element, 0
while (! stopCondition()) {
    my $input = readSensorData(); # step 1
    $storedData = $storedData->append($input); # step 2
    if ($storedData->nelem > $count) { # step 3
        $storedData = $storedData->slice("-$count:-1");
        # note that -1 points to the last element in a piddle and -X refers to 
        # the element X-1  away from the end (true for piddles and native arrays)
    }
    my ($max, $min) = evaluate($storedData); # step 4
}

我不确定这是否能回答您的问题,但您下面的评论似乎与您上面的问题完全不同。考虑编辑以上内容以更好地反映您遇到的问题或提出新问题。


获得运行平均值的一种简单方法是使用有限脉冲响应滤波器,即卷积。将任何信号与(归一化的)矩形脉冲进行卷积,得到运行平均值。

my $filter = ones($count) / $count; 
my $runningAve = convolveND($input, $filter); 
my $max = $runningAve->max`; 

或者在一行

my $max = convolveND($input, ones($count) / $count)->max;

convolveND 记录在这里


使用此方法需要注意一件事,即 $runningAve piddle 开头和结尾的值并不是真正的运行平均值。为了确保输出与输入的大小相同convolveND(默认情况下),有效地将零连接到输入的开头和结尾,结果是第一个和最后几个元素$runningAve低于实际运行平均值。(请注意,运行平均值N - (window - 1)原则上应该包含元素,N 是 的大小$input。)由于这些“坏”值必然低于实际运行平均值,因此它们不会干扰您想要的最大值。(关于“默认情况下”:convolveND有其他处理边缘的方法,正如您将在上面链接的文档中看到的那样。)

(注意:我不是 PDL 专家。可能有一种比 convolveND 更便宜的方法来获得运行平均值,例如$ra = $input->range(...)->sumover(0) / $count,但我不知道你在......上面放了什么. 另见http://search.cpan.org/~jlapeyre/PDL-DSP-Iir-0.002/README.pod#moving_average )

于 2012-09-24T18:44:40.753 回答