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 で日本語ファイル名 - あすかぜ・ねっと
めざしたのは、
- プラグインをいれて、git、subversionのリポジトリをmercurialのリポジトリのように扱えるようにする
- githubやbitbucketを扱えるようにする
- ファイル名をutf-8にして日本語を使えるようにする
です
- githubからhttpやhttpsでクローンできない
- gitとsubversionのプラグインが干渉して切り替えに設定ファイルをいじらないといけない
といった制約があるもののおおむねうまくいっていると思います
手順
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の***の部分をバージョンによって書き直さなくてもいいようにしてみました。
使い方は
- sbt-launch-***.jarとsbt.batの改変版をpathの通ったフォルダにいれる。(sbt-launch-***.jarというファイルはフォルダ内でダブらないようにする)
- プロジェクトをおく空のフォルダを作り、そのフォルダでコマンドプロンプトを開く
- 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 } }