use PDL;
use PDL::Opt::Simplex;
#
# Simplex Demo - Alison Offer (aro@aaocbn.aao.gov.au)
#
#
# this is some sort of convergence criterion
$minsize = 1.e-6;
# max number of iterations ?
$maxiter = 100;
#
print " \n
1: least squares gaussian fit to data + noise \n
32 *exp (-((x-10)/6)^2) + noise
2: minimise polynomial \n
(x-3)^2 + 2.*(x-3)*(y-2.5) + 3.*(y-2.5)^2 \n
Please make your choice (1 or 2):";
chop($choice = <>);
if ($choice == 1) {
print "Please enter noise factor (small number, 0-6):";
chop($factor = <>);
#
# data : gaussian + noise
#
foreach $j (0..19) {
$data[$j] = 32*exp(-(($j-10)/6)**2) +
$factor * (rand() - 0.5);
}
#
# initial guess - $initsize controls the size of the initial simplex (I think)
#
$init = pdl [ 33, 9, 12 ];
$initsize = 2;
#
#
($optimum,$ssize) = simplex($init,$initsize,$minsize,$maxiter,
# this sub returns the function to be minimised.
sub {my ($xv) =@_;
my $a = $xv->slice("(0)");
my $b = $xv->slice("(1)");
my $c = $xv->slice("(2)");
my $sum = $a * 0.0;
foreach $j (0..19) {
$sum += ($data[$j] -
$a*exp(-(($j-$b)/$c)**2))**2;
}
return $sum;
});
} else {
$init = pdl [ 2 , 2 ];
$initsize = 2;
($optimum,$ssize) = simplex($init,$initsize,$minsize,$maxiter,
sub {my ($xv) =@_;
my $x = $xv->slice("(0)");
my $y = $xv->slice("(1)");
return ($x-3)**2 + 2.*($x-3)*($y-2.5)
+ 3.*($y-2.5)**2;
});
}
print "OPTIMUM = $optimum \n";
print "SSIZE = $ssize\n";