我以前从未钻研过Perl的世界,我发现它很混乱,可以使用一些帮助。在下面的代码中,calc()部分返回'count'样本的'输入'的运行平均值。我想修改它,以便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;
}
答案 0 :(得分:6)
答案 1 :(得分: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
答案 2 :(得分:0)
编辑:这是我需要的循环。
我是这样做的。
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
is documented here。
使用这种方法有一点需要注意,即$ 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)