#!/usr/bin/perl # Copyright (c) 2009-2017 Martin Becker. All rights reserved. # This package is free software; you can redistribute it and/or modify it # under the same terms as Perl itself. # Math::Polynomial usage example: demonstrating Runge's phenomenon # # High degree interpolation polynomials fitted through nodes with equidistant # x-values can oscillate wildly towards the end nodes, which makes them # unsuitable for approximation purposes. This script calculates values # to plot a function and an interpolation polynomial, displaying such # behaviour, which was described by Carl Runge in a paper of 1901. # # The accompanying file "runge_plot.png" demonstrates this visually. use strict; use warnings; use Math::Polynomial 1.000; sub my_function { my ($x) = @_; return 1.0 / (1.0 + 25.0*$x*$x); } my $INTERVALS = 8; my $MIN_X = -1.0; my $MAX_X = 1.0; my $PLOT_INTERVALS = 40; my $PLOT_MIN_X = -1.25; my $PLOT_MAX_X = 1.25; my @x_values = map { $MIN_X + ($MAX_X - $MIN_X) * $_ / $INTERVALS } 0..$INTERVALS; my @y_values = map { my_function($_) } @x_values; my $lagrange = Math::Polynomial->interpolate(\@x_values, \@y_values); foreach my $i (0..$PLOT_INTERVALS) { my $x = $PLOT_MIN_X + ($PLOT_MAX_X-$PLOT_MIN_X) * $i / $PLOT_INTERVALS; printf "%7.4f %10.6f %10.6f\n", $x, my_function($x), $lagrange->evaluate($x); } __END__