diff options
Diffstat (limited to 'tcllib/modules/math/symdiff.test')
-rw-r--r-- | tcllib/modules/math/symdiff.test | 458 |
1 files changed, 458 insertions, 0 deletions
diff --git a/tcllib/modules/math/symdiff.test b/tcllib/modules/math/symdiff.test new file mode 100644 index 0000000..bf35cb8 --- /dev/null +++ b/tcllib/modules/math/symdiff.test @@ -0,0 +1,458 @@ +# symdiff.test -- +# +# Test cases for the 'symdiff' package +# +# This file contains a collection of tests for one or more of the Tcllib +# procedures. Sourcing this file into Tcl runs the tests and +# generates output for errors. No output means no errors were found. +# +# Copyright (c) 2005 by Kevin B. Kenny +# All rights reserved. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: symdiff.test,v 1.2 2011/01/13 02:49:53 andreas_kupries Exp $ + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.5 +testsNeedTcltest 2.1 + +support { + use grammar_aycock/aycock-runtime.tcl grammar::aycock::runtime grammar::aycock + useKeep grammar_aycock/aycock-debug.tcl grammar::aycock::debug grammar::aycock + useKeep grammar_aycock/aycock-build.tcl grammar::aycock grammar::aycock +} +testing { + useLocal symdiff.tcl math::calculus::symdiff +} + +# ------------------------------------------------------------------------- + +namespace eval ::math::calculus::symdiff::test { + +namespace import ::tcltest::test +namespace import ::tcltest::cleanupTests +namespace import ::math::calculus::symdiff::* + +set prec $::tcl_precision +if {![package vsatisfies [package provide Tcl] 8.5]} { + set ::tcl_precision 17 +} else { + set ::tcl_precision 0 +} + +test symdiff-1.1 {derivative of a constant} { + symdiff {1.0} a +} 0.0 + +test symdiff-2.1 {derivative of a variable} { + symdiff {$a} a +} 1.0 + +test symdiff-2.2 {derivative of a variable} { + symdiff {$b} a +} 0.0 + +test symdiff-3.1 {derivative of a sum, easy cases} { + symdiff {1.0 + 1.0} a +} 0.0 + +test symdiff-3.2 {derivative of a sum, easy cases} { + symdiff {1.0 + $a} a +} 1.0 + +test symdiff-3.3 {derivative of a sum, easy cases} { + symdiff {$a + 1.0} a +} 1.0 + +test symdiff-3.4 {derivative of a sum, easy cases} { + symdiff {$a + $a} a +} 2.0 + +test symdiff-3.5 {derivative of a sum, easy cases} { + symdiff {$a + $b} a +} 1.0 + +test symdiff-3.6 {derivative of a sum, easy cases} { + symdiff {$a + $a + $a} a +} 3.0 + +test symdiff-4.1 {derivative of a difference, easy cases} { + -body { + symdiff {1.0 - 1.0} a + } + -match regexp + -result {[-+]?0.0} +} + +test symdiff-4.2 {derivative of a difference, easy cases} { + symdiff {1.0 - $a} a +} -1.0 + +test symdiff-4.3 {derivative of a difference, easy cases} { + symdiff {$a - 1.0} a +} 1.0 + +test symdiff-4.4 {derivative of a difference, easy cases} { + symdiff {$a - $a} a +} 0.0 + +test symdiff-4.5 {derivative of a difference, easy cases} { + symdiff {$a + $b} a +} 1.0 + +test symdiff-4.6 {derivative of a difference, easy cases} { + symdiff {$a + $a - $a} a +} 1.0 + +test symdiff-5.1 {derivative of a product, easy cases} { + symdiff {1.0 * 1.0} a +} 0.0 + +test symdiff-5.2 {derivative of a product, easy cases} { + symdiff {3.0 * $a} a +} 3.0 + +test symdiff-5.3 {derivative of a product, easy cases} { + symdiff {$a * 3.0} a +} 3.0 + +test symdiff-5.4 {derivative of a product, easy cases} { + symdiff {$a * $a} a +} {($a + $a)} + +test symdiff-5.5 {derivative of a product, easy cases} { + symdiff {$a * $b} a +} {$b} + +test symdiff-5.6 {derivative of a product, easy cases} { + symdiff {($a + $b) * ($a + $b)} a +} {(($a + $b) + ($a + $b))} + +test symdiff-5.7 {derivative of a linear function} { + symdiff {$a*$x + $b} x +} {$a} + +test symdiff-6.1 {derivative of a sum} { + symdiff {($a*$x+$b)+($c*$x+$d)} x +} {($a + $c)} + +test symdiff-7.1 {derivative of a difference} { + symdiff {($a*$x+$b)-($c*$x+$d)} x +} {($a - $c)} + +test symdiff-8.1 {derivative of a product} { + symdiff {($a*$x+$b)*($c*$x+$d)} x +} {(($c * (($a * $x) + $b)) + ($a * (($c * $x) + $d)))} + +test symdiff-9.1 {derivative of a quotient} { + symdiff {$x/1.0} x +} 1.0 + +test symdiff-9.2 {derivative of a quotient} { + symdiff {$x/-1.0} x +} -1.0 + +test symdiff-9.3 {derivative of a quotient} { + symdiff {1.0/$x} x +} {-(((1.0 / $x) / $x))} + +test symdiff-9.4 {derivative of a quotient} { + symdiff {($a*$x+$b)/($c*$x+$d)} x +} {(($a - (($c * (($a * $x) + $b)) / (($c * $x) + $d))) / (($c * $x) + $d))} + +test symdiff-10.1 {derivative of an exponent} { + symdiff {pow($a*$x+$b,3.5)} x +} {($a * (3.5 * pow((($a * $x) + $b), 2.5)))} + +test symdiff-10.2 {derivative of an exponent, slightly harder case} { + -body { + symdiff {pow(10.0,$x)} x + } + -match regexp + -result {\(pow\(10.0, \$x\) \* 2.30258509299404(?:59|6)\)} +} + +test symdiff-10.3 {derivative of an exponent, awkward case} { + symdiff {pow($a*$x+$b,$c*$x+$d)} x +} {(pow((($a * $x) + $b), (($c * $x) + $d)) * ((($a * (($c * $x) + $d)) / (($a * $x) + $b)) + ($c * log((($a * $x) + $b)))))} + +test symdiff-11.1 {derivative of a unary negation} { + symdiff {-($a*$x + $b)} x +} {-($a)} + +test symdiff-11.2 {derivative of a unary plus} { + symdiff {+($a*$x + $b)} x +} {$a} + +test symdiff-12.1 {derivative of acos} { + symdiff {acos($x)} x +} {(-1.0 / sqrt((1.0 - ($x * $x))))} + +test symdiff-12.2 {derivative of acos} { + symdiff {acos($a*$x+$b)} x +} {-(($a / sqrt((1.0 - ((($a * $x) + $b) * (($a * $x) + $b))))))} + +test symdiff-13.1 {derivative of acos} { + symdiff {asin($x)} x +} {(1.0 / sqrt((1.0 - ($x * $x))))} + +test symdiff-13.2 {derivative of asin} { + symdiff {asin($a*$x+$b)} x +} {($a / sqrt((1.0 - ((($a * $x) + $b) * (($a * $x) + $b)))))} + +test symdiff-14.1 {derivative of atan} { + symdiff {atan($x)} x +} {(1.0 / (1.0 + ($x * $x)))} + +test symdiff-14.2 {derivative of atan} { + symdiff {atan($a*$x+$b)} x +} {($a / (1.0 + ((($a * $x) + $b) * (($a * $x) + $b))))} + +test symdiff-15.1 {derivative of atan2} { + symdiff {atan2($x,1.0)} x +} {(1.0 / (($x * $x) + 1.0))} + +test symdiff-15.2 {derivative of atan2} { + symdiff {atan2(1.0,$x)} x +} {(-1.0 / (1.0 + ($x * $x)))} + +test symdiff-15.3 {derivative of atan2} { + symdiff {atan2($x,$y)} x +} {($y / (($x * $x) + ($y * $y)))} + +test symdiff-15.4 {derivative of atan2} { + symdiff {atan2($y,$x)} x +} {-(($y / (($y * $y) + ($x * $x))))} + +test symdiff-15.5 {derivative of atan2} { + symdiff {atan2($a*$x+$b,$c*$x+$d)} x +} {((($a * (($c * $x) + $d)) - ((($a * $x) + $b) * $c)) / (((($a * $x) + $b) * (($a * $x) + $b)) + ((($c * $x) + $d) * (($c * $x) + $d))))} + +test symdiff-16.1 {derivative of cos} { + symdiff {cos($x)} x +} {-(sin($x))} + +test symdiff-16.2 {derivative of cos} { + symdiff {cos($a*$x + $b)} x +} {-(($a * sin((($a * $x) + $b))))} + +test symdiff-17.1 {derivative of cosh} { + symdiff {cosh($x)} x +} {sinh($x)} + +test symdiff-17.2 {derivative of cosh} { + symdiff {cosh($a*$x + $b)} x +} {($a * sinh((($a * $x) + $b)))} + +test symdiff-18.1 {derivative of exp} { + symdiff {exp($x)} x +} {exp($x)} + +test symdiff-18.2 {derivative of exp} { + symdiff {exp($a*$x+$b)} x +} {($a * exp((($a * $x) + $b)))} + +test symdiff-19.1 {derivative of hypot} { + symdiff {hypot(0.0,$a)} a +} {($a / hypot(0.0, $a))} + +test symdiff-19.2 {derivative of hypot} { + symdiff {hypot($b,$a)} a +} {($a / hypot($b, $a))} + +test symdiff-19.3 {derivative of hypot} { + symdiff {hypot($a*$x+$b,$c*$x+$d)} x +} {((($a * (($a * $x) + $b)) + ($c * (($c * $x) + $d))) / hypot((($a * $x) + $b), (($c * $x) + $d)))} + +test symdiff-20.1 {derivative of log} { + symdiff {log($x)} x +} {(1.0 / $x)} + +test symdiff-20.2 {derivative of log} { + symdiff {log($a*$x+$b)} x +} {($a / (($a * $x) + $b))} + +test symdiff-21.1 {derivative of log10} { + -body { + symdiff {log10($x)} x + } + -match regexp + -result {\(1.0 / \(2.30258509299404(?:59|6) \* \$x\)\)} +} + +test symdiff-21.2 {derivative of log10} { + -body { + symdiff {log10($a * $x + $b)} x + } + -match regexp + -result {\(\$a / \(2.30258509299404(?:59|6) \* \(\(\$a \* \$x\) \+ \$b\)\)\)} +} + +test symdiff-22.1 {derivative of sin} { + symdiff {sin($x)} x +} {cos($x)} + +test symdiff-22.2 {derivative of sin} { + symdiff {sin($a*$x+$b)} x +} {($a * cos((($a * $x) + $b)))} + +test symdiff-22.1 {derivative of sinh} { + symdiff {sinh($x)} x +} {cosh($x)} + +test symdiff-22.2 {derivative of sinh} { + symdiff {sinh($a*$x+$b)} x +} {($a * cosh((($a * $x) + $b)))} + +test symdiff-23.1 {derivative of sqrt} { + symdiff {sqrt($x)} x +} {(1.0 / (2.0 * sqrt($x)))} + +test symdiff-23.2 {derivative of sqrt} { + symdiff {sqrt($a*$x+$b)} x +} {($a / (2.0 * sqrt((($a * $x) + $b))))} + +test symdiff-24.1 {derivative of tan} { + symdiff {tan($x)} x +} {(1.0 / (cos($x) * cos($x)))} + +test symdiff-24.2 {derivative of tan} { + symdiff {tan($a*$x+$b)} x +} {($a / (cos((($a * $x) + $b)) * cos((($a * $x) + $b))))} + +test symdiff-24.1 {derivative of tanh} { + symdiff {tanh($x)} x +} {(1.0 / (cosh($x) * cosh($x)))} + +test symdiff-24.2 {derivative of tanh} { + symdiff {tanh($a*$x+$b)} x +} {($a / (cosh((($a * $x) + $b)) * cosh((($a * $x) + $b))))} + +test symdiff-25.1 {error handling} { + -body { + symdiff {[foo $x]} x + } + -match glob + -returnCodes error + -result {invalid character*} +} + +test symdiff-25.2 {error handling} { + -body { + symdiff {$x(1)} x + } + -match glob + -returnCodes error + -result {syntax error*} +} + +test symdiff-25.3 {error handling} { + -body { + symdiff {$a & $b} a + } + -match glob + -returnCodes error + -result {invalid character*} +} + +test symdiff-25.4 {error handling} { + list [catch {symdiff {int($a)} a} result] $result +} {1 {symdiff can't differentiate the "int" function}} + +test symdiff-25.5 {error handling} { + -body { + symdiff {$a ? $b : $c} a + } + -returnCodes error + -match glob + -result {invalid character*} +} + +test symdiff-26.1 {unary minus optimization} { + symdiff {$a * $x + -$b * $x} x +} {($a - $b)} + +test symdiff-26.2 {unary minus optimization} { + symdiff {-$a * $x - $b * $x} x +} {-(($a + $b))} + +test symdiff-26.3 {unary minus optimization} { + symdiff {$a * $x - -$b * $x} x +} {($a + $b)} + +test symdiff-26.4 {unary minus optimization} { + symdiff {-$a * $x * $b} x +} {-(($a * $b))} + +test symdiff-26.5 {unary minus optimization} { + symdiff {$a * $x * -$b} x +} {-(($a * $b))} + +test symdiff-26.6 {unary minus optimization} { + symdiff {---($a*$x+$b)} x +} {-($a)} + +test symdiff-26.7 {unary minus optimization} { + symdiff {-$x * $x} x +} {-(($x + $x))} + +test symdiff-27.1 {power optimizations} { + symdiff {pow($x,1)} x +} 1.0 + +test symdiff-27.2 {power optimizations} { + symdiff {pow($x,2.0)} x +} {(2.0 * $x)} + +test symdiff-28.1 {quotient optimization} { + symdiff {($x * $x) / 1.0} x +} {($x + $x)} + +test symdiff-28.2 {quotient optimization} { + symdiff {($x * $x) / -1.0} x +} {-(($x + $x))} + +test symdiff-28.3 {quotient optimization - error case} { + list [catch {symdiff {($x * $x) / 0.0} x} result] $result +} {1 {requested expression will result in division by zero at run time}} + +test symdiff-29.1 {product optimization} { + symdiff {(2. * $x) * 3.0} x +} 6.0 + +test symdiff-29.2 {product optimization} { + symdiff {($a * $x) * -1.0} x +} {-($a)} + +test symdiff-30.0 {illustration of Newton's method - find a root of sin(x)-0.5 near 0.5} { + proc root {expr var guess} { + upvar 1 $var v + set deriv [symdiff $expr $var] + set v $guess + set updateExpr [list expr "\$$var - ($expr) / ($deriv)"] + for { set i 0 } { $i < 4 } { incr i } { + set v [uplevel 1 $updateExpr] + } + return $v + } + set r [root {sin($x)-0.5} x 0.5] + expr {sin($r)} +} 0.5 + +# End of test cases +set ::tcl_precision $prec +cleanupTests +} + +namespace delete ::math::calculus::symdiff::test + +# Local Variables: +# mode: tcl +# End: |