Skip to content

Instantly share code, notes, and snippets.

@shashir
Last active March 14, 2016 23:45
Show Gist options
  • Save shashir/4096dda89e11ca19d3b3 to your computer and use it in GitHub Desktop.
Save shashir/4096dda89e11ca19d3b3 to your computer and use it in GitHub Desktop.
Matrix -- simple no library
import scala.reflect.ClassTag
case class Matrix[T : ClassTag](
rows: Int,
cols: Int,
matrix: Array[Array[T]]
)(implicit num: Numeric[T]) {
import num._
require(matrix.length == rows, "Row number incorrect.")
for (row: Array[T] <- matrix) {
require(row.length == cols, "Columns inconsistent.")
}
def apply(i: Int, j: Int): T = this.matrix(i)(j)
def apply(i: Int): Array[T] = this.matrix(i)
def elemBiOp(that: Matrix[T], op: (T, T) => T): Matrix[T] = {
require(this.rows == that.rows && this.cols == that.cols)
val result: Array[Array[T]] = Array.ofDim(rows, cols)
for (i <- 0 until rows; j <- 0 until cols) {
result(i)(j) = op(this.matrix(i)(j), that.matrix(i)(j))
}
return Matrix(rows, cols, result)
}
def elemUniOp(op: T => T): Matrix[T] = {
val result: Array[Array[T]] = Array.ofDim(rows, cols)
for (i <- 0 until rows; j <- 0 until cols) {
result(i)(j) = op(this.matrix(i)(j))
}
return Matrix[T](rows, cols, result)
}
def +(that: Matrix[T]): Matrix[T] = elemBiOp(that, _ + _)
def -(that: Matrix[T]): Matrix[T] = elemBiOp(that, _ - _)
def *(that: Matrix[T]): Matrix[T] = elemBiOp(that, _ * _)
def /(that: Matrix[T]): Matrix[T] = elemBiOp(that, div(_, _))
def *(s: T): Matrix[T] = elemUniOp(_ * s)
def /(s: T): Matrix[T] = elemUniOp(div(_, s))
private def div(a: T, b: T): T = implicitly[Numeric[T]] match {
case num: Fractional[T] => num.div(a, b)
case num: Integral[T] => num.quot(a, b)
case _ => throw new IllegalArgumentException("Indivisible numeric type.")
}
def apply(that: Matrix[T]): Matrix[T] = {
require(this.cols == that.rows)
val result: Array[Array[T]] = Array.ofDim(this.rows, that.cols)
for (
i <- 0 until this.rows;
j <- 0 until that.cols;
m <- 0 until this.cols;
n <- 0 until that.rows;
if (m == n)
) {
result(i)(j) += this(i, m) * that(n, j)
}
return Matrix(this.rows, that.cols, result)
}
def trace(): T = {
return (for (i <- 0 until Math.min(rows, cols)) yield this(i, i)).sum
}
def t: Matrix[T] = {
val result: Array[Array[T]] = Array.ofDim(cols, rows)
for (i <- 0 until this.rows; j <- 0 until cols) {
result(j)(i) += this(i, j)
}
return Matrix(cols, rows, result)
}
override def toString(): String = {
return matrix.map { _.mkString(" ") }.mkString("\n")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment