LoginSignup
2
1

More than 5 years have passed since last update.

netlib-java breezeで行列計算する

Last updated at Posted at 2016-09-15

リコメンドエンジンの仕事で行列の内積を取る必要があったのでざっと触ったのでメモ。

やりたいことは以下のイメージです。

\begin{pmatrix}
1.0 & 2.0 & 3.0 \\
4.0 & 5.0 & 6.0
\end{pmatrix}

\times

\begin{pmatrix}
1.0 \\
2.0 \\
3.0 
\end{pmatrix}

=

\begin{pmatrix}
14.0 \\
32.0 \\
\end{pmatrix}

※以下では楽なのでscalaで書いていますが、僕は仕事では、がっつりチューニングしたい&他ロジックとの兼ね合いでjavaで書いています。

breeze

下記のような感じで書くと、

val matrix_A = DenseMatrix(Array(1.0, 2.0, 3.0), Array(4.0, 5.0, 6.0))
println("matrix_A")
println(matrix_A)
val vector_B = DenseMatrix(Array(1.0), Array(2.0), Array(3.0))
println("\nvector_B")
println(vector_B)
val result = matrix_A * vector_B
println("\nresult")
println(result)

このような出力をしてくれます。

matrix_A
1.0  2.0  3.0  
4.0  5.0  6.0  

vector_B
1.0  
2.0  
3.0  

result
14.0  
32.0 

netlib.ddot

下記のような感じで書くと、

val blas: BLAS = BLAS.getInstance

val (a, b) = makeRandomMatrixAndVector(10, 3)

val vector_A = Array(1.0, 2.0, 3.0)
println("vector_A")
println(vector_A.toSeq.mkString(","))

val vector_B = Array(4.0, 5.0, 6.0)
println("\nvector_B")
println(vector_B.toSeq.mkString(","))

val dotProduct = blas.ddot(vector_A.length, vector_A, 1, vector_B, 1)
println("\ndotProduct")
println(dotProduct)

このように出力してくれます。

vector_A
1.0,2.0,3.0

vector_B
4.0,5.0,6.0

dotProduct
32.0

netlib.dgemv

以下のように書くと、

val blas: BLAS = BLAS.getInstance

val m = 3
val n = 2

val matrix_A = new Array[Double](m* n)

matrix_A(0)=1; matrix_A(3)=2
matrix_A(1)=0; matrix_A(4)=2
matrix_A(2)=3; matrix_A(5)=3

val vector_B = new Array[Double](n)
vector_B(0)=1
vector_B(1)=2

//結果は返り値でなくここに格納される
val result = new Array[Double](m)

blas.dgemv("N", m, n, 1.0, matrix_A, m, vector_B, 1, 0.0, result, 1)

println("\nresult")
result.foreach(println)

このように出力します。

result
5.0
4.0
9.0

パフォーマンス

(Cモジュール導入は、デプロイ面倒なのでまだやってません)

ソースコードを雑に置いています。
https://github.com/uryyyyyyy/matrixVectorSample

あまりチューニングできていませんが、僕の仕事の箇所でいうとnetlibとbreezeの差よりも、

  • 前後の処理の計算量のオーダー
  • 無駄なオブジェクト生成によるメモリ消費(GCタイミング)
  • double値などプリミティブ型のboxing/unboxingコスト

が支配的でした。プロダクトによって自然な形で取り入れられる形のものを使うのが良さそうです。(Javaの方がチューニングしやすいかなって個人的には思います。)

現場からは以上です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1