in reply to Lagrange Polynomials in Perl
Or, you could go fancy with map and reduce:
use strict; use warnings; use List::Util q(reduce); sub xdi { my ($x, $d, $i) = @_; reduce{ $a*$b }map{ $_==$i || $d - $x->[$_] }keys @$x } sub lagc { my ($x, $f) = @_; [map{ $f->[$_] / xdi($x,$x->[$_],$_) }keys @$x] } sub lagx { my ($x, $L, $x0) = @_; reduce{ $a+$b }map{ $L->[$_] * xdi($x,$x0,$_) }keys @$x }
Consider also using bigrat if exact interpolation is sought.
Update. Same thing with sample gnuplot.
use Chart::Gnuplot; use List::Util q(reduce); sub xdi { my ($x, $d, $i) = @_; reduce{ $a*$b }map{ $_==$i || $d - $x->[$_] }keys @$x } sub lagc { my ($x, $f) = @_; [map{ $f->[$_] / xdi($x,$x->[$_],$_) }keys @$x] } sub lagx { my ($x, $L, $x0) = @_; reduce{ $a+$b }map{ $L->[$_] * xdi($x,$x0,$_) }keys @$x } my $x = [-10 .. 10]; my $f = [map { $_/25 + sin $_ } @$x]; my $LC = lagc $x, $f; my $xx = [map { $x->[0] + ($x->[-1] - $x->[0]) * $_/500 } -30 .. 530]; my $ff = [map { lagx $x, $LC, $_ } @$xx]; my $pts0 = Chart::Gnuplot::DataSet->new(xdata => $x, ydata => $f, styl +e => "points"); my $pts = Chart::Gnuplot::DataSet->new(xdata => $xx, ydata => $ff, sty +le => "lines"); Chart::Gnuplot->new(title => "f(x)", output => "plot.ps")->plot2d($pts +0, $pts);
Final note: Math::Polynomial can perform Lagrange interpolation, so there's probably little reason to roll your own module.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Lagrange Polynomials in Perl
by Mascasc (Novice) on Apr 29, 2015 at 16:34 UTC | |
|
Re^2: Lagrange Polynomials in Perl
by Mascasc (Novice) on Apr 30, 2015 at 02:09 UTC |