【问题标题】:Scala Matrix InversionScala矩阵求逆
【发布时间】:2011-08-30 07:09:06
【问题描述】:

嗯,是的,我真的需要一个没有创作者眼睛的人的快速输入。根据我的scalacheck 测试,这里出了点问题……但我对它的了解还不够,不知道哪里出了问题。

case class Matrix(_1: (Float, Float, Float, Float), _2: (Float, Float, Float, Float),
                  _3: (Float, Float, Float, Float), _4: (Float, Float, Float, Float)) extends Immutable {
  def invert = {
    val _11 = _2._2 * _3._3 * _4._4 - _2._2 * _3._4 * _4._3 - _3._2 * _2._3 * _4._4
      +_3._2 * _2._4 * _4._3 + _4._2 * _2._3 * _3._4 - _4._2 * _2._4 * _3._3
    val _21 = -_2._1 * _3._3 * _4._4 + _2._1 * _3._4 * _4._3 + _3._1 * _2._3 * _4._4
      -_3._1 * _2._4 * _4._3 - _4._1 * _2._3 * _3._4 + _4._1 * _2._4 * _3._3
    val _31 = _2._1 * _3._2 * _4._4 - _2._1 * _3._4 * _4._2 - _3._1 * _2._2 * _4._4
      +_3._1 * _2._4 * _4._2 + _4._1 * _2._2 * _3._4 - _4._1 * _2._4 * _3._2
    val _41 = -_2._1 * _3._2 * _4._3 + _2._1 * _3._3 * _4._2 + _3._1 * _2._2 * _4._3
      -_3._1 * _2._3 * _4._2 - _4._1 * _2._2 * _3._3 + _4._1 * _2._3 * _3._2
    val _12 = -_1._2 * _3._3 * _4._4 + _1._2 * _3._4 * _4._3 + _3._2 * _1._3 * _4._4
      -_3._2 * _1._4 * _4._3 - _4._2 * _1._3 * _3._4 + _4._2 * _1._4 * _3._3
    val _22 = _1._1 * _3._3 * _4._4 - _1._1 * _3._4 * _4._3 - _3._1 * _1._3 * _4._4
      +_3._1 * _1._4 * _4._3 + _4._1 * _1._3 * _3._4 - _4._1 * _1._4 * _3._3
    val _32 = -_1._1 * _3._2 * _4._4 + _1._1 * _3._4 * _4._2 + _3._1 * _1._2 * _4._4
      -_3._1 * _1._4 * _4._2 - _4._1 * _1._2 * _3._4 + _4._1 * _1._4 * _3._2
    val _42 = _1._1 * _3._2 * _4._3 - _1._1 * _3._3 * _4._2 - _3._1 * _1._2 * _4._3
      +_3._1 * _1._3 * _4._2 + _4._1 * _1._2 * _3._3 - _4._1 * _1._3 * _3._2
    val _13 = _1._2 * _2._3 * _4._4 - _1._2 * _2._4 * _4._3 - _2._2 * _1._3 * _4._4
      +_2._2 * _1._4 * _4._3 + _4._2 * _1._3 * _2._4 - _4._2 * _1._4 * _2._3
    val _23 = -_1._1 * _2._3 * _4._4 + _1._1 * _2._4 * _4._3 + _2._1 * _1._3 * _4._4
      -_2._1 * _1._4 * _4._3 - _4._1 * _1._3 * _2._4 + _4._1 * _1._4 * _2._3
    val _33 = _1._1 * _2._2 * _4._4 - _1._1 * _2._4 * _4._2 - _2._1 * _1._2 * _4._4
      +_2._1 * _1._4 * _4._2 + _4._1 * _1._2 * _2._4 - _4._1 * _1._4 * _2._2
    val _43 = -_1._1 * _2._2 * _4._3 + _1._1 * _2._3 * _4._2 + _2._1 * _1._2 * _4._3
      -_2._1 * _1._3 * _4._2 - _4._1 * _1._2 * _2._3 + _4._1 * _1._3 * _2._2
    val _14 = -_1._2 * _2._3 * _3._4 + _1._2 * _2._4 * _3._3 + _2._2 * _1._3 * _3._4
      -_2._2 * _1._4 * _3._3 - _3._2 * _1._3 * _2._4 + _3._2 * _1._4 * _2._3
    val _24 = _1._1 * _2._3 * _3._4 - _1._1 * _2._4 * _3._3 - _2._1 * _1._3 * _3._4
      +_2._1 * _1._4 * _3._3 + _3._1 * _1._3 * _2._4 - _3._1 * _1._4 * _2._3
    val _34 = -_1._1 * _2._2 * _3._4 + _1._1 * _2._4 * _3._2 + _2._1 * _1._2 * _3._4
      -_2._1 * _1._4 * _3._2 - _3._1 * _1._2 * _2._4 + _3._1 * _1._4 * _2._2
    val _44 = _1._1 * _2._2 * _3._3 - _1._1 * _2._3 * _3._2 - _2._1 * _1._2 * _3._3
      +_2._1 * _1._3 * _3._2 + _3._1 * _1._2 * _2._3 - _3._1 * _1._3 * _2._2

    val det = _1._1 * _11 + _1._2 * _21 + _1._3 * _31 + _1._4 * _41
    if (det == 0) this
    else Matrix(
      (_11, _12, _13, _14),
      (_21, _22, _23, _24),
      (_31, _32, _33, _34),
      (_41, _42, _43, _44)
    ) * (1 / det)
  }

  def *(f: Float) = Matrix(
    (_1._1 * f, _1._2 * f, _1._3 * f, _1._4 * f),
    (_2._1 * f, _2._2 * f, _2._3 * f, _2._4 * f),
    (_3._1 * f, _3._2 * f, _3._3 * f, _3._4 * f),
    (_4._1 * f, _4._2 * f, _4._3 * f, _4._4 * f)
  )
}

