summaryrefslogtreecommitdiffstats
path: root/tcllib/modules/math/symdiff.test
diff options
context:
space:
mode:
Diffstat (limited to 'tcllib/modules/math/symdiff.test')
-rw-r--r--tcllib/modules/math/symdiff.test458
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: