顺序更新矩阵 RDD 的列

Sequentially updating columns of a Matrix RDD

我对 mllib.linalg 中使用的 RDD 有哲学上的疑问。在数值线性代数中,人们想使用可变数据结构,但由于在 Spark 中,一切 (RDD) 都是不可变的,我想知道是否有办法解决这个问题,特别是针对我正在处理的以下情况;

import org.apache.spark.mllib.linalg._
import breeze.numerics._

val theta = constants.Pi / 64
val N = 1000
val Gk: Matrix = Matrices.dense(2, 2, Array(
                               cos(theta), sin(theta),
                               -sin(theta), cos(theta))
                               )
val x0: Vector = Vectors.dense(0.0, 1.0)
var xk = DenseMatrix.zeros(2, N + 1)

按顺序思考,我想 access/update xk 的第一列由 x0 完成,而通常 scala/breeze 由 xk(::, 0) := x0 完成, 和其他列

for (k <- 0 to N - 1) {
    xk(::, k + 1) := Gk * xk(::, k)
}

但是在 mllib.linalg.Matrices 中没有为它定义(像应用一样!)方法 here。只是访问一列(行)是否违反不变性?如果我使用 RowMatrix 会怎样?那我可以 access/update 行吗?

My matrices can be local (like above) or distributed and I'd like to know in general, if the above process can be done in a functional way.

如有任何评论或帮助,我将不胜感激。

到目前为止,我已经找到了几个问题的答案,但 "philosophical" 个问题仍然存在。

首先,我发现我可以像以前一样使用 import breeze.linalg._ 来利用 breeze 矩阵的数据可变性,但这可能无法完全以分布式方式完成。

其次,上述循环的函数式处理当然是尾递归,如下

def nMultiply(x: Vector, M: Matrix, n: Int): Tuple2[Vector, Array[Double]] = {
    def loop(acc: Vector, n: Int, store: Array[Double]): Tuple2[Vector, Array[Double]] = {
        if (n <= 0) (acc, store)
        else {
            var res: Vector = M.multiply(loop(x, n - 1, store)._1)
            (res, loop(x, n - 1, store)._2.union(res.toArray))
        }
    }
loop(x, n, Array[Double]())
}