Matrix Examples

Some examples. You shouldn't use toString() to find out about matricies. Mdoc calls it on each line anyway - not much i can do about that.

import vecxt.all.*
import vecxt.BoundsCheck.DoBoundsCheck.yes
import narr.*

val nestedArr = NArray(
  NArray[Double](1.0, 2.0, 3.5),
  NArray[Double](3.0, 4.0, 5.0),
  NArray[Double](6.0, 7.0, 8.0)
)
// nestedArr: Array[Array[Double]] = [[D@5f581cf0

val matInt = Matrix.fromRows(
  NArray[Int](1,2),
  NArray[Int](3,4)
)
// matInt: Matrix[Int] = vecxt.matrix$Matrix@4fe2a4ba

val matrix = Matrix.fromRowsArray(nestedArr)
// matrix: Matrix[Double] = vecxt.matrix$Matrix@3483c902
val matrix2 = Matrix.fromColumnsArray(nestedArr)
// matrix2: Matrix[Double] = vecxt.matrix$Matrix@1a37fe0e

matrix.shape
// res0: Tuple2[Row, Col] = (3,3)

matrix.printMat
// res1: String = 1.0 2.0 3.5
// 3.0 4.0 5.0
// 6.0 7.0 8.0

matrix2.printMat
// res2: String = 1.0 3.0 6.0
// 2.0 4.0 7.0
// 3.5 5.0 8.0

matrix.col(1).printArr
// res3: String = [2.0,4.0,7.0]

matrix.row(2).printArr
// res4: String = [6.0,7.0,8.0]

// Note that indexing is done via a tuple.
matrix((1, 2))
// res5: Double = 5.0

More matrix operations...

import vecxt.all.*
import vecxt.BoundsCheck.DoBoundsCheck.yes
import narr.*

val mat1 = Matrix.fromRows(
  NArray(1.0, 4.0, 2.0), 
  NArray(5.0, 3.0, 6.0)
)
// mat1: Matrix[Double] = vecxt.matrix$Matrix@8bdccee

println(mat1.printMat)
// 1.0 4.0 2.0
// 5.0 3.0 6.0

val mat2 = Matrix.fromRows(
  NArray(7.0, 9.0), 
  NArray(8.0, 11.0),
  NArray(10, 12.0)
)
// mat2: Matrix[Double] = vecxt.matrix$Matrix@7f7fc849

println(mat2.printMat)
// 7.0 9.0
// 8.0 11.0
// 10.0 12.0

val result = mat1.matmul(mat2)
// result: Matrix[Double] = vecxt.matrix$Matrix@23f58ec

result.printMat
// res8: String = 59.0 77.0
// 119.0 150.0

// @ is a reserved character, so we can't just copy numpy syntax... experimental
val result2 = mat1 @@ mat2
// result2: Matrix[Double] = vecxt.matrix$Matrix@e9ad60f

result2.printMat
// res9: String = 59.0 77.0
// 119.0 150.0

// opperator precedence...
val result3 = Matrix.eye[Double](2) + mat1 @@ mat2
// result3: Matrix[Double] = vecxt.matrix$Matrix@78d143c2

result3.printMat
// res10: String = 60.0 77.0
// 119.0 151.0

// TODO
// val mat3 = mat2.transpose + mat1
// mat3.printMat
// (mat2.transpose - mat1).printMat


// TODO: Check performance of vectorised version on JVM
mat1.exp.printMat
// res11: String = 2.718281828459045 54.598150033144236 7.38905609893065
// 148.4131591025766 20.085536923187668 403.4287934927351

// TODO: Check performance of vectorised version on JVM
mat1.log.printMat
// res12: String = 0.0 1.3862943611198906 0.6931471805599453
// 1.6094379124341003 1.0986122886681098 1.791759469228055

(mat1.sum(Dimension.Rows).printMat)
// res13: String = 7.0
// 14.0
(mat1.max(Dimension.Cols).printMat)
// res14: String = 5.0 4.0 6.0
(mat1.min(Dimension.Rows).printMat)
// res15: String = 1.0
// 3.0
(mat1.product(Dimension.Cols).printMat)
// res16: String = 5.0 12.0 12.0

(mat1.mapRowsToScalar(_.sum).printMat)
// res17: String = 7.0
// 14.0
(mat1.mapRows(r => r / r.sum).printMat)
// res18: String = 0.14285714285714285 0.5714285714285714 0.2857142857142857
// 0.3571428571428571 0.21428571428571427 0.42857142857142855

(mat1.mapColsToScalar(_.sum).printMat)
// res19: String = 6.0 7.0 8.0
(mat1.mapCols(r => r / r.sum).printMat)
// res20: String = 0.16666666666666666 0.5714285714285714 0.25
// 0.8333333333333333 0.42857142857142855 0.75

mat1.horzcat(mat1).printMat
// res21: String = 1.0 4.0 2.0 1.0 4.0 2.0
// 5.0 3.0 6.0 5.0 3.0 6.0
mat2.vertcat(mat2).printMat
// res22: String = 7.0 9.0
// 8.0 11.0
// 10.0 12.0
// 7.0 9.0
// 8.0 11.0
// 10.0 12.0

Slicing

Index via a Int, NArray[Int] or a Range to slice a matrix. The :: operator is used to select all elements in a dimension.

import vecxt.all.*
import vecxt.BoundsCheck.DoBoundsCheck.yes
import narr.*

val mat = Matrix.fromRows(
    NArray[Double](1.0, 2.0, 3.0),
    NArray[Double](4.0, 5.0, 6.0),
    NArray[Double](7.0, 8.0, 9.0)
)
// mat: Matrix[Double] = vecxt.matrix$Matrix@79415e36
mat(::, ::).printMat
// res23: String = 1.0 2.0 3.0
// 4.0 5.0 6.0
// 7.0 8.0 9.0
mat(Array(1), ::).printMat
// res24: String = 4.0 5.0 6.0
mat(::, Array(1)).printMat
// res25: String = 2.0
// 5.0
// 8.0
mat(Array(1), Array(1)).printMat
// res26: String = 5.0
mat(0 to 1, 0 to 1).printMat
// res27: String = 1.0 2.0
// 4.0 5.0
mat(NArray.from[Int](Array(0, 2)), 0 to 1).printMat
// res28: String = 1.0 2.0
// 7.0 8.0

Indexing

import vecxt.all.*
import vecxt.BoundsCheck.DoBoundsCheck.yes
import narr.*

val mat4 = Matrix.fromRows(
    NArray[Double](1.0, 2.0, 3.0),
    NArray[Double](4.0, 5.0, 6.0),
    NArray[Double](7.0, 8.0, 9.0)
)
// mat4: Matrix[Double] = vecxt.matrix$Matrix@33e3793e

mat4((1,1))
// res29: Double = 5.0

mat4(Array((1,1), (2,2))).printMat
// res30: String = 0.0 0.0 0.0
// 0.0 5.0 0.0
// 0.0 0.0 9.0