0

現在、Perl と gnuplot を学んでいます。次の値に基づいて特定の値をカウントする方法を知りたいです。たとえば、次のもので構成されるテキストファイルがあります。

#ID(X) Y
1 1
3 9
5 11

出力には、不明な ID の値も表示されます。したがって、出力は次のようになります。

#ID(X) Y
1 1
2 5
3 9
4 10
5 11

ID#2 の Y は、線形代数である ((2-3)/(1-3))*1 + ((2-1)/(3-1))*9 に基づいています。

Y2=((X2-X3)/(X1-X3))*Y1 + ((X2-X1)/(X3-X1)) * Y3

ID#5も同様

現在、私はこのコードを持っています、

    #! /usr/bin/perl -w
    use strict;

    my $prev_id = 0;
    my $prev_val = 0;
    my $next_id;
    my $next_val;

    while (<>)
    {
    my ($id, $val) = split;
    for (my $i = $prev_id + 1; $i < $next_id; $i++)
    {
    $val = (($id - $next_id) / ($prev_id - $next_id)) * $prev_val + (($id - $prev_id) / ($next_id - $prev_id)) * $next_val;
    printf ("%d %s\n", $i, $val);
    }
    printf ("%d %s\n", $id, $val);
    ($prev_val, $prev_id) = ($val, $id);
    ($next_val, $next_id) = ($prev_val, $prev_id);  
}
4

4 に答える 4

1

あなたが常に1の整数間隔を扱っていることを考えると、あなたの式は私が予想するよりも複雑に見えます.

複数の連続した欠落値のギャップを埋めたいかどうかは言われませんでしたが、そうしたいと仮定しましょう。

あなたがしていることは、最初の行で読み取られ、それが現在のものであると言って、それを出力します。次に、次の行を読み取り、その ID が予期されたものでない場合は、単純な線形補間でギャップを埋めます...

疑似コード

(currID, currY) = readline()
outputvals( currID, currY )

while lines remain do
    (nextID, nextY) = readline()
    gap = nextID - currID

    for i = 1 to gap
        id = currID + i
        y = currY + (nextY - currY) * i / gap
        outputvals( id, y )
    end

    (currID, currY) = (nextID, nextY)
end

Perl 以外のコードで申し訳ありません。Perl を何年も使用しておらず、構文の半分を覚えていないだけです。=) ただし、ここでの概念をコードに変換するのは非常に簡単です。

于 2013-01-16T03:52:15.243 に答える
0

配列を使用することが最善の方法かもしれません。これにより、データをさらに操作できるようになります。

** 警告: y の複数の連続する欠損値では機能しません。@paddyの回答を参照してください。

#!/usr/bin/perl
use strict;
use warnings;

my @coordinates;
while (<DATA>) {
    my ($x, $y) = split;
    $coordinates[$x] = $y;
}

# note that the for loop starts on index 1 here ...
for my $x (1 .. $#coordinates) {
    if (! $coordinates[$x]) {
        $coordinates[$x] = (($x - ($x + 1)) / (($x - 1) - ($x + 1)))
                         * $coordinates[$x - 1]
                         + (($x - ($x - 1)) / (($x + 1) - ($x - 1)))
                         * $coordinates[$x + 1];
    }

    print "$x - $coordinates[$x]\n";
}

__DATA__
1 1
3 9
5 11
于 2013-01-16T21:14:21.360 に答える
0

問題が次の値を取得していることを示しました。重要なのは前を見ることではなく、後ろを見ることです。

my $prev = get first value;
my ($prev_a, $prev_b) = parse($prev);

my $this = get second value;
my ($this_a, $this_b) = parse($this);

while ($next = get next value) {
   my ($next_a, $next_b) = parse($next);
   ...
   $prev = $this;  $prev_a = $this_a;  $prev_b = $this_b;  
   $this = $next;  $this_a = $next_a;  $this_b = $next_b;
}
于 2013-01-16T06:25:59.513 に答える
-1
#! /usr/bin/perl -w
use strict;

my @in = (1,9,11);
my @out;

for (my $i = 0; $i<$#in; $i++) {

    my $j = $i*2;

    my $X1 = $i;
    my $X2 = $i+1;
    my $X3 = $i+2;

    my $Y1 = $in[$i];
    my $Y3 = $in[$i+1];

    my $Y2 = $Y1*(($X2-$X3)/($X1-$X3))
           + $Y3*(($X2-$X1)/($X3-$X1));

    $out[$j]   = $in[$i];
    $out[$j+1] = $Y2;
}

$out[$#in*2] = $in[$#in];
print (join " ",@out);
于 2013-01-16T04:11:12.097 に答える