scalaで行列(2)
行列のプログラムがようやくできました。
足し算と掛け算を定義しただけですが、行列の係数の型をパラメータでとれるようにしました。
結構、むずかしかったです。
package mnru.matrix object MatrixField { type F[T] = (T, T) => T type R[T] = List[T] type M[T] = List[R[T]] import scala.math.Numeric class Matrix[T: Numeric](val elms: M[T]) { override def toString() = (this.elms map (_.mkString("[", ",", "]"))).mkString("", "\n", "\n") def mop(that: Matrix[T])(op: F[T]): Matrix[T] = new Matrix[T]( (for ((rthis, rthat) <- this.elms zip that.elms) yield for ((ethis, ethat) <- rthis zip rthat) yield op(ethis, ethat)) ) // def mop(that: Matrix[T])(op: F[T]): Matrix[T] = new Matrix[T](((this.elms zip that.elms).map(t => ((t._1 zip t._2)).map(s => op(s._1, s._2))))) def +(a: T, b: T) = implicitly[Numeric[T]].plus(a, b) def -(a: T, b: T) = implicitly[Numeric[T]].minus(a, b) def *(a: T, b: T) = implicitly[Numeric[T]].times(a, b) def +(that: Matrix[T]): Matrix[T] = this.mop(that)(this.+(_, _)) def -(that: Matrix[T]): Matrix[T] = this.mop(that)(this.-(_, _)) def dot(that: Matrix[T]): Matrix[T] = this.mop(that)(this.*(_, _)) def transpose = new Matrix[T](this.elms.transpose) def dotProduct(a: R[T], b: R[T]): T = (for ((x, y) <- a zip b) yield this.*(x, y)).reduceLeft(this.+(_, _)) def *(that: Matrix[T]): Matrix[T] = new Matrix[T]( (for (rthis <- this.elms) yield (for (cthat <- that.elms.transpose) yield dotProduct(rthis, cthat))) ) } val matA = new Matrix[Int](List(1 :: 2 :: 3 :: Nil, 4 :: 5 :: 6 :: Nil)) val matB = new Matrix[Int](List(7 :: 8 :: 9 :: Nil, 10 :: 11 :: 12 :: Nil)) // val matC = matA.mop(matB)(_ + _) val matC = matA.transpose val matD = matB * matC def main(args: Array[String]) { println(matA) println(matB) println(matC) println(matD) } }