in reply to Interpolating data slope for multiple points
The following seems to do what you want using a simple linear interpolation. The trick is figuring out which two data points to interpolate between. That's what the shift @rawData while ... is doing.
use strict; use warnings; use POSIX; use constant kIntervals => 10.0; my @rawData; my $tmin; my $tmax; my $secPerDay = 60 * 60 * 24; for (<DATA>) { chomp; next unless m{^\s*([\d/]+)\s+([\d.]+)}; my ($m, $d, $y) = split /\//, $1; my $weight = $2; my $date = POSIX::mktime(0, 0, 0, $d, $m - 1, $y - 1900); $tmin = $date if ! $tmin; $date -= $tmin; $tmax = $date /= $secPerDay; push @rawData, [$date, $weight]; } my ($wmax, $wmin) = ($rawData[0][1], $rawData[-1][1]); my $interval = $tmax / kIntervals; my $wcalc = $wmax; my $wgone; my @data; for my $point (0 .. kIntervals) { my $epoch = $point * $interval; shift @rawData while @rawData > 1 && $rawData[1][0] < $epoch; last if ! @rawData; if (@rawData == 1) { push @data, [$epoch, $rawData[0][1]]; last; } my $m = $rawData[0][1]; my $s = ($rawData[1][1] - $rawData[0][1]) / ($rawData[1][0] - $raw +Data[0][0]); push @data, [$epoch, $m + $s * ($epoch - $rawData[0][0])]; } printf "%d\t%5.1f\n", $_->[0], $_->[1] for @data; __DATA__ 6/26/2010 334 8/12/2010 311.8 8/19/2010 308.4 9/5/2010 300.0 9/9/2010 298.6 9/14/2010 297.2 9/16/2010 293.6
Prints:
0 334.0 8 330.1 16 326.3 24 322.4 32 318.5 41 314.6 49 310.7 57 306.7 65 302.7 73 299.0 82 293.6
I haven't bothered with the graphing code, mostly because that makes it harder to compare results without posting a graph.
Note that the %s strftime format code is non-standard. I used mktime instead to get epoch seconds then converted that into delta days.
Update: Fixed interval calculation bug - use $interval instead of kIntervals!
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Interpolating data slope for multiple points
by oko1 (Deacon) on Sep 17, 2010 at 05:06 UTC | |
by GrandFather (Saint) on Sep 17, 2010 at 05:47 UTC | |
by oko1 (Deacon) on Sep 17, 2010 at 15:10 UTC |