Perl根据下一个值计算当前值

时间:2013-01-16 03:14:24

标签: perl text linear-algebra

目前我正在学习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 个答案:

答案 0 :(得分: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,并且不记得一半的语法。 =)这里的概念很容易翻译成代码。

答案 1 :(得分: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;
}

答案 2 :(得分: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

答案 3 :(得分:-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);
相关问题