Scala 的矩陣運算
阿新 • • 發佈:2019-02-02
本文講解 Scala 中進行矩陣運算的包 breeze 的一些基礎操作。
Breeze 是 Scala 中用於線性代數相關數值運算的開源庫。
安裝
首先我們使用 SBT 匯入:
libraryDependencies ++= Seq(
// Last stable release
"org.scalanlp" %% "breeze" % "0.13.2",
// Native libraries are not included by default. add this if you want them (as of 0.7)
// Native libraries greatly improve performance, but increase jar sizes.
// It also packages various blas implementations, which have licenses that may or may not
// be compatible with the Apache License. No GPL code, as best I know.
"org.scalanlp" %% "breeze-natives" % "0.13.2",
// The visualization library is distributed separately as well.
// It depends on LGPL code
"org.scalanlp" %% "breeze-viz" % "0.13.2"
)
這裡其官方 Github 的文件還有這樣一句:
resolvers += "Sonatype Releases" at "https://oss.sonatype.org/content/repositories/releases/"
但是我加上以後就會報錯,去掉以後就 build 好了,很奇怪。
快速開始
首先引入下面內容:
import breeze.linalg._
新建一個向量:
// Dense vector will allocate memory for zeros, where sparse won't.
val x = DenseVector.zeros[Double](5)
val y = SparseVector.zeros[Double](5)
println(x) // DenseVector(0.0, 0.0, 0.0, 0.0, 0.0)
println(y) // SparseVector(5)()
與 Scala 不同,breeze 建立的所有向量都是列向量。
可以通過下標獲取或者更改向量中的元素,而且支援負數下標。
// Access and update data elements by their index
// and negative indices are supported, x(i) == x(x.length + i)
println(x(0)) // 0.0
x(4) = 4
println(x(-1)) // 4.0
Breeze 也支援切片,並且範圍切片比任意切片快得多。切片賦值時使用的時 :=
,可以給切片賦一個相同的值,也可以給其賦一個相同長度的向量。
x(3 to 4) := .5
x(0 to 1) := DenseVector(.1, .2)
println(x) // DenseVector(0.1, 0.2, 0.0, 0.5, 0.5)
接下來我們再新建一個全為 0 的 5x5 矩陣:
val m = DenseMatrix.zeros[Int](5, 5)
println(m)
結果:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
然後我們可以訪問其行或者列,列就是 DenseVectors
的型別,行是 DenseVectors
的轉置。
// The columns of m can be accessed as DenseVectors, and the rows as DenseMatrices.
val size = (m.rows, m.cols)
println(size) // (5,5)
val column = m(::, 1)
println(column) // DenseVector(0, 0, 0, 0, 0)
// Transpose to match row shape
m(4, ::) := DenseVector(1, 2, 3, 4, 5).t
println(m)
結果:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 2 3 4 5
同樣可以切割出一個子矩陣:
m(0 to 1, 0 to 1) := DenseMatrix((3, 1), (-1, -2))
println(m)
結果:
3 1 0 0 0
-1 -2 0 0 0
0 0 0 0 0
0 0 0 0 0
1 2 3 4 5