/usr/share/perl5/Math/Derivative.pm is in libmath-derivative-perl 0.04-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | # functions for calculating derivatives of data
# $Id: Derivative.pm,v 1.1 1995/12/26 16:26:59 willijar Exp $
=head1 NAME
Math::Derivative - Numeric 1st and 2nd order differentiation
=head1 SYNOPSIS
use Math::Derivative qw(Derivative1 Derivative2);
@dydx = Derivative1(\@x, \@y);
@d2ydx2 = Derivative2(\@x, \@y);
@d2ydx2 = Derivative2(\@x, \@y, $yp0, $ypn);
=head1 DESCRIPTION
This Perl package exports functions for performing numerical first
(B<Derivative1>) and second B<Derivative2>) order differentiation on
vectors of data.
=head2 FUNCTIONS
The functions must be imported by name.
=head3 Derivative1()
Take the references to two arrays containing the x and y ordinates of
the data, and return an array of the 1st derivative at the given x ordinates.
=head3 Derivative2()
Take references to two arrays containing the x and y ordinates of the
data and return an array of the 2nd derivative at the given x ordinates.
You may optionally give values to use as the first dervivatives at the
start and end points of the data. If you don't, first derivative values
will be calculated from the arrays for you.
=head1 AUTHOR
John A.R. Williams B<J.A.R.Williams@aston.ac.uk>
John M. Gamble B<jgamble@cpan.org> (current maintainer)
=cut
package Math::Derivative;
use 5.8.3;
use Exporter;
our(@ISA, @EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT_OK = qw(Derivative1 Derivative2);
our $VERSION = 0.04;
use strict;
use warnings;
use Carp;
sub Derivative1
{
my ($x, $y) = @_;
my @y2;
my $n = $#{$x};
croak "X and Y array lengths don't match." unless ($n == $#{$y});
$y2[0] = ($y->[1] - $y->[0])/($x->[1] - $x->[0]);
$y2[$n] = ($y->[$n] - $y->[$n-1])/($x->[$n] - $x->[$n-1]);
for (my $i=1; $i<$n; $i++)
{
$y2[$i] = ($y->[$i+1] - $y->[$i-1])/($x->[$i+1] - $x->[$i-1]);
}
return @y2;
}
sub Derivative2
{
my ($x, $y, $yp1, $ypn) = @_;
my $n = $#{$x};
my (@y2, @u);
my ($qn, $un);
croak "X and Y array lengths don't match." unless ($n == $#{$y});
if (defined $yp1)
{
$y2[0] = -0.5;
$u[0] = (3/($x->[1] - $x->[0])) * (($y->[1] - $y->[0])/($x->[1] - $x->[0]) - $yp1);
}
else
{
$y2[0] = 0;
$u[0] = 0;
}
for (my $i = 1; $i < $n; $i++)
{
my $sig = ($x->[$i] - $x->[$i-1])/($x->[$i+1] - $x->[$i-1]);
my $p = $sig * $y2[$i-1] + 2.0;
$y2[$i] = ($sig - 1.0)/$p;
$u[$i] = (6.0 * ( ($y->[$i+1] - $y->[$i])/($x->[$i+1] - $x->[$i]) -
($y->[$i] - $y->[$i-1])/($x->[$i] - $x->[$i-1])
)/
($x->[$i+1] - $x->[$i-1]) - $sig * $u[$i-1])/$p;
}
if (defined $ypn)
{
$qn = 0.5;
$un = (3.0/($x->[$n]-$x->[$n-1])) *
($ypn - ($y->[$n] - $y->[$n-1])/($x->[$n] - $x->[$n-1]));
}
else
{
$qn = 0;
$un = 0;
}
$y2[$n] = ($un - $qn * $u[$n-1])/($qn * $y2[$n-1] + 1.0);
for(my $i = $n-1; $i >= 0; --$i)
{
$y2[$i] = $y2[$i] * $y2[$i+1] + $u[$i];
}
return @y2;
}
1;
|