# -*- tcl -*- # optimize.test -- # Test cases for the ::math::optimize package # # Note: # By evaluating the tests in a different namespace than global, # we assure that the namespace issue (Bug #...) is checked. # if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } source [file join [file dirname [info script]] optimize.tcl] puts "math::optimize [package present math::optimize]" namespace eval optimizetest { #package require math::optimize namespace import ::math::optimize::* # # Simple test functions # proc const_func { x } { return 1.0 } proc ffunc { x } { expr {$x*(1.0-$x*$x)} } proc minfunc { x } { expr {-$x*(1.0-$x*$x)} } proc absfunc { x } { expr {abs($x*(1.0-$x*$x))} } proc within_range { result min max } { #puts "Within range? $result $min $max" #puts "[expr {2.0*abs($result-$min)/abs($max+$min)}]" if { $result >= $min && $result <= $max } { set ok 1 } else { set ok 0 } return $ok } # # Test the minimum procedure # # Note about the uneven and even functions: # the initial interval is chosen symmetrical, so that the # three function values are equal. # test "Minimum-1.0" "Minimum of constant function" { set result [minimum -1.0 1.0 ::optimizetest::const_func] within_range $result -1.0 1.0 } 1 # # To do: find out why this case fails # test "Minimum-2.0" "Minimum of odd function, case 1" { set result [minimum -1.0 1.0 ::optimizetest::ffunc] set xmin [expr {-sqrt(1.0/3.0)-0.0001}] set xmax [expr {-sqrt(1.0/3.0)+0.0001}] within_range $result $xmin $xmax } 1 test "Minimum-2.1" "Minimum of odd function, asymmetric interval" { set result [minimum -0.8 1.2 ::optimizetest::ffunc] set xmin [expr {-sqrt(1.0/3.0)-0.0001}] set xmax [expr {-sqrt(1.0/3.0)+0.0001}] within_range $result $xmin $xmax } 1 test "Minimum-2.2" "Minimum of odd function, case 2" { set result [minimum -1.0 1.0 ::optimizetest::minfunc] set xmin [expr {sqrt(1.0/3.0)-0.0001}] set xmax [expr {sqrt(1.0/3.0)+0.0001}] within_range $result $xmin $xmax } 1 test "Minimum-2.3" "Minimum of even function" { set result [minimum -1.0 1.0 ::optimizetest::absfunc] set xmin -0.0001 set xmax 0.0001 within_range $result $xmin $xmax } 1 # # Test the maximum procedure # # Note about the uneven and even functions: # the initial interval is chosen symmetrical, so that the # three function values are equal. # test "Maximum-1.0" "Maximum of constant function" { set result [maximum -1.0 1.0 ::optimizetest::const_func] within_range $result -1.0 1.0 } 1 test "Maximum-2.0" "Maximum of odd function, case 1" { set result [maximum -1.0 1.0 ::optimizetest::ffunc] set xmin [expr {sqrt(1.0/3.0)-0.0001}] set xmax [expr {sqrt(1.0/3.0)+0.0001}] within_range $result $xmin $xmax } 1 test "Maximum-2.1" "Maximum of odd function, case 2" { set result [maximum -1.0 1.0 ::optimizetest::minfunc] set xmin [expr {-sqrt(1.0/3.0)-0.0001}] set xmax [expr {-sqrt(1.0/3.0)+0.0001}] within_range $result $xmin $xmax } 1 # # Either of the two maxima will do # test "Maximum-2.2" "Maximum of even function" { set result [maximum -1.0 1.0 ::optimizetest::absfunc] set xmin [expr {-sqrt(1.0/3.0)-0.0001}] set xmax [expr {-sqrt(1.0/3.0)+0.0001}] set ok [within_range $result $xmin $xmax] set xmin [expr {sqrt(1.0/3.0)-0.0001}] set xmax [expr {sqrt(1.0/3.0)+0.0001}] incr ok [within_range $result $xmin $xmax] } 1 # # Test the solveLinearProgram procedure # - not implemented yet # if { 0 } { set symm_constraints { { 1.0 2.0 1.0 } { 2.0 1.0 1.0 } } test "LinearProg-1.0" "Symmetric constraints, case 1" { set result [solveLinearProgram $::symm_constraints {1.0 1.0}] set ok 1 if { ! [within_range [lindex $result 0] 0.333300 0.333360] || ! [within_range [lindex $result 1] 0.333300 0.333360] } { set ok 0 } set ok } 1 test "LinearProg-1.1" "Symmetric constraints, case 2" { set result [solveLinearProgram $::symm_constraints {1.0 0.0}] set ok 1 if { ! [within_range [lindex $result 0] 0.999900 1.000100] || ! [within_range [lindex $result 1] -0.000100 0.000100] } { set ok 0 } set ok } 1 test "LinearProg-1.2" "Symmetric constraints, case 3" { set result [solveLinearProgram $::symm_constraints {0.0 1.0}] set ok 1 if { ! [within_range [lindex $result 1] 0.999900 1.000100] || ! [within_range [lindex $result 0] -0.000100 0.000100] } { set ok 0 } set ok } 1 test "LinearProg-1.3" "Symmetric constraints, case 4" { set result [solveLinearProgram $::symm_constraints {3.0 4.0}] set ok 1 if { ! [within_range [lindex $result 0] 0.333300 0.333360] || ! [within_range [lindex $result 1] 0.333300 0.333360] } { set ok 0 } set ok } 1 test "LinearProg-2.1" "Unbounded program" { set result [solveLinearProgram {{1.0 -2.0 1.0} {-2.0 1.0 1.0}} {3.0 4.0}] } "unbounded" test "LinearProg-2.2" "Infeasible program" { set result [solveLinearProgram {{1.0 0.0 2.0} {1.0 1.0 1.0}} {1.0 1.0}] } "infeasible" test "LinearProg-3.1" "Simple 3D program" { set result [solveLinearProgram \ {{1.0 1.0 2.0 1.0} {1.0 2.0 1.0 1.0} {2.0 1.0 1.0 1.0}} {1.0 1.0 1.0}] set ok 1 if { ! [within_range [lindex $result 0] 0.249900 0.250100] || ! [within_range [lindex $result 1] 0.249900 0.250100] || ! [within_range [lindex $result 2] 0.249900 0.250100] } { set ok 0 } set ok } 1 test "LinearProg-3.2" "Redundant constraints" { set result [solveLinearProgram \ {{1.0 0.0 10.0} {0.0 1.0 10.0} {-1.0 -2.0 -1.0} {-1.0 -1.0 -1.0}} {1.0 1.0}] set ok 1 # Expected answer? #if { ! [within_range [lindex $result 0] 0.249900 0.250100] || # ! [within_range [lindex $result 1] 0.249900 0.250100] } { # set ok 0 #} set ok } 1 } ;# End of if 0 } ;# End of optimizetest namespace