2016-07-19 56 views
0

假設我有一個整數矩陣a並需要創建一個新矩陣b以便b[i, j]a[i, j]及其鄰居的總和。Scala中的簡單矩陣計算

我定義了一個矩陣Array[Array[Int]]和寫一個函數foo計算b這樣的:

type Matrix = Array[Array[Int]] 

def sumOfNeighbors(a: Matrix, x: Int, y: Int): Int = { 

    val range = -1 to 1 
    val deltas = range.flatMap { dx => range map {dy => (dx, dy)} } 
        .filter { case (dx, dy) => dx != 0 || dy != 0 } 

    val withinBounds: Int => Boolean = x => x >= 0 && x < a.size 
    val coords = deltas.map {case (dx, dy) => (x + dx, y + dy)} 
        .filter {case (i, j) => withinBounds(i) && withinBounds(j)} 

    coords.map{case (i, j) => a(i)(j)}.sum 
} 

def foo(a: Matrix): Matrix = 
    a.zipWithIndex map {case (row, i) => 
    row.zipWithIndex.map {case (x, j) => x + sumOfNeighbors(a, i, j)} 
    } 

是否有意義?你會如何簡化這個代碼?

+0

它沒有做它的規範「所以b [i,j]是[i,j]和它的鄰居的和。」因爲它排除了[i,j]與「過濾器......」的總和。 –

+0

我確實加了'a [i,j]'。參見'foo'函數。我同意,不過在sumOfNeighbors中不過濾它會更自然。 – Michael

+0

啊,我錯過了。然後就會有「簡化代碼」的改變!另外,我知道我正在找藉口:)但'case(x,j)'到'case(i,j)'的視覺相似性是我錯過了這個的一個原因...... –

回答

1

您的代碼確實有意義,但您可以添加幾個工具,根據您的資源,可以將其擴展。
如果將Spark與Scala代碼結合使用(如果可行),則可以使用Spark提供的一些均值漂移軟件包。使用RDD你可以做很多相同的功能。
https://spark-packages.org/?q=tags%3Alsh

如果這只是小規模,但沒有一個是真正必要的。

+1

使用Breeze庫可能會更好,因爲Spark的'ml'和'mllib'使用基於Breeze的Vector和Matrix實現。另外,它也是Scala的線性代數解題庫。 – sebszyller