Version 1 of Vector arithmetics

Updated 2005-04-20 13:13:09 by escargo

if 0 {Richard Suchenwirth 2005-04-20 - APL and J (see Tacit programming) have the feature that arithmetics can be done with vectors and arrays as well as scalar numbers, in the varieties (for any operator @):

  • vector @ scalar -> vector
  • scalar @ vector -> vector
  • vector @ vector -> vector (same dimensions, element-wise)

Here's experiments how to do this in Tcl. First lmap is a collecting foreach - it maps the specified body over a list:}

 proc lmap {_var list body} {
     upvar 1 $_var var
     set res {}
     foreach var $list {lappend res [uplevel 1 $body]}
     set res
 }

#-- We need basic scalar operators from expr factored out:

 foreach op {+ - * /} {proc $op {a b} "expr {\$a $op \$b}"}

if 0 {This generic wrapper takes one binary operator (could be any suitable function) and two arguments, which may be scalars, vectors, or even matrices (lists of lists), as it recurses as often as needed. Note that as my lmap above only takes one list, the two-list case had to be made explicit with foreach. Jim users can use a multi-list lmap there for simplicity.}

 proc vec {op a b} {
     if {[llength $a] == 1 && [llength $b] == 1} {
         $op $a $b
     } elseif {[llength $a]==1} {
         lmap i $b {vec $op $a $i}
     } elseif {[llength $b]==1} {
         lmap i $a {vec $op $i $b}
     } elseif {[llength $a] == [llength $b]} {
         set res {}
         foreach i $a j $b {lappend res [vec $op $i $j]}
         set res
     } else {error "length mismatch [llength $a] != [llength $b]"}
 }

#-- Tests:

 proc e.g. {cmd -> expected} {
     catch $cmd res
     if {$res ne $expected} {puts "$cmd -> $res, not $expected"}
 }

#-- Scalar + Scalar

 e.g. {vec + 1 2} -> 3

#-- Scalar + Vector

 e.g. {vec + 1 {1 2 3 4}} -> {2 3 4 5}

#-- Vector / Scalar

 e.g. {vec / {1 2 3 4} 2.} -> {0.5 1.0 1.5 2.0}

#-- Scalar + Matrix (Isn't this Vector + Vector?)

 e.g. {vec + {1 2 3} {4 5 6}} -> {5 7 9}

#-- Matrix * Scalar

 e.g. {vec * {{1 2 3} {4 5 6}} 2} -> {{2 4 6} {8 10 12}}

#-- Multiplying a 3x3 matrix with another:

 e.g. {vec * {{1 2 3} {4 5 6} {7 8 9}} {{1 0 0} {0 1 0} {0 0 1}}} -> \
         {{1 0 0} {0 5 0} {0 0 9}}

if 0 {


Category Concept | Arts and crafts of Tcl-Tk programming }