如何在TCL脚本中代码3 x 3矩阵的代码?

发布于 2025-01-19 11:20:32 字数 100 浏览 3 评论 0原文

我发现在 tcl 中编码 3x3 矩阵的逆矩阵很困难。我们真的需要包来编码矩阵吗?我需要用最简单的编码对以下部分进行清晰的解释 1.如何创建矩阵? 2.如何求行列式? 3.如何求它的逆?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

平定天下 2025-01-26 11:20:32

我们不需要包——毕竟它们只是 Tcl 代码——但有时它们确实简化了很多事情。

矩阵在 Tcl 中表示为数字列表的列表;这是自然的表现。把它们想象成这样(这是行主形式):

set myMatrix {
    { 1.0 -2.0  3.0 }
    {-4.0  5.0 -6.0 }
    { 7.0 -8.0 -9.0 }
}

但是可以像这样重写(这只是空白的改变,并不重要):

set myMatrix {{1.0 -2.0 3.0} {-4.0 5.0 -6.0} {7.0 -8.0 -9.0}}

反转这样一个矩阵的代码是 Tcler 的 Wiki

puts [Inverse3 $myMatrix]
# {-1.7222222222222223 -0.7777777777777778 -0.05555555555555555} {-1.4444444444444444 -0.5555555555555556 -0.1111111111111111} {-0.05555555555555555 -0.1111111111111111 -0.05555555555555555}

这是 Wiki 页面的代码,保存在此处,以防万一页面被编辑掉(并使用优化的_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
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文