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)

  }


}

scalaで行列(1)

scalaで行列演算のプログラムを書いているのですがなかなかうまくいきません。
mop という2項演算子を引数に取って各要素ごとに演算を実行するメソッドを作ったのですが、それを使って+をうまく定義できないところで躓いてます。
どこが悪いかわかる方はコメントをいただけると助かります。


matC=matA. mop( matB) (_ + _)                          //動く
def +(that: Matrix[T]) = this.mop(that)(_ + _)                 //動かない
matC = matA + matB 


package mnru.matrix


object MatrixField {
  type F[T] = (T, T) => T
  type M[T] = List[List[T]]


  class Matrix[T](val elms: M[T]) {

    override def toString()= (this.elms map (_.mkString("[", ",", "]"))).mkString("\n")


    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 +(that: Matrix[T]) = this.mop(that)(_ + _)


  }


  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 + matB              //動かない 


  def main(args: Array[String]) {

    println(matC)
  }


}

もうすぐtortoiseHG2.0が出そうですけど、僕のtortoise HG 1.1.9の設定・導入方法をメモして置きます(windows7,32bit版)。
PyQt port(2.0の前身)ではうまく動かなかったので、誰か対処法を教えてもらえると助かります。

参考にしたサイトを書いておきます。

http://avr.paslog.jp/article/1617629.html
Bitbucket | The Git solution for professional teams
TortoiseHg で日本語ファイル名 - あすかぜ・ねっと

めざしたのは、

です

といった制約があるもののおおむねうまくいっていると思います

手順

1.tortoisehgをインストールする。
2.puttyごった煮版をインストールする
3.「c:\hgex」というディレクトリを作って

   hg clone http://bitbucket.org/durin42/hg-git/ C:/hgex/hg-git
   hg clone http://bitbucket.org/durin42/hgsubversion/ C:/hgex/hgsvn
   hg clone http://bitbucket.org/tinyfish/hg-fixutf8/ C:/hgex/hg-fixutf8

というコマンドを次々に実行する
4.mercurial.iniというファイルに以下の設定を書く

[extensions]
hgext.bookmarks =
hggit = C:\hgex\hg-git\hggit
hgsubversion = C:\hgex\hgsvn\hgsubversion
fixutf8 = c:\hgex\hg-fixutf8\to\fixutf8.py

5.ユーザー設定でユーザー名を設定する
6.環境変数を以下の設定にする
LANG=ja
HGENCODING=utg-8
7.TortoiseHgをインストールしたフォルダにある「TortoisePlink.exe」を
コピーして「ssh.exe」にリネーム
8.github,bitbucketにアカウントを作る
9.puttygenで作った公開鍵をgithubとbitbucketにコピペ(それぞれ別)。秘密鍵をファイルとして保存する。



はしょってますが設定・導入法はこんな感じです。
使い方は参照先のサイトのほうが図もあってわかりやすいです。

のwindows用バッチファイルを作ってみた。

http://code.google.com/p/simple-build-tool/wiki/Setup
で紹介されているsbt.batファイル中を

sbt-launch-***.jarの***の部分をバージョンによって書き直さなくてもいいようにしてみました。

使い方は

  1. sbt-launch-***.jarとsbt.batの改変版をpathの通ったフォルダにいれる。(sbt-launch-***.jarというファイルはフォルダ内でダブらないようにする)
  2. プロジェクトをおく空のフォルダを作り、そのフォルダでコマンドプロンプトを開く
  3. sbtと打ち込む(プロジェクトの作成が始まる)


sbt.bat(改変版)

  @ echo off
set SCRIPT_DIR=%~dp0
for %%i in ("%SCRIPT_DIR%sbt-launch-*.jar") do  (
java -Xmx512M -jar "%%i" %*
)


稚拙なバッチファイルですが、よろしければお使いください。

factorもどき


inforno :: Scalaでスタック指向言語をサクッと実装する や 合併のお知らせ|OKIソフトウェア
を参考に自分もfactorもどきをscalaでかいてみました。かなりコピペしています。
かなりいろんなことをはしょっています。

import scala.util.parsing.combinator._
import java.io.{FileReader, InputStreamReader}
import scala.collection.mutable.{Stack,  HashMap}


