## Wednesday, July 1, 2009

### Matrices 5b

To finish my last post I wrote a quick&dirty class to show MatrixInt in use. Alas, it was so dirty I couldn't stand the shame, so I rewrote it. Have fun. :-)

`class LinearEquations(val m: MatrixInt, val r: MatrixInt) {  require(m.rows == r.rows && r.cols == 1)    def maxColumnSize(matrix: MatrixInt, isAbs: Boolean): Int = (    matrix.toArray     flatMap (row => row)     map (value => (if (isAbs) value.abs else value).toString.length)    reduceLeft (_ max _)  )    lazy val maxCoefficientsColumnSize =  maxColumnSize(m, true)  lazy val maxConstantsColumnSize = maxColumnSize(r, false)  lazy val maxColsSize = m.cols.toString.length    def numberSign(n: Int) = if (n < 0) " - " else " + "  def formatNumber(n: Int, size: Int) = "%"+size+"d" format n  def formatConstant(n: Int) = formatNumber(n, maxConstantsColumnSize)  def formatCoefficient(n: Int) = formatNumber(n.abs, maxCoefficientsColumnSize)  def formatUnknown(index: Int) = "x("+("%0"+maxColsSize+"d" format index)+")"    // On Scala 2.8, replace drop(1) with tail and first with head below  def formatLine(coefficients: Array[Int],                  constant: Int,                  printUnknown: Int => String) =    coefficients    .zipWithIndex    .drop(1)    .foldLeft(formatCoefficient(coefficients.first)+printUnknown(0))(      (x,y) => x+numberSign(y._1)+formatCoefficient(y._1)+printUnknown(y._2)    )+" = "+formatConstant(constant)  def makeString(printUnknown: Int => String) = (    for(row <- 0 until m.rows)    yield formatLine(m.row(row), r(row,0), printUnknown)  ).mkString("\n")      override def toString = makeString(formatUnknown)    def getUnknowns(u: MatrixInt): Int => String =    (index: Int) => " * "+u(index,0)  lazy val solutionInverse: Option[MatrixInt] =    if (m.inverse == None)      None    else      Some(m.inverse.get * r)   def solveInverse =    if (solutionInverse == None)      "There is no unique solution"    else      makeString(getUnknowns(solutionInverse.get))   lazy val solutionCramer: Option[MatrixInt] = {    val vector = r.toArray.flatMap(x => x)    if (m.determinant == 0)      None    else      Some(MatrixInt(        for((col: Int) <- (0 until m.cols).toArray)        yield Array(            m.replaceCol(col, vector).determinant / m.determinant           )      ))  }        def solveCramer =    if (solutionCramer == None)      "There is no unique solution"    else      makeString(getUnknowns(solutionCramer.get))}`