2015-06-27 81 views
1

我在使用mllib.linalg中的RDD时遇到了一些哲学问题。在数值线性代数中,人们想要使用可变数据结构,但是由于在Spark中所有的东西(RDDs)都是不可变的,所以我想知道是否有办法解决这个问题,特别是在我处理的情况下。按顺序更新矩阵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) 

按顺序思维,我想通过

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

但在访问/通过x0,而正常情况下在斯卡拉/微风由xk(::, 0) := x0完成更新xk第一列和其他列mllib.linalg.Matrices没有(适用于!)为其定义的方法here。只是访问一个列(行)反对不变性?如果我使用RowMatrix怎么办?我可以访问/更新行吗?

我的矩阵可以是本地的(如上)或分布式和 我想知道在一般情况下,如果上面的方法可以在功能性的方式来完成。

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

回答

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