Updated 2012-05-18 21:10:58 by RLE

Calculating determinants. Not really difficult, but sometimes helpful if there is some script where it is yet done.

See also Matrix determinant, for another implementation and a discussion of why row expansion is not an efficient algorithm for computing determinants.
``` #
# detVal determinant
# returns value of \$determinant
# where determinant has the form {{a b} {c d}}
# or {{a b c} {d e f} {g h i}}
# or {{a b c d} {e f g h} {i j k l} {m n o p}}
# ...
#
proc detVal determinant {
if {[llength \$determinant] == 1} then {
set determinant
} else {
set result 0
set sign 1
set i 0
foreach num [lindex \$determinant 0] {
set subDeterminant [subDet \$determinant \$i]
set subDetVal [detVal \$subDeterminant]
set sign [expr {- \$sign}]
set result [expr {\$result + \$num * \$subDetVal * \$sign}]
incr i
}
set result
}
}

#
# subDet determinant n
# returns \${n}th subdeterminant of \$determinant
# e.g. subDet {{a b} {c d}} 0 => d
# or subDet {{a b} {c d}} 1 => c
# or subDet {{a b c} {d e f} {g h i}} 1 => {{d f} {g i}}
# ...
#
proc subDet {determinant n} {
set result {}
foreach oldRow [lrange \$determinant 1 end] {
set newRow {}
set i 0
foreach num \$oldRow {
if {\$i != \$n} then {
lappend newRow \$num
}
incr i
}
lappend result \$newRow
}
set result
}

#
# detColSet determinant colNum col
# returns copy of \$determinant where \${colNum}th col
# is replaced with \$col
#
proc detColSet {determinant colNum col} {
set i 0
foreach num \$col {
lset determinant \$i \$colNum \$num
incr i
}
set determinant
}

# debug
if true {
#
# vertical cmd ...
# aligns result of [cmd ...] vertically
# e.g.
# % vertical subDet \$det1 0
# 11 9
# 50 1
#
proc vertical args {
join [eval \$args] \n
}

set det0 {
{2 3}
{9 10}
}

set det1 {
{2 3 5}
{12 11 9}
{30 50 1}
}
}```