如何在Scala微风中求解线性矩阵系统?即,我有 Ax = b,其中 A 是一个矩阵(通常是正定矩阵),而 x 和 b 是向量。
我可以看到有可用的cholesky 分解,但我似乎找不到求解器?(如果是 matlab 我可以做 x = b \ A。如果是 scipy 我可以做 x = A.solve(b) )
如何在Scala微风中求解线性矩阵系统?即,我有 Ax = b,其中 A 是一个矩阵(通常是正定矩阵),而 x 和 b 是向量。
我可以看到有可用的cholesky 分解,但我似乎找不到求解器?(如果是 matlab 我可以做 x = b \ A。如果是 scipy 我可以做 x = A.solve(b) )
显然,它实际上非常简单,并且作为运算符内置在 scala-breeze 中:
x = A \ b
它不使用 Cholesky,它使用 LU 分解,这是我认为的一半,但它们都是 O(n^3),因此具有可比性。
好吧,我最后写了自己的求解器。我不确定这是否是最佳方法,但这似乎不是不合理的?:
// Copyright Hugh Perkins 2012
// You can use this under the terms of the Apache Public License 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package root
import breeze.linalg._
object Solver {
// solve Ax = b, for x, where A = choleskyMatrix * choleskyMatrix.t
// choleskyMatrix should be lower triangular
def solve( choleskyMatrix: DenseMatrix[Double], b: DenseVector[Double] ) : DenseVector[Double] = {
val C = choleskyMatrix
val size = C.rows
if( C.rows != C.cols ) {
// throw exception or something
}
if( b.length != size ) {
// throw exception or something
}
// first we solve C * y = b
// (then we will solve C.t * x = y)
val y = DenseVector.zeros[Double](size)
// now we just work our way down from the top of the lower triangular matrix
for( i <- 0 until size ) {
var sum = 0.
for( j <- 0 until i ) {
sum += C(i,j) * y(j)
}
y(i) = ( b(i) - sum ) / C(i,i)
}
// now calculate x
val x = DenseVector.zeros[Double](size)
val Ct = C.t
// work up from bottom this time
for( i <- size -1 to 0 by -1 ) {
var sum = 0.
for( j <- i + 1 until size ) {
sum += Ct(i,j) * x(j)
}
x(i) = ( y(i) - sum ) / Ct(i,i)
}
x
}
}