From 81512340bb09d482912b3bf69a955d18b0cb2a78 Mon Sep 17 00:00:00 2001 From: Jonathan Leto Date: Thu, 9 Oct 2008 20:46:46 -0700 Subject: [PATCH] Improved intro examples in Math::GSL and fixed return signature of gsl_deriv_* functions --- Changes | 2 ++ Deriv.i | 18 +++++++++++------- lib/Math/GSL.pm | 15 ++++++++++++--- t/Deriv.t | 30 +++++++++++++----------------- 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/Changes b/Changes index 5ed0921..6c808eb 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,7 @@ 0.14 - Improved Roots docs + - Improved introduction examples in Math::GSL + - Fixed return signature of gsl_deriv_* functions to return a flat list - Fix location of shared objects (Sisyphus) - Added raw() method to RNG objects - Chebyshev Series Approximation, with tests and docs diff --git a/Deriv.i b/Deriv.i index e00e89a..eac03aa 100644 --- a/Deriv.i +++ b/Deriv.i @@ -7,7 +7,7 @@ double x, double h, double *result, double *abserr) { SV ** sv; - AV* av = newAV(); + //AV* av = newAV(); sv = hv_fetch(Callbacks, (char*)&$input, sizeof($input), FALSE ); if (sv == (SV**)NULL) @@ -22,13 +22,18 @@ /* This actually calls the perl subroutine */ call_sv(*sv, G_SCALAR); - av_push(av, newSVnv((double) *$4)); - av_push(av, newSVnv((double) *$5)); - $result = sv_2mortal( newRV_noinc( (SV*) av) ); + //av_push(av, newSVnv((double) *$4)); + //av_push(av, newSVnv((double) *$5)); + //$result = sv_2mortal( newRV_noinc( (SV*) av) ); + $result = sv_newmortal(); + sv_setnv($result, (double) *$4); + argvi++; + sv_setnv($result, (double) *$5); + argvi++; + if (argvi >= items) { EXTEND(SP,1); } - argvi++; } @@ -55,11 +60,10 @@ __END__ =head1 NAME -Math::GSL::Deriv - Functions to compute numerical derivatives by finite differencing +Math::GSL::Deriv - Numerical Derivatives =head1 SYNOPSIS -This module is not yet implemented. Patches Welcome! use Math::GSL::Deriv qw /:all/; diff --git a/lib/Math/GSL.pm b/lib/Math/GSL.pm index 496ad22..dbc18bd 100644 --- a/lib/Math/GSL.pm +++ b/lib/Math/GSL.pm @@ -39,13 +39,22 @@ Version 0.13_01 =head1 SYNOPSIS - use Math::GSL::Matrix qw/:all/; + use Math::GSL::Matrix; my $matrix = Math::GSL::Matrix->new(5,5); # 5x5 zero matrix - $matrix->set_col(0, [1..5]) - ->set_row(2, [5..9]); + # note that columns and rows are zero-based + $matrix->set_col(0, [1..5]) # set *first* column to 1,2,3,4,5 + ->set_row(2, [5..9]); # set *third* column to 5,6,7,8,9 my @matrix = $matrix->as_list; # matrix as Perl list my $gsl_matrix = $matrix->raw; # underlying GSL object + use Math::GSL::RNG; + my $rng = Math::GSL::RNG->new; + my @random_numbers = map { $rng->get } (1 .. 1000); + + use Math::GSL::Deriv qw/:all/; + my $function = sub { my $x=shift; sin($x**2) }; + my ($status,$val,$err) = gsl_deriv_central($function, 5, 0.01 ); + Each GSL subsystem has it's own module. For example, the random number generator subsystem is Math::GSL::RNG. Many subsystems have a more Perlish and object-oriented frontend which can be used, as the above example shows. The raw diff --git a/t/Deriv.t b/t/Deriv.t index a0a68a7..15d80cd 100644 --- a/t/Deriv.t +++ b/t/Deriv.t @@ -34,41 +34,37 @@ sub TEST_DERIV_CENTRAL_DIES : Tests { } sub TEST_DERIV_CENTRAL : Tests { - my ($x,$h)=(10,0.01); my $self = shift; - my ($status, $result); + my ($x,$h)=(10,0.01); - ($status, $result) = gsl_deriv_central ( sub { $_[0] ** 3 }, $x, $h,); + my ($status, $val,$err) = gsl_deriv_central ( sub { $_[0] ** 3 }, $x, $h,); ok_status($status); - my $res = abs($result->[0]-3*$x**2); - ok( $res < $result->[1] , sprintf ("gsl_deriv_forward: res=%.18f, abserr=%.18f",$res, $result->[1] )); + my $res = abs($val-3*$x**2); + ok( $res <= $err , sprintf ("gsl_deriv_forward: res=%.18f, abserr=%.18f",$res, $err )); } sub TEST_DERIV_FORWARD : Tests { - my ($x,$h)=(10,0.01); my $self = shift; - my ($status, $result); - ($status, $result) = gsl_deriv_forward ( sub { 2 * $_[0] ** 2 }, $x, $h,); + my ($x,$h)=(10,0.01); + my ($status, $val,$err) = gsl_deriv_forward ( sub { 2 * $_[0] ** 2 }, $x, $h,); ok_status($status); - my $res = abs($result->[0]-4*$x); - ok( $res < $result->[1] , sprintf ("gsl_deriv_forward: res=%.18f, abserr=%.18f",$res, $result->[1] )); + my $res = abs($val-4*$x); + ok( $res <= $err , sprintf ("gsl_deriv_forward: res=%.18f, abserr=%.18f",$res, $err )); } sub TEST_DERIV_BACKWARD : Tests { - my ($x,$h)=(10,0.01); my $self = shift; - my ($status, $result); - - ($status, $result) = gsl_deriv_backward ( sub { log $_[0] }, $x, $h,); + my ($x,$h)=(10,0.01); + my ($status, $val, $err) = gsl_deriv_backward ( sub { log $_[0] }, $x, $h,); ok_status($status); - my $res = abs($result->[0]-1/$x); - ok( $res < $result->[1] , sprintf ("gsl_deriv_backward: res=%.18f, abserr=%.18f",$res, $result->[1] )); + my $res = abs($val-1/$x); + ok( $res <= $err , sprintf ("gsl_deriv_backward: res=%.18f, abserr=%.18f",$res, $err )); } sub TEST_DERIV_CENTRAL_CALLS_THE_SUB : Tests { - my ($x,$h)=(10,0.01); my $self = shift; + my ($x,$h)=(10,0.01); throws_ok( sub { gsl_deriv_central ( sub { die "CALL ME BACK!"} , $x, $h)