package lib.matrix

fun isSymmetric(a: Matrix): Boolean {
  return if (a.m != a.n) false else a == t(a)
}

fun isSkewSymmetric(a: Matrix): Boolean {
  return if (a.m != a.n) false else a == -t(a)
}

fun t(a: Matrix): Matrix {
  return Matrix(a.n, a.m, Array(a.n) { i -> Array(a.m) { j -> a[j + 1, i + 1] } })
}

fun tr(a: Matrix): Double {
  if (a.m != a.n)
      throw IllegalArgumentException("Cannot find trace of a non-square (${a.m} x ${a.n}) matrix")
  return Array(a.m) { a[it + 1, it + 1] }.sum()
}

fun det(a: Matrix): Double {
  if (a.m != a.n)
      throw IllegalArgumentException(
          "Cannot find determinant of a non-square (${a.m} x ${a.n}) matrix")
  return when (a.m) {
    1 -> a[1, 1]
    2 -> (a[1, 1] * a[2, 2]) - (a[1, 2] * a[2, 1])
    3 ->
        (a[1, 1] * a[2, 2] * a[3, 3]) +
            (a[1, 2] * a[2, 3] * a[3, 1]) +
            (a[1, 3] * a[2, 1] * a[3, 2]) -
            (a[1, 3] * a[2, 2] * a[3, 1]) -
            (a[1, 2] * a[2, 1] * a[3, 3]) -
            (a[1, 1] * a[2, 3] * a[3, 2])
    else -> TODO("Cannot find determinant of a ${a.m} x ${a.n} matrix")
  }
}

fun identityMatrix(n: Int): Matrix {
  return Matrix(n, n, Array(n) { i -> Array(n) { j -> if (i == j) 1.0 else 0.0 } })
}

package lib.matrix

fun isSymmetric(a: Matrix): Boolean {
  return if (a.m != a.n) false else a == t(a)
}

fun isSkewSymmetric(a: Matrix): Boolean {
  return if (a.m != a.n) false else a == -t(a)
}

fun t(a: Matrix): Matrix {
  return Matrix(a.n, a.m, Array(a.n) { i -> Array(a.m) { j -> a[j + 1, i + 1] } })
}

fun tr(a: Matrix): Double {
  if (a.m != a.n)
      throw IllegalArgumentException("Cannot find trace of a non-square (${a.m} x ${a.n}) matrix")
  return Array(a.m) { a[it + 1, it + 1] }.sum()
}

fun det(a: Matrix): Double {
  if (a.m != a.n)
      throw IllegalArgumentException(
          "Cannot find determinant of a non-square (${a.m} x ${a.n}) matrix")
  return when (a.m) {
    1 -> a[1, 1]
    2 -> (a[1, 1] * a[2, 2]) - (a[1, 2] * a[2, 1])
    3 ->
        (a[1, 1] * a[2, 2] * a[3, 3]) +
            (a[1, 2] * a[2, 3] * a[3, 1]) +
            (a[1, 3] * a[2, 1] * a[3, 2]) -
            (a[1, 3] * a[2, 2] * a[3, 1]) -
            (a[1, 2] * a[2, 1] * a[3, 3]) -
            (a[1, 1] * a[2, 3] * a[3, 2])
    else -> TODO("Cannot find determinant of a ${a.m} x ${a.n} matrix")
  }
}

fun identityMatrix(n: Int): Matrix {
  return Matrix(n, n, Array(n) { i -> Array(n) { j -> if (i == j) 1.0 else 0.0 } })
}
