Scalaで数値演算処理を行う場合、ScalaNLPのbreezeを利用することが出来ます。

このエントリでは、
線形代数で扱う行列演算の中から、
基本的なものを実際に試してみたので、以下にまとめておきます。
以下のチートシートに従っています。

Linear Algebra Cheat Sheet
https://github.com/scalanlp/breeze/wiki/Linear-Algebra-Cheat-Sheet

以下のようにbuild.sbtにライブラリを指定し、
サンプルコードを書いて、sbt runで実行すれば試すことが出来ます。

build.sbt

scalaVersion := "2.12.8"

libraryDependencies  ++= Seq(
  "org.scalanlp" %% "breeze" % "0.13.2",
)

mainClass in (Compile, run) := Some("LinearAlgebra")

src/main/scala/LinearAlgebra.scala

import breeze.linalg._
import breeze.numerics._

object LinearAlgebra {
  def main(args: Array[String]): Unit = {
    // 行列の定義
    println("**** 行列の定義")
    val matrix1 = DenseMatrix((1.0, 0.0, -4.0),(2.0, -3.0, -1.0))
    println("行列A: \n" + matrix1)
    println("Aの転置行列: \n" + matrix1.t)
    val zeroMatrix = DenseMatrix.zeros[Double](2,2)
    println("ゼロ行列: \n" + zeroMatrix)
    val identityMatrix = DenseMatrix.eye[Double](2)
    println("単位行列: \n" + identityMatrix)

    // 行列の和とスカラー倍
    println("\n**** 行列の和とスカラー倍")
    val matrixA = DenseMatrix((1.0, 0.0, -4.0),(2.0, -3.0, -1.0))
    val matrixB = DenseMatrix((-3.0, 4.0, 8.0),(1.0, 5.0, -2.0))
    println("行列A: \n" + matrixA)
    println("行列B: \n" + matrixB)
    println("A+B: \n" + (matrixA + matrixB))
    println("A-B: \n" + (matrixA - matrixB))
    println("3A: \n" + (matrixA *:* 3.0))
    println("A-2B: \n" + (matrixA - matrixB *:* 2.0))

    // 行列の内積
    println("\n**** 行列の内積")
    val matrix2A = DenseMatrix((3.0, -3.0, 1.0), (0.0, -2.0, 4.0))
    val matrix2B = DenseMatrix((-1.0, 0.0), (5.0, 1.0), (0.0, -3.0))
    println("行列A: \n" + matrix2A)
    println("行列B: \n" + matrix2B)
    println("AB: " + (matrix2A * matrix2B))

    // 逆行列
    println("\n**** 逆行列")
    val matrix3A = DenseMatrix((1.0, 2.0),(3.0, 4.0))
    println("行列A: \n" + matrix3A)
    println("Aの逆行列: \n" + inv(matrixA))

    // 行列式、固有値と固有ベクトル
    println("\n**** 行列式、固有値と固有ベクトル")
    val matrix4A = DenseMatrix((1.0, -2.0),(3.0, -4.0))
    println("行列A: \n" + matrix4A)
    println("行列式: \n" + det(matrix4A))
    println("固有値: \n" + eig(matrix4A).eigenvalues)
    println("固有ベクトル: \n" + eig(matrix4A).eigenvectors)
  }
}

実行結果:

$ sbt run
※途中省略※
[info] Running LinearAlgebra
**** 行列の定義
行列A:
1.0  0.0   -4.0  
2.0  -3.0  -1.0  
Aの転置行列:
1.0   2.0   
0.0   -3.0  
-4.0  -1.0  
ゼロ行列:
0.0  0.0  
0.0  0.0  
単位行列:
1.0  0.0  
0.0  1.0  

**** 行列の和とスカラー倍
行列A:
1.0  0.0   -4.0  
2.0  -3.0  -1.0  
行列B:
-3.0  4.0  8.0   
1.0   5.0  -2.0  
A+B:
-2.0  4.0  4.0   
3.0   2.0  -3.0  
A-B:
4.0  -4.0  -12.0  
1.0  -8.0  1.0    
3A:
3.0  0.0   -12.0  
6.0  -9.0  -3.0   
A-2B:
7.0  -8.0   -20.0  
0.0  -13.0  3.0    

**** 行列の内積
行列A:
3.0  -3.0  1.0  
0.0  -2.0  4.0  
行列B:
-1.0  0.0   
5.0   1.0   
0.0   -3.0  
AB: -18.0  -6.0   
-10.0  -14.0  

**** 逆行列
行列A:
1.0  2.0  
3.0  4.0  
Aの逆行列:
1.0                 0.0                  -1.0  
0.6666666666666666  -0.3333333333333333  -3.5  

**** 行列式、固有値と固有ベクトル
行列A:
1.0  -2.0  
3.0  -4.0  
行列式:
2.0
固有値:
DenseVector(-0.9999999999999996, -2.0)
固有ベクトル:
0.7071067811865476  0.5547001962252291  
0.7071067811865475  0.8320502943378437  
[success] Total time: 8 s, completed 2019/01/19 19:55:27

行列計算については見ればわかるので、特に説明しませんでした。

上記の例に無い演算は、やりたいことを英訳して、
チートシート内を検索すればだいたい見つけられます。

# 例えば、対角成分
# →(英訳)→ diagonal element
# →(検索)→ Create view of matrix diagonal: diag(a) とか。

また、Spark MLlibを使っている場合は、
SparkMLlibがbreezeに依存しているので、
ライブラリの設定はしなくても、spark-shellなどから利用できます。