按顺序更新Matrix RDD的列

时间:2015-06-27 17:58:59

标签: scala matrix apache-spark apache-spark-mllib scala-breeze

我在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)

顺序思考,我想通过xk访问/更新x0的第一列,其中scala / breeze通常由xk(::, 0) := x0完成,其他列由<{1}}完成/ p>

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

但是在mllib.linalg.Matrices中没有为它定义{apply like!)方法here。只是访问列(行)以抵抗不变性?如果我使用RowMatrix怎么办?我可以访问/更新行吗?

  

我的矩阵可以是本地的(如上所述)或分布式的     我想知道一般情况下,上述过程是否可以通过功能方式完成。

我很感激任何评论或帮助。

1 个答案:

答案 0 :(得分:1)

到目前为止,我已经找到了几个问题的答案,尽管“哲学”问题仍然存在。

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

其次,上述循环的功能方法当然是尾递归,如下所示

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]())
}