有没有办法可以在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
}
答案 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.tail
。 tail
操作将为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
无操作循环迭代。一些风格的东西:
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
}