# -*- tcl -*- # Tests for the math::probopt pacakge # # RCS: @(#) $Id: geometry.test,v 1.13 2010/04/06 17:02:25 andreas_kupries Exp $ # ------------------------------------------------------------------------- source [file join \ [file dirname [file dirname [file join [pwd] [info script]]]] \ devtools testutilities.tcl] testsNeedTcl 8.5 testsNeedTcltest 1.0 support { useLocal math.tcl math } testing { useLocal probopt.tcl math::probopt } # setRand -- # Make sure we always get the same results: # Use srand() to ensure that the random numbers follow # the same sequence. # proc setRand {} { expr {srand(100000)} } # # Simple quadratic function # proc f {coords} { lassign $coords x y return [expr {($x-1.0)**2 + ($y-1.0)**2}] } # # Rosenbrock function # proc rosenbrock {coords} { lassign $coords x y return [expr {100.0 * ($y - $x ** 2) ** 2 + (1.0 - $x) ** 2}] } # # Slightly distorted sombrero - minimum at (1,0) # proc sombrero {coords} { lassign $coords x y set r [expr {hypot($x,$y)}] return [expr {(1.0 - $r ** 2) ** 2 + 0.01 * (1.0 - $x)**2}] } # # Wavy function (3D) - absolute minimum at (x,y,z) = (0,0,0), but lots of local minima # proc wavy3d {coords} { lassign $coords x y z return [expr {1.0 - cos(10.0*$x) * cos(10.0*$y) * cos(10.0*$z) + 0.01 * ($x**2 + $y**2 + $z**2)}] } # # Discontinuous function with a clear global minimum at (x,y) = (0,0) # proc halfparabola {coords} { lassign $coords x y if { $x > 0.0 } { set f [expr {$x**2 + $y**2}] } else { set f [expr {-$x + abs($y) + 1.0}] } return $f } # # 3D function with maximum - bounds slightly beyond [-1,1] # proc sombrero3D {coords} { lassign $coords x y z set r2 [expr {$x**2 + $y**2 + $z**2}] return [expr {(10.0 - $r2)**2}] } # # Procedure in a namespace # namespace eval testcase { proc ftest {coords} { lassign $coords x y return [expr {($x-1.0)**2 + ($y-1.0)**2}] } } # # Create and register (in that order!) custom matching procedures # proc matchTolerant { expected actual } { set match 1 foreach a $actual e $expected { if { $e != 0.0 } { if { abs($e-$a)>0.005*abs($e) && abs($e-$a)>0.005*abs($a) } { set match 0 break } } else { if { abs($a) > 0.0001 } { set match 0 } } } return $match } ::tcltest::customMatch tolerant matchTolerant # Test cases -- # # # PSO # test "PSO-0.1" "Check known options" -body { set coords_value [::math::probopt::pso f {{0.0 4.0} {0.0 4.0}} -swarmsize 10 -iterations 50 -vweight 0.2 -pweight 0.1 -gweight 03 -type local -neighbours 4 -tolerance 1e-3] set result "OK" } -returnCodes {ok} -result "OK" test "PSO-0.2" "Check unknown options" -body { set coords_value [::math::probopt::pso f {{0.0 4.0} {0.0 4.0}} -UNKNOWN 10] set result "OK" } -returnCodes {error} -result "Unknown option: -UNKNOWN" test "PSO-0.3" "Check content of dictionary" -body { set coords_value [::math::probopt::pso f {{0.0 4.0} {0.0 4.0}}] foreach key {optimum-coordinates optimum-value evaluations best-values} { set r [dict get $coords_value $key] } set result "OK" } -returnCodes {ok} -result "OK" test "PSO-1.1" "Two-dimensional paraboloid" -match tolerant -setup setRand -body { set coords_value [::math::probopt::pso f {{0.0 4.0} {0.0 4.0}} -iterations 50] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {1.0 1.0 0.0} test "PSO-1.2" "Two-dimensional paraboloid - namespace" -match tolerant -setup setRand -body { global coords_value namespace eval testcase { global coords_value set coords_value [::math::probopt::pso ftest {{0.0 4.0} {0.0 4.0}} -iterations 50] } set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {1.0 1.0 0.0} test "PSO-2.1" "Tilted sombrero - 2D" -match tolerant -setup setRand -body { set coords_value [::math::probopt::pso sombrero {{-4.0 4.0} {-4.0 4.0}} -iterations 50] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {0.9784 0.2080 0.0} test "PSO-2.2" "Tilted sombrero - 2D, local method" -match tolerant -setup setRand -body { set coords_value [::math::probopt::pso sombrero {{-4.0 4.0} {-4.0 4.0}} -iterations 50 -type local] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {0.9605 0.2820 0.0} test "PSO-2.3" "Tilted sombrero - 2D, more particles" -match tolerant -setup setRand -body { set coords_value [::math::probopt::pso sombrero {{-4.0 4.0} {-4.0 4.0}} -iterations 50 -swarmsize 200] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {0.970 -0.2419 0.0} test "PSO-3.1" "Wavy function - 3D" -match tolerant -setup setRand -body { set coords_value [::math::probopt::pso wavy3d {{0.0 4.0} {0.0 4.0} {0.0 4.0}} -iterations 50] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {2.8405 1.9068 2.2180 0.2157} test "PSO-3.2" "Wavy function - 3D" -match tolerant -setup setRand -body { set coords_value [::math::probopt::pso wavy3d {{0.0 4.0} {0.0 4.0} {0.0 4.0}} -iterations 50 -swarmsize 100 -neighbours 6] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {1.5703 0.9424 1.2564 0.0493} test "PSO-4.1" "Discontinuous function - 2D" -match tolerant -setup setRand -body { set coords_value [::math::probopt::pso halfparabola {{-4.0 4.0} {-4.0 4.0}} -iterations 50] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {0.0 0.0 0.0} # # SCE # test "SCE-0.1" "Check known options" -body { set coords_value [::math::probopt::sce f {{0.0 4.0} {0.0 4.0}} -complexes 2 -mincomplexes 2 -newpoints 1 -shuffle 0 -pointspercomplex 0 -pointspersubcomplex 0 \ -iterations 100 -maxevaluations 1.0e9 -abstolerance 0.0 -reltolerance 0.001] set result "OK" } -returnCodes {ok} -result "OK" test "SCE-0.2" "Check unknown options" -body { set coords_value [::math::probopt::sce f {{0.0 4.0} {0.0 4.0}} -UNKNOWN 10] set result "OK" } -returnCodes {error} -result "Unknown option: -UNKNOWN" test "SCE-0.3" "Check content of dictionary" -body { set coords_value [::math::probopt::sce f {{0.0 4.0} {0.0 4.0}}] foreach key {optimum-coordinates optimum-value evaluations best-values} { set r [dict get $coords_value $key] } set result "OK" } -returnCodes {ok} -result "OK" test "SCE-1.1" "Two-dimensional paraboloid" -match tolerant -setup setRand -body { set coords_value [::math::probopt::sce f {{0.0 4.0} {0.0 4.0}} -iterations 50] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {1.0064 1.0082 0.0001078} # # DE # test "DE-0.1" "Check known options" -body { set coords_value [::math::probopt::diffev f {{0.0 4.0} {0.0 4.0}} -number 0 -factor 0.6 -lambda 0.0 -crossover 0.5 \ -iterations 100 -maxevaluations 1.0e9 -abstolerance 0.0 -reltolerance 0.001] set result "OK" } -returnCodes {ok} -result "OK" test "DE-0.2" "Check unknown options" -body { set coords_value [::math::probopt::diffev f {{0.0 4.0} {0.0 4.0}} -UNKNOWN 10] set result "OK" } -returnCodes {error} -result "Unknown option: -UNKNOWN" test "DE-0.3" "Check content of dictionary" -body { set coords_value [::math::probopt::diffev f {{0.0 4.0} {0.0 4.0}}] foreach key {optimum-coordinates optimum-value evaluations best-values} { set r [dict get $coords_value $key] } set result "OK" } -returnCodes {ok} -result "OK" test "DE-1.1" "Two-dimensional paraboloid" -match tolerant -setup setRand -body { set coords_value [::math::probopt::diffev f {{0.0 4.0} {0.0 4.0}} -iterations 50] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {1.0068 1.0096 0.0001387} # # LIPO # test "LIPO-0.1" "Check known options" -body { set coords_value [::math::probopt::lipoMax f {{0.0 4.0} {0.0 4.0}} -iterations 100 -lipschitz 10.0] set result "OK" } -returnCodes {ok} -result "OK" test "LIPO-0.2" "Check unknown options" -body { set coords_value [::math::probopt::lipoMax f {{0.0 4.0} {0.0 4.0}} -UNKNOWN 10] set result "OK" } -returnCodes {error} -result "Unknown option: -UNKNOWN" test "LIPO-0.3" "Check content of dictionary" -body { set coords_value [::math::probopt::lipoMax f {{0.0 4.0} {0.0 4.0}}] foreach key {optimum-coordinates optimum-value evaluations best-values} { set r [dict get $coords_value $key] } set result "OK" } -returnCodes {ok} -result "OK" test "LIPO-1.1" "Three-dimensional sombrero" -match tolerant -setup setRand -body { set coords_value [::math::probopt::lipoMax sombrero3D {{-1.2 1.2} {-1.2 1.2} {-1.2 1.2}} -iterations 5000] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {-0.0447 -0.0710 -0.0956 99.6769} test "ADALIPO-0.1" "Check known options" -body { set coords_value [::math::probopt::adaLipoMax f {{0.0 4.0} {0.0 4.0}} -iterations 100 -bernoulli 0.1] set result "OK" } -returnCodes {ok} -result "OK" test "ADALIPO-0.2" "Check unknown options" -body { set coords_value [::math::probopt::adaLipoMax f {{0.0 4.0} {0.0 4.0}} -UNKNOWN 10] set result "OK" } -returnCodes {error} -result "Unknown option: -UNKNOWN" test "ADALIPO-0.3" "Check content of dictionary" -body { set coords_value [::math::probopt::adaLipoMax f {{0.0 4.0} {0.0 4.0}}] foreach key {optimum-coordinates optimum-value evaluations best-values} { set r [dict get $coords_value $key] } set result "OK" } -returnCodes {ok} -result "OK" # Odd behaviour: 5000 iterations and the thing hangs? #test "ADALIPO-1.1" "Three-dimensional sombrero" -match tolerant -setup setRand -body { # set coords_value [::math::probopt::adaLipoMax sombrero3D {{-1.2 1.2} {-1.2 1.2} {-1.2 1.2}} -iterations 5000] # set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] #} -result {0.0 0.0 1.0} test "ADALIPO-1.1" "Three-dimensional sombrero" -match tolerant -setup setRand -body { set coords_value [::math::probopt::adaLipoMax sombrero3D {{-1.2 1.2} {-1.2 1.2} {-1.2 1.2}} -iterations 500] set result [concat [dict get $coords_value optimum-coordinates] [dict get $coords_value optimum-value]] } -result {-0.0971 -0.0577 0.1905 99.0216} #set coords_value [::math::probopt::pso halfparabola {{-4.0 4.0} {-4.0 4.0}} -iterations 50] #puts $coords_value