Scala中的上三角矩阵

时间:2016-05-06 15:12:06

标签: scala functional-programming

有没有办法可以在scala中更快地计算上三角矩阵?

/** Returns a vector which consists of the upper triangular elements of a matrix */   
def getUpperTriangle(A: Array[Array[Double]]) = 
{
    var A_ = Seq(0.)
    for (i <- 0 to A.size - 1;j <- 0 to A(0).size - 1)
    {
        if (i <= j){
            A_ = A_ ++ Seq(A(i)(j))
            }
    }
    A_.tail.toArray
}

2 个答案:

答案 0 :(得分:6)

我不太了解更快,但这更短,更实用&#34; (我注意到您使用functional-programming

标记了您的问题
def getUpperTriangle(a: Array[Array[Double]]) = 
   (0 until a.size).flatMap(i => a(i).drop(i)).toArray

或者,或多或少相同的想法:

def getUpperTriangle(a: Array[Array[Double]]) =
   a.zipWithIndex.flatMap{case(r,i) => r.drop(i)}

答案 1 :(得分:1)

您可以采取以下三项基本方法来简化逻辑以提高性能:

  • 以空Seq开头,因此您最后不必致电Seq.tailtail操作将为O(n),因为Seq工厂方法会为您提供IndexedSeq
  • 使用Seq.:+将单个元素附加到Seq,而不是使用单个元素构建Seq,并使用Seq.++附加两个Seqs }。对于Seq.:+O(1)IndexedSeq(已摊销)并且速度非常快。将Seq.++与单个元素序列一起使用可能仍然是O(1),但会有更多的开销。
  • 您可以j开始i,而不是在j开始0并在循环体中测试i <= j。这将保存n^2/2无操作循环迭代。

一些风格的东西:

  • 最好始终包含返回类型。没有它,你实际上会得到一个弃用警告。
  • 我们在Scala中使用小写作为变量名称
  • 0 until size可能比0 to size - 1
  • 更具可读性
def getUpperTriangle(a: Array[Array[Double]]): Array[Double] = {
  var result = Seq[Double]()
  for (i <- 0 until a.size; j <- i until A(0).size) {
    result = result :+ a(i)(j)
  }
  result.toArray
}