Algorithm-GoldenSection
view release on metacpan or search on metacpan
lib/Algorithm/GoldenSection.pm view on Meta::CPAN
package Algorithm::GoldenSection;
use warnings;
use strict;
use Carp;
use Readonly;
use version; our $VERSION = qv('0.0.2');
=head1 NAME
Algorithm::GoldenSection - Golden Section Search Algorithm for one-dimensional minimisation.
=cut
=head1 VERSION
This document describes Algorithm::GoldenSection version 0.0.2
=cut
=head1 DESCRIPTION
This module is an implementation of the Golden Section Search Algorithm for finding minima of a unimodal function.
In order to isolate a minimum of a univariate functions the minimum must first be isolated.
Consequently the program first bounds a minimum - i.e. the program initially creates a triplet of points:
x_low < x_int < x_high, such that f(x_int) is lower than both f(x_low) and f(x_high). Thus we ensure that there
is a local minimum within the interval: x_low-x_high. The program then uses the Golde Section Search algorithm
to successively narrow down on the bounded region to find the minimum.
See http://en.wikipedia.org/wiki/Golden_section_search and
http://www.gnu.org/software/gsl/manual/html_node/One-dimensional-Minimization.html.
The module provides a Perl5OO interface. Simply construct a Algorithm::GoldenSection object with appropriate parameters
- see L</SYNOPSIS>. Then call the minimise C<method>. This returns a LIST of the value of x at the minimum, the value of
f(x) at the minimum and the number of iterations used to isolate the minimum.
=cut
=head1 SYNOPSIS
use Algorithm::GoldenSection;
# Create a Algorithm::GoldenSection object and pass it a CODE reference to the function to be minimised and initials values for x_low and x_int.
$gs = Algorithm::GoldenSection->new( { function => sub { my $x = shift; my $b = $x * sin($x) - 2 * cos($x); return $b },
x_low => 4,
x_int => 4.7,} ) ;
# Call minimisation method to bracket and minimise.
my ($x_min, $f_min, $iterations) = $gs->minimise;
print qq{\nMinimisation results: x a minimum = $x_min, function value at minimum = $f_min. Calculation took $iterations iterations};
=cut
# package-scoped lexicals
Readonly::Scalar my $ouro => 1.618034 ;
Readonly::Scalar my $glimite => 100.0 ;
Readonly::Scalar my $pequeninho => 1.0e-20 ;
Readonly::Scalar my $tolerancia => 3.0e-8; # tolerance
Readonly::Scalar my $C => (3-sqrt(5))/2;
Readonly::Scalar my $R => 1-$C;
#/ I had leaving things for operator precedence. you won´t see A+B*(C-D) whe you mean: A+( B*(C-D) ) - i.e. * binds more tightly that +
sub new {
my ( $class, $h_ref ) = @_;
croak qq{\nArguments must be passed as HASH reference.} if ( ( $h_ref ) && ( ref $h_ref ne q{HASH} ) );
my $self = {};
bless $self, $class;
$self->_check_options($h_ref);
return $self;
}
sub _check_options {
my ( $self, $h_ref ) = @_;
croak qq{\nOption \x27function\x27 is obrigatory and accepts a CODE reference}
if ( ( !exists $h_ref->{function} ) || ( ref $h_ref->{function} ne q{CODE} ) );
croak qq{\nOption \x27x_low\x27 requirements a numeric value}
if ( ( !exists $h_ref->{x_low} ) || ( $h_ref->{x_low} !~ /\A[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?\z/xms ) );
croak qq{\nOption \x27x_low\x27 requirements a numeric value}
if ( ( !exists $h_ref->{x_int} ) || ( $h_ref->{x_int} !~ /\A[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?\z/xms ) );
$self->{function} = $h_ref->{function};
$self->{x_low} = $h_ref->{x_low};
$self->{x_int} = $h_ref->{x_int};
}
sub _switch {
( run in 0.677 second using v1.01-cache-2.11-cpan-39bf76dae61 )