I'm finding difficulty in coding for inverse of a 3x3 matrix in tcl. do we really need packages to code for matrix , i need clear explanation for the following parts with minimal simpler coding 1.how to create matrix ? 2.how to find determinant? 3.how to find inverse of it ?
Asked
Active
Viewed 221 times
1 Answers
2
We don't need packages — they're just Tcl code after all — but they do simplify things quite a bit sometimes.
Matrices are represented in Tcl as lists of lists of numbers; it's the natural representation. Think of them being like this (which is row-major form):
set myMatrix {
{ 1.0 -2.0 3.0 }
{-4.0 5.0 -6.0 }
{ 7.0 -8.0 -9.0 }
}
But that can be rewritten like this (it's just a change of whitespace, which isn't significant):
set myMatrix {{1.0 -2.0 3.0} {-4.0 5.0 -6.0} {7.0 -8.0 -9.0}}
The code to invert such a matrix is on the Tcler's Wiki:
puts [Inverse3 $myMatrix]
# {-1.7222222222222223 -0.7777777777777778 -0.05555555555555555} {-1.4444444444444444 -0.5555555555555556 -0.1111111111111111} {-0.05555555555555555 -0.1111111111111111 -0.05555555555555555}
This is the code from the Wiki page, saved here in case the page gets edited away (and using the optimised _Cofactor3
).
proc Inverse3 {matrix} {
if {[llength $matrix] != 3 ||
[llength [lindex $matrix 0]] != 3 ||
[llength [lindex $matrix 1]] != 3 ||
[llength [lindex $matrix 2]] != 3} {
error "wrong sized matrix"
}
set inv {{? ? ?} {? ? ?} {? ? ?}}
# Get adjoint matrix : transpose of cofactor matrix
for {set i 0} {$i < 3} {incr i} {
for {set j 0} {$j < 3} {incr j} {
lset inv $i $j [_Cofactor3 $matrix $i $j]
}
}
# Now divide by the determinant
set det [expr {double([lindex $matrix 0 0] * [lindex $inv 0 0]
+ [lindex $matrix 0 1] * [lindex $inv 1 0]
+ [lindex $matrix 0 2] * [lindex $inv 2 0])}]
if {$det == 0} {
error "non-invertable matrix"
}
for {set i 0} {$i < 3} {incr i} {
for {set j 0} {$j < 3} {incr j} {
lset inv $i $j [expr {[lindex $inv $i $j] / $det}]
}
}
return $inv
}
proc _Cofactor3 {matrix i j} {
set COLS {{1 2} {0 2} {0 1}}
lassign [lindex $COLS $j] row1 row2
lassign [lindex $COLS $i] col1 col2
set a [lindex $matrix $row1 $col1]
set b [lindex $matrix $row1 $col2]
set c [lindex $matrix $row2 $col1]
set d [lindex $matrix $row2 $col2]
set det [expr {$a*$d - $b*$c}]
if {($i+$j) & 1} { set det [expr {-$det}]}
return $det
}

Donal Fellows
- 133,037
- 18
- 149
- 215
-
can you explain how can we give user input as matrix without predefining? – lucky Apr 07 '22 at 20:22