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}
}
}