Arjen Markus (8 may 2007) Some examples of Maple [
1] 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