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

特定の値のリストの最大値を見つけたい場合は、独自のサブルーチンを作成する必要はありません。perlv5.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`; 

または1行で

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

convolveND ここに文書化されています


この方法で注意すべき点が 1 つあります。それは、$runningAve ピドルの最初と最後の値が、実際には移動平均ではないということです。出力が入力と同じサイズになるようにするためconvolveND(既定では) は、入力の最初と最後に効果的にゼロを連結します。その結果、 の最初と最後のいくつかの要素が$runningAve実際の移動平均よりも低くなります。N - (window - 1)(移動平均には原則として要素が必要であり、N は のサイズであることに注意してください$input。) これらの「悪い」値は実際の移動平均値よりも必然的に低くなるため、必要な最大値を乱すことはありません。(「デフォルト」に関して:convolveND上記にリンクされているドキュメントでわかるように、エッジを処理する他の方法があります。)

(NB: 私は 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 に答える