class TinyFactorParser extends JavaTokenParsers {

var quoteIndex = 0
def quoteName = { quoteIndex += 1 ;"quot"+ quoteIndex}

var qTable=new HashMap[Any,List[Any]]()

lazy val item:Parser[Any] = quotation|
"true" ^^^ true|"false" ^^^ false |
  stringLiteral ^^ (s => s.substring(1, s.length() - 1)) |
   """[a-zA-Z_0-9\+\-\*\<\>\=]+""".r ^^
    (s => try {s.toLong} catch {case ex: NumberFormatException => Symbol(s)})

lazy val quotation:Parser[Any]="[" ~> rep(item) <~ "]" ^^
		{script =>{var name =  Symbol("")  ;name=Symbol(quoteName); qTable += (name -> script);name}}
lazy val word:Parser[(Any,List[Any])]=":" ~>rep(item)<~ ";" ^^
		{case name::script => (name -> script)}
lazy val program:Parser[HashMap[Any,List[Any]]]=rep(word) ^^ {HashMap() ++= _ }

}


object TinyFactor{

var dataStack= new Stack[Any] ()
var procStack= new Stack[Any] ()

var quoteTable=new HashMap[Any,List[Any]]()
var wordTable=new HashMap[Any,List[Any]]()


def pop=dataStack.pop
def push(v:Any)=dataStack.push(v)

   def ilB2(f:(Long,Long)=>Boolean){(pop,pop) match{
	  case (x,y)=>
    	dataStack.push(f(y.asInstanceOf[Long],x.asInstanceOf[Long]))
      }}

   def iArI2(f:(Long,Long)=>Long){(pop,pop) match{
	  case (x,y)=>
    	dataStack.push(f(y.asInstanceOf[Long],x.asInstanceOf[Long]))
      }}


def callWord(x:Any,y:HashMap[Any,List[Any]]){procStack++=y(x).reverse}



 val execTable:HashMap[Any,()=>Unit]= HashMap(

		(Symbol("drop"),  ()=>{ pop }),
		(Symbol("dup"),  ()=>{val v= pop;push(v);push(v) }),
	 	(Symbol("swap"),()=>{(pop,pop) match {case (x,y) => {push(x);push(y)}}}),
		(Symbol("rot"),()=>{(pop,pop,pop) match {case (x,y,z) => {push(x);push(z);push(y)}}}),
		(Symbol("if"),()=>{(pop,pop,pop) match {case (x,y,z) =>{if(z==true) callWord(y,quoteTable) else callWord(x,quoteTable)}}}),
		(Symbol("dip"),()=>{(pop,pop) match {case (x,y) => {procStack.push(y);callWord(x,quoteTable)}}}),

	    (Symbol("+"),() => {iArI2(_+_)}),
	    (Symbol("-"),()=> {iArI2(_-_)} ),
	    (Symbol("*"),()=> { iArI2(_*_)} ),
	    (Symbol("/"),()=> { iArI2(_/_)} ),
	    (Symbol(">"),()=> { ilB2(_>_) } ),
	    (Symbol("<"),()=> { ilB2(_<_) } ),
	    (Symbol(">="),()=> { ilB2(_>=_)} ),
	    (Symbol("<="),()=> { ilB2(_<=_) } ),
	    (Symbol("=="),()=> { ilB2(_==_) } )

	 	)

def displayStack{   println("dataStack:"+dataStack.toString)
					println("procStack:"+procStack.toString)}



def main(args: Array[String]) {
val reader = if (args(0) == "-") new InputStreamReader(System.in)
else new FileReader(args(0))
val parsers = new TinyFactorParser
 wordTable = parsers.parseAll(parsers.program, reader).get
 quoteTable=parsers.qTable


 def evalProcTop{
	 procStack.pop match {

		 case x if quoteTable.contains(x) => {push(x)}
		 case x if wordTable.contains(x) => {callWord(x,wordTable)}
		case x if execTable.contains(x) => {execTable(x) () }
		 case x => push(x)
			     }

		}

def evalProcAll{ while( ! procStack.isEmpty ){displayStack;evalProcTop} }

println(wordTable)
println(quoteTable)



callWord(Symbol("main"),wordTable)
evalProcAll

displayStack


}

}