## Version 0 of Operations on series of numerical data

Updated 2014-03-31 10:10:20 by arjen

Arjen Markus (31 march 2014) This may be the start of a new package, one to manipulate series of numerical data at a high level in pure Tcl. The code below is a humble experiment. Of course for large amounts of data it would be better to have a compiled extension and there are certainly packages around or in development that can/will do that, but it is also attractive to have a Tcl-only package.

```# series.tcl --
#      First attempt at creating a package to handle series of numerical data
#
namespace eval ::math::series {
}

# mexpr --
#     Evaluate an expression with lists (series) of data
#
# Arguments:
#     expression       String valid as a Tcl expression
#
# Returns:
#     List of the results of the expression evaluated with subsequent values
#
# Note:
#     Array elements \$x(\$y) in these expressions do not yet work properly!
#     Also avoid variables whose name has the form "__...___"
#
#     The current implementation may not be very efficient, because of
#     the expression being reparsed each iteration.
#
proc ::math::series::mexpr {expression} {

#
# Extract the variable names
#
set vars [lsort -unique [regexp -all -inline {\\$[A-Za-z_]+} \$expression]]

set forvars {}
foreach v \$vars {
set v [string range \$v 1 end]
upvar 1 \$v __\${v}__
if { [llength [set __\${v}__]] > 1 } {
lappend forvars \$v [set __\${v}__]
} else {
set \$v [set __\${v}__]
}
}

#
# Evaluate the expression via the list variables
#
if { [llength \$forvars] > 0 } {
set __result__ {}
foreach {*}\$forvars {
lappend __result__ [expr \$expression]
}
} else {
set __result__ [expr \$expression]
}

return \$__result__
}

#
# procedure to compare the performance
#
proc test_expr {xlist ylist} {
foreach x \$xlist y \$ylist {
lappend result [expr {\$x+\$y}]
}
return \$result
}

#
# Simple test
#
set x {1 2 3 4 5 6 7 8 9}
set y {2 3 4 5 6 7 8 9 10}
set z 1

puts [::math::series::mexpr {\$x+\$y}]
puts [::math::series::mexpr {\$x+\$z}]
puts [test_expr \$x \$y]
puts [::math::series::mexpr {1+2}]

set x {}
set y {}
for {set i 0} {\$i < 1000} {incr i} {
lappend x \$i
lappend y \$i
}

# Hm, mexpr is about 4 times as slow as test_expr
puts "Time for mexpr:     [time {::math::series::mexpr {\$x+\$y}} 1000]"
puts "Time for test_expr: [time {test_expr \$x \$y} 1000]"

```

 Category Mathematics Category Numerical Analysis