另外,我可以将此矩阵加载到 OpenGL 中还是必须先转置它。我真的总是对这个数学感到困惑。

【问题讨论】:

  • 请告诉我这是生成的代码...
  • 我是从一个例子亲手写的...
  • 哦,天哪。那是浪费时间。

标签: math scala matrix matrix-inverse


【解决方案1】:

反转矩阵通常是个坏主意,因为计算可能是病态的。

如果您想求解方程组,最好使用 LU 分解和前向-后向替换之类的方法,特别是如果您可以重用分解来求解多个右手边向量。

This link 显示了一个带有旋转的高斯消元的 Java 示例。

这里有另一个想法:也许您可以在您的应用程序中使用 Java 库,如 JAMA 的继任者 Apache Commons Math

如果您有特殊情况,建议您将其输入Wolfram Alpha,以便在开始编码之前查看答案。

【讨论】:

    【解决方案2】:

    我很确定 Simplex3D 实现了这个计算(并且很可能在那里正确地完成了)。

    【讨论】:

      【解决方案3】:

      如果你想玩数字 - 一定要自己动手 - 你可以从 Jesper 和 duffymo 那里得到一些很好的建议(求逆矩阵在实践中没有用 - 看看 LU 分解)。

      但是,如果您只想完成工作TM,请查看ScalalaScalalab

      无论哪种方式,您都需要 Linear Algebra background 知识 - 这对于许多领域来说都是非常有用的数学。

      【讨论】:

        【解决方案4】:

        查看维基百科上的Invertible matrix: Analytic solution。顶部的全部计算计算矩阵的adjugate,从中计算行列式,然后逆矩阵为1 / det 乘以辅助矩阵。

        整个计算是针对您的代码中的 4 x 4 矩阵显式写出的,因此如果其中存在错误,则需要花费一些精力来检查整个事情。维基百科的文章解释了它应该如何工作。

        【讨论】:

        • 值得注意的是,对于较大的矩阵(甚至 4x4),这不是一种有效的计算方式。
        猜你喜欢
        • 1970-01-01
        • 2013-05-05
        • 1970-01-01
        • 2017-11-24
        • 2013-11-11
        • 2014-09-02
        • 2020-05-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多