#proc det matrix { def det(matrix): #if {[llength $matrix] != [llength [lindex $matrix 0]]} { if matrix.len()[0] != matrix.len()[1]: #error "non-square matrix" raise SizeError, "non-square matrix" #} #switch [llength $matrix] { # 2 { if matrix.len()[0] == 2: #foreach {a b c d} [join $matrix] break a,b,c,d = matrix[0,0], matrix[0,1], matrix[1,0], matrix[1,1] #expr {$a*$d - $b*$c} return a*d - b*c # } default { else: #set i 0 i = 0 #set mat2 [lrange $matrix 1 end] mat2 = matrix[1:,...] #set res 0 res = 0 #foreach element [lindex $matrix 0] { for element in matrix[0] #if $element { if element: #set sign [expr {$i%2? -1: 1}] if i%2: sign = -1 else: sign = 1 #set res [expr {$res + $sign*$element* [det [cancelcol $i $mat2]]}] res += sign * element * det(cancelcol(i, mat2)) #} #incr i i += 1 #} #set res return res # } #} #} #proc cancelcol {n matrix} { def cancelcol(n, matrix) #set res {} res = [] #foreach row $matrix { for row in matrix.rows: #lappend res [lreplace $row $n $n] res += [row[n]] #} #set res return res #}