in reply to Data averages by time of day

Interpolation isn't probably relevant in this case. Bestfit curve (or approximation) which Abigail mentions is. This is why: we want averages (read: good, useful values) in arbitrary Xs, while interpolation produces a function which will exactly evaluate to those Ys from those Xs we used as data for interpolation. Nothing said about Xs between original datapoints, they can be anything. Think of a sine wave which perfectly interpolates points (0, 0), (pi, 0), ..., (n*pi, 0).

Approximation minimizes distance between the curve and each of the datapoints (the datacloud) to produce exactly what you want: a function to calculate useful value in any point of the X axis.

Give Math::Approx a try. Like this:

my %data = ( mins_from_midnight('07:01') => 82, mins_from_midnight('23:48') => 188, # ... ); my $approx = Math::Approx->new(undef, 3, %data); print $approx->approx(mins_from_midnight('15:40'));

Update: and yes, the day you took a specific datapoint does not matter. Anyway, you want average and that means all the days are the same for your task. That's ok.

Replies are listed 'Best First'.
Re: Re: Data averages by time of day
by blue_cowdawg (Monsignor) on Feb 26, 2004 at 19:34 UTC

    I love it! :-)


    Peter L. Berghold -- Unix Professional
    Peter at Berghold dot Net
       Dog trainer, dog agility exhibitor, brewer of fine Belgian style ales. Happiness is a warm, tired, contented dog curled up at your side and a good Belgian ale in your chalice.
Re: Re: Data averages by time of day
by tsee (Curate) on Feb 28, 2004 at 18:48 UTC
    To get at the formula that results from the approximation, try this: (The normal Math::Approx methods also work on Math::Approx::Symbolic objects.)
    use Math::Approx::Symbolic; my %data = ( (7*60+1) => 82, (23*60+48) => 188, ); my $approx = Math::Approx::Symbolic->new(undef, 3, %data); my $sym = $approx->symbolic(); print "$sym\n"; my $prettier = $sym->to_latex(); print "$prettier\n"; # Computing y-values: print $sym->value(x => time_of_day()), "\n"; # Doing that faster: use Math::Symbolic::Compiler; my ($closure) = $sym->to_sub(); print $closure->(time_of_day()), "\n"; # Way faster: use Math::Symbolic::Custom::CCompiler; my $inlined_c = $sym->to_compiled_c(); print $inlined_c->(time_of_day()), "\n";