Arjen Markus (8 may 2007) Some examples of Maple [L1 ] code inspired me to consider the procedures below. The idea is simple: Suppose you want to compute a series:
n i i f(x) = Sum (-1) x /(i+1)**2 i=0
You could write a procedure like this:
proc f {x n} { set sum 0.0 for { set i 0 } { $i <= $n } { incr i } { set sum [expr {$sum + pow(-$x,$i)/(($i+1)*($i+1))}] } return $sum }
but in a mathematical application like Maple, it makes more sense to provide a command that takes care of the details:
f = series(n, i->(-x)^i/i^2);
(or something similar, I am not familiar with Maple, just saw some code fragments in an article)
The question arises: can we do that in Tcl too?
Well, that is easy (except for a few nasty details, as using a private namespace and a local variable with an uncommon name):
namespace eval ::Maple { variable count 0 namespace eval v { } } # series -- # Define a new function that evaluates a series # # Arguments: # var Names of the variables that holds the arguments # number number of terms # idx Index variable # expression Expression defining the terms # # Result: # Name of a new procedure # proc ::Maple::series {var number idx expression} { variable count set procname ::Maple::v::series_$count incr count set numbern [lindex $number 0] puts "numbern =$numbern" proc $procname [list $var $number] [string map \ [list VAR $var IDX $idx NUMBER $numbern EXPR $expression] { set _sum_ 0.0 for { set IDX 0 } { $IDX <= $NUMBER } { incr IDX } { set _sum_ [expr {$_sum_ + EXPR}] } return $_sum_ }] return $procname }
Now let us try it:
# # The direct definition # proc fdir {x {n 100}} { set sum 0.0 for { set i 0 } { $i <= $n } { incr i } { set sum [expr {$sum + pow(-$x,$i)/(($i+1)*($i+1))}] } return $sum } set f [::Maple::series x {n 100} i {pow(-$x,$i)/(($i+1)*($i+1))}] set x 0.0 while { $x < 0.99 } { puts "$x: [$f $x] - [fdir $x]" set x [expr {$x + 0.05}] }
I leave it as an exercise to expand this little package to other mathematical objects, such as matrices, vectors or definite integrals