#!/usr/bin/perl

use lib 'd:/Programs/Perl/lib';

use strict;
use Sci::Optimize;

my $Opt = new Optimize;

my $Method = "PDL::Simplex";
#my $Method = "Amoeba::Simplex";
#my $Method = "ModifiedNewton";
#my $Method = "LinearOptimization"; # 線形パラメータのみ。

my $EPS = 1.0e-7;
my $nMaxIter = 100;
my @Guess = (1, 1, 1);
my @OptId = (1, 1, 1);
my @Scale = (1, 1, 1);
my $iPrintLevel = 0;

print "use $Method\n";

#必要なければ、PDLDisplayFunc以降は指定する必要はない
my ($OptVars, $MinVal) = $Opt->Optimize($Method, \@Guess, \@OptId, \@Scale, 
				$EPS, $nMaxIter, $iPrintLevel,
				\&MinimizationFunc, \&PDLDisplayFunc,
				sub { Optimize::BuildDifferentialMatrixes(@_); },
				);
print "Optimized at (",join(',',@{$OptVars}),")=$MinVal\n";

exit;

#==============================================
# 最小化関数のサブルーチン
# MinimizationFunc    : 
# PDLDisplaySimplex: PDL::Opt::Simplex用のDisplay関数
#==============================================
sub MinimizationFunc {
	my ($pVars, $iPrintLevel) = @_;
	my ($a, $b, $c) = @$pVars;
#print "a=$a, b=$b, c=$c\n";
	my $S = ($a-7)**2 + ($b+3)**2 + ($c-4)**2 + ($c-2);
printf("a,b,c=%6.3f\t%6.3f\t%6.3f\t(%g)\n", $a, $b, $c, $S) if($iPrintLevel >= 2);
	return $S;
}

sub PDLDisplayFunc {
	my ($piddle) = @_;
#print "Display: piddle=$piddle\n";
}
