Hi,
I suggest a patch for PDL::Opt::Simplex.
($optimum,$ssize) = simplex($init,$initsize,$minsize,
$maxiter,
sub {evaluate_func_at($_[0])},
sub {display_simplex($_[0])}
);
The change I made is about $init above. When the $init is two-dimension,
pre-constructed simplex is assumed. Otherwise it is same as the original
version. My minimization takes very long time. So it requres restart
sometimes. That's why I wanted to have pre-constructed simplex.
--
Best,
InSuk Joung
--- /home/isjoung/perl/lib/x86_64-linux-thread-multi/PDL/Opt/Simplex.pm 2009-07-28 17:15:07.000000000 -0400
+++ Simplex.pm 2009-07-29 11:05:28.000000000 -0400
@@ -113,23 +113,33 @@
sub PDL::simplex {
my($init,$initsize,$minsize,$maxiter,$sub,$logsub,$t) = @_;
if(!defined $t) {$t = 0}
- my ($i,$j); my $nd = $init->getdim(0);
- my $simp = PDL->zeroes($nd,$nd+1);
- $simp .= $init;
+ my ($i,$j);
+ my ( $nd, $nd2 ) = ( dims($init), 1 );
+ my $simp;
+ if ( $nd2 == 1 ) {
+ $simp = PDL->zeroes($nd,$nd+1);
+ $simp .= $init;
# Constructing a tetrahedron:
# At step n (starting from zero)
# take vertices 0..n and move them 1/(n+1) to negative dir on axis n.
# Take vertex n+1 and move it n/(n+1) to positive dir on axis n
- if(!ref $initsize) {
- $initsize = PDL->pdl($initsize)->dummy(0,$nd);
+ if(!ref $initsize) {
+ $initsize = PDL->pdl($initsize)->dummy(0,$nd);
+ }
+ for($i=0; $i<$nd; $i++) {
+ my $pj = $i/($i+1);
+ (my $stoopid = $simp->slice("$i,0:$i"))
+ -= $initsize->at($i) * $pj;
+ (my $stoopid1 = $simp->slice("$i,".($i+1)))
+ += $initsize->at($i) * (1-$pj);
+ }
}
- for($i=0; $i<$nd; $i++) {
- my $pj = $i/($i+1);
- (my $stoopid = $simp->slice("$i,0:$i"))
- -= $initsize->at($i) * $pj;
- (my $stoopid1 = $simp->slice("$i,".($i+1)))
- += $initsize->at($i) * (1-$pj);
+ elsif ( $nd2 == $nd + 1 ) {
+ $simp = $init;
}
+ else {
+ return;
+ }
my $maxind = PDL->null;
my $minind = PDL->zeroes(2);;
my $ssum = PDL->null;
@@ -137,7 +147,9 @@
my $new;
my $realnew;
my $vals = &{$sub}($simp);
- my $ssize = $initsize->min*2;
+ my $ss1 = ($simp - $simp->slice(":,0"))**2;
+ sumover($ss1,(my $ss2=PDL->null));
+ my $ssize = PDL::max(sqrt($ss2));
&{$logsub}($simp,$vals,$ssize)
if $logsub;
while($maxiter-- and max(PDL->topdl($ssize)) > $minsize ) {
@@ -184,7 +196,7 @@
$worst .= $realnew;
(my $stoopid2= $vals->slice("($maxind)")) .= &{$sub}($worst);
my $ss1 = ($simp - $simp->slice(":,0"))**2;
- sumover($ss1,(my $ss2=PDL->null));
+ sumover($ss1,($ss2=PDL->null));
$ssize = PDL::max(sqrt($ss2));
&{$logsub}($simp,$vals,$ssize)
if $logsub;
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl