#!/usr/bin/perl

use lib 'd:/git/tkProg/tklib/Perl/lib';
use lib '/home/share/tkProg/tklib/Perl/lib';

use strict;
use Sci qw(cosh);
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-15;
my $nMaxIter = 100;
my @Guess = (1);
my @OptId = (1);
my @Scale = (.01);
my $iPrintLevel = 0;

print "use $Method\n";

print "R,f,S\n";
for(my $i = 0 ; $i < 21 ; $i++) {
	my $R = 1.0 + $i * 0.1;

	my ($OptVars, $MinVal) = $Opt->Optimize($Method, \@Guess, \@OptId, \@Scale, 
				$EPS, $nMaxIter, $iPrintLevel,
				sub { &MinimizationFunc($R, @_); }, \&PDLDisplayFunc,
				sub { Optimize::BuildDifferentialMatrixes(@_); },
				);
#print "Optimized at (",join(',',@{$OptVars}),")=$MinVal\n";
	print "$R,$OptVars->[0],", sqrt($MinVal), "\n";
}

exit;

#==============================================
# 最小化関数のサブルーチン
# MinimizationFunc    : 
# PDLDisplaySimplex: PDL::Opt::Simplex用のDisplay関数
#==============================================
sub MinimizationFunc {
	my ($R, $pVars, $iPrintLevel) = @_;
	my ($f) = @$pVars;

	my $ln2 = log(2.0);
	my $S = exp($ln2 / $f) / 2.0 - cosh( ($R-1.0)/($R+1.0) * $ln2 / $f);
#print "R=$R, f=$f, S = $S\n";
	return $S * $S;
#	return sqrt($S * $S);
}

sub PDLDisplayFunc {
	my ($piddle) = @_;
#print "Display: piddle=$piddle\n";
}
