scalaで行列(3)
くどいですが、また書き換えてみました。
前回は二項演算子を引数にとって行列の各要素の演算を行うmopというメソッドを作ったのですが、
それの行バージョンのropというメソッドを加えてみました。
(import文とMatrixクラスのみ抜粋)
import scala.math.Numeric class Matrix[T: Numeric](val elms: M[T]) { override def toString() = (this.elms map (_.mkString("[", ",", "]"))).mkString("", "\n", "\n") def rop(rthis:R[T],rthat:R[T])(op: F[T]):R[T]=(rthis zip rthat)map (t => op(t._1,t._2)) def mop(that: Matrix[T])(op: F[T]): Matrix[T] = new Matrix[T]( ( this.elms zip that.elms) map (t => rop(t._1,t._2)(op(_,_))) ) 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 transpose = new Matrix[T](this.elms.transpose) def dotProduct(a: R[T], b: R[T]): T = (rop(a,b)(this.*(_,_)).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))) ) }
さらにScala2.9からNumericが*,+,-をメソッドに持つ structual subtypingのように扱えるようになったので
import Numeric.Implicits._ class Matrix[T: Numeric](val elms: M[T]) { override def toString() = (this.elms map (_.mkString("[", ",", "]"))).mkString("", "\n", "\n") def rop(rthis:R[T],rthat:R[T])(op: F[T]):R[T]=(rthis zip rthat)map (t => op(t._1,t._2)) def mop(that: Matrix[T])(op: F[T]): Matrix[T] = new Matrix[T]( ( this.elms zip that.elms) map (t => rop(t._1,t._2)(op(_,_))) ) def +(that: Matrix[T]): Matrix[T] = this.mop(that)(_+_) def -(that: Matrix[T]): Matrix[T] = this.mop(that)(_-_) def transpose = new Matrix[T](this.elms.transpose) def dotProduct(a: R[T], b: R[T]): T = (rop(a,b)(_*_)).reduceLeft(_+_) def *(that: Matrix[T]): Matrix[T] = new Matrix[T]( (for (rthis <- this.elms) yield (for (cthat <- that.elms.transpose) yield dotProduct(rthis, cthat))) ) }
当初の思惑に近づいてすっきりした気もしますが、隠語の羅列のような気もします。