Tensor

A tensor in mathematics is a generalisation of vectors and matrices, where the number of indices can be any natural number (as opposed to 1 for vectors and 2 for matrices). The name comes from tension, since the need for these first arose in the study of complex stresses, but they are probably most prominently seen in differential geometry.

AM (22 october) From my student days I remember a lecture on the transformation of the anisotropic properties of certain solids due to elastic forces that required the use of a fourth-order tensor, as the properties themselves were a matrix in three dimensions. That sort of things involve 81 coefficients (3**4) but luckily there are all manner of requirements with respect to one another, so that the number of independent coefficients is much smaller.

Tensors also seem to figure prominently in general relativity theory (yes, differential geometry), but fortunately I have never been involved in that.


Tensor is also the name of a package by Neil McKay [L1 ]. Conference paper: [L2 ] (PS). [Please provide more links to code and documentation, fill in details, etc.]

See also:


AM (15 june 2009) Here is a small script to determine the distribution of data stored in a one-dimensional tensor. Nothing revolutionary, but it shows that the package can be used for more than arcane mathematical manipulations:

# bins.tcl --
#     Show how to use the Tensor package to do some simple 
#     data analysis
#

package require Tensor

# determineBins --
#     Estimate the data distribution via a histogram approach
# 
# Arguments:
#     data             Tensor containing the data
#     bounds           List of bounds for the bins
#
# Result:
#     Counts of values falling in a bin
#
proc determineBins {data bounds} {
    
    set oldbin 0

    ::tensor::create check -size [data dimensions]
    ::tensor::create count -size 1


    set counts {}

    foreach bound $bounds {
        check = boolean $data <= scalar $bound
        count = contraction check 0

        set newbin [count]
        lappend counts [expr {$newbin-$oldbin}]
        set oldbin $newbin
    }

    rename check {}
    rename count {}

    set rest [expr [data dimensions]-([join $counts +])]
    lappend counts $rest
    return $counts
}

# main --
#     Fill a tensor with data and determine the bins
#
::tensor::create data -size 10000

for {set i 0} {$i < 10000} {incr i} {
    set x [expr {($i/10000.0)}]
    data section $i = scalar $x
}

set bins [list 0.0 0.1 0.2 0.3 0.4]

set counts [determineBins data $bins]

foreach c [lrange $counts 0 end-1] b $bins {
    puts "<= $b: $c"
}
 
puts " > $b: [lindex $counts end]"

The result:

<= 0.0: 1.0
<= 0.1: 1000.0
<= 0.2: 1000.0
<= 0.3: 1000.0
<= 0.4: 1000.0
 > 0.4: 5999.0

which is as it should be.


AM (25 june 2009) Yet another small experiment: compute the moving average of a timeseries (a very artificial series, but that does not really matter):

# movingaverage.tcl --
#     Compute a moving average computation with the tensor package
#

package require Tensor

::tensor::create a -initial {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20}
::tensor::create b -size 20

foreach start {0 1 2 3 4} {
    set end [expr {$start + 15}]
    ::tensor::expr "b(i=0:15) = b(i=0:15) + a(i=$start:$end)"
}
b /= scalar 5.0

puts "Original series: [a]"
puts "Moving average (5 points window): [b]" 

AMB - 2023-10-18 19:49:41

The package ndlist uses nested Tcl lists to represent tensors.