# calculus.test -- # Test cases for the Calculus package # package require tcltest source [file join [pwd] [file dirname [info script]] calculus.tcl] puts "math::calculus [package present math::calculus]" package require log log::lvSuppress notice namespace eval ::math::calculus::test { namespace import ::tcltest::test namespace import ::tcltest::cleanupTests namespace import ::math::calculus::* # # Simple test functions - exact result predictable! # proc const_func { x } { return 1 } proc linear_func { x } { return $x } proc downward_linear { x } { return [expr {100.0-$x}] } # # Test the Integral proc # test "Integral-1.0" "Integral of constant function" { integral 0 100 100 const_func } 100.0 test "Integral-1.1" "Integral of linear function" { integral 0 100 100 linear_func } 5000.0 test "Integral-1.2" "Integral of downward linear function" { integral 0 100 100 downward_linear } 5000.0 test "Integral-1.3" "Integral of expression" { integralExpr 0 100 100 {100.0-$x} } 5000.0 proc const_func2d { x y } { return 1 } proc linear_func2d { x y } { return $x } test "Integral2D-1.0" "Integral of constant 2D function" { integral2D { 0 100 10 } { 0 50 1 } const_func2d } 5000.0 test "Integral2D-1.1" "Integral of constant 2D function (different step)" { integral2D { 0 100 1 } { 0 50 1 } const_func2d } 5000.0 test "Integral2D-1.2" "Integral of linear 2D function" { integral2D { 0 100 10 } { 0 50 1 } linear_func2d } 250000.0 # # Note: # Test cases for integral3D are missing! # # # Test cases: yet to be brought into the tcltest form! # # xvec should one long! proc const_func { t xvec } { return 1.0 } # xvec should be two long! proc dampened_oscillator { t xvec } { set x [lindex $xvec 0] set x1 [lindex $xvec 1] return [list $x1 [expr {-$x1-$x}]] } foreach method {eulerStep heunStep rungeKuttaStep} { log::log notice "Method: $method" set xvec 0.0 set t 0.0 set tstep 1.0 for { set i 0 } { $i < 10 } { incr i } { set result [$method $t $tstep $xvec const_func] log::log notice "Result ($t): $result" set t [expr {$t+$tstep}] set xvec $result } set xvec { 1.0 0.0 } set t 0.0 set tstep 0.1 for { set i 0 } { $i < 20 } { incr i } { set result [$method $t $tstep $xvec dampened_oscillator] log::log notice "Result ($t): $result" set t [expr {$t+$tstep}] set xvec $result } } # # Boundary value problems: # proc coeffs { x } { return {1.0 0.0 0.0} } proc forces { x } { return 0.0 } log::log notice [boundaryValueSecondOrder coeffs forces {0.0 1.0} {100.0 0.0} 10] log::log notice [boundaryValueSecondOrder coeffs forces {0.0 0.0} {100.0 1.0} 10] # # Determining the root of an equation # use simple functions # proc func { x } { expr {$x*$x-1.0} } proc deriv { x } { expr {2.0*$x} } test "NewtonRaphson-1.0" "Result should be 1" { set result [newtonRaphson func deriv 2.0] if { abs($result-1.0) < 0.0001 } { set answer 1 } } 1 test "NewtonRaphson-1.1" "Result should be -1" { set result [newtonRaphson func deriv -0.5] if { abs($result+1.0) < 0.0001 } { set answer 1 } } 1 proc func2 { x } { expr {$x*exp($x)-1.0} } proc deriv2 { x } { expr {exp($x)+$x*exp($x)} } test "NewtonRaphson-2.1" "Result should be nearly 0.56714" { set result [newtonRaphson func2 deriv2 2.0] if { abs($result-0.56714) < 0.0001 } { set answer 1 } } 1 test "NewtonRaphson-2.1" "Result should be nearly 0.56714" { set result [newtonRaphson func2 deriv2 -0.5] if { abs($result-0.56714) < 0.0001 } { set answer 1 } } 1 cleanupTests } namespace delete ::math::calculus::test