在Apache Spark中解决大规模线性系统

时间:2016-09-11 23:35:12

标签: apache-spark matrix-inverse

我目前正在寻求使用Spark解决大规模线性系统Ax = b。我已经做了很多搜索以找到解决方案,this链接是我找到的唯一解决方案,用于计算A的伪逆,以便将其反转并乘以b作为下一步。为简单起见,我将在此复制解决方案。

import org.apache.spark.mllib.linalg.{Vectors,Vector,Matrix,SingularValueDecomposition,DenseMatrix,DenseVector}
import org.apache.spark.mllib.linalg.distributed.RowMatrix

def computeInverse(X: RowMatrix): DenseMatrix = {
  val nCoef = X.numCols.toInt
  val svd = X.computeSVD(nCoef, computeU = true)
  if (svd.s.size < nCoef) {
    sys.error(s"RowMatrix.computeInverse called on singular matrix.")
  }

  // Create the inv diagonal matrix from S 
  val invS = DenseMatrix.diag(new DenseVector(svd.s.toArray.map(x => math.pow(x,-1))))

  // U cannot be a RowMatrix
  val U = new DenseMatrix(svd.U.numRows().toInt,svd.U.numCols().toInt,svd.U.rows.collect.flatMap(x => x.toArray))

  // If you could make V distributed, then this may be better. However its alreadly local...so maybe this is fine.
  val V = svd.V
  // inv(X) = V*inv(S)*transpose(U)  --- the U is already transposed.
  (V.multiply(invS)).multiply(U)
  }

然而,这个解决方案的问题是,最后,我们必须使U成为本地DenseMatrix,我认为对于大型矩阵来说是不可能的。为了解决这个问题,我将不胜感激任何帮助和想法。

1 个答案:

答案 0 :(得分:0)

您可以尝试其中一种迭代算法(https://rdrr.io/cran/jsonlite/man/flatten.html)。不是直接求解Ax = b,而是搜索最小化f(x)= 0.5x ^ tAx -x ^ tb的x

使用并行PCG,实际迭代是连续完成的;这是您的工作人员共享的简单乘法和其他操作。但是这允许您在群集中分布稀疏矩阵。

不幸的是,Spark的线性代数库是一项正在进行的工作,我没有示例代码向您展示。对于你的问题,可能有比PCG更好的方法,我们只需要在Spark中实现它们。不确定你的背景是什么,但你可以从一般研究如何并行解决线性方程组的系统开始。

编辑:还有一些讨论e.g. PCGhere