カテゴリー

最新の記事

最近のコメント

最近のトラックバック

月別アーカイブ

ブログ検索

RSSフィード

ブロとも申請フォーム

この人とブロともになる

スポンサーサイト

スポンサー広告
--.--.--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ベンチャーブログのランキングに参加しています。
下のバナーをクリックして応援していただけると嬉しいです。
にほんブログ村 ベンチャーブログへ

Newton法で方程式を解く

Scheme/Gauche
2008.12.06
新しい言語のスタディを始めると、やはり簡単なプログラムを作って、これまで使っていた言語との比較を行いたくなる。前回ちょっと言及した東京大学理学部の「Scheme演習」の中に「Newton法で方程式を解け」という問題があったので、やってみることにした。

解を求めたい方程式を

 f(x)=0


とすると、Newton法による方程式の解は以下のように求められる。

Step1.
まず任意のxにおけるf(x)の微分値を求める関数を作成する。この関数を deriv(x) とする。deriv(x)は以下のように定義できる。

 deriv(x) = ( f(x+dx) - f(x) ) / dx



dxが十分に小さい値であれば、deriv(x)の値は十分に微分値に近づくと考えられる。

Step2.
適当なxの値(これを a とする)におけるf(x)の値を求める。つまりf(a)を求めるわけである。

Step3.
x=a における deriv(x) 、つまり deriv(a) を求める。

Step4.
( a - f(a) / deriv(a) ) を求め、これを新しい a とする。

Step5.
Step2~4を繰り返し、f(a)の値を0に近づける。0との差が十分に小さい値になったときに(これを dy とする)、その時の a の値を方程式の解とする。

方程式によっては、最初のaの値によって求められる解が変わってしまったり、解が得られないこともあるが、とりあえず上記の方法で解を求めてみよう。

Scheme/Gaucheでプログラムを作成した場合、コードは次のようになる。

 (define (newton func a dx dy)
  (define (deriv x)
    (/ (- (func (+ x dx))(func x)) dx))
  (cond ((< (func a) dy) a)
    (else (newton func (- a (/ (func a) (deriv a))) dx dy))))


ここで以下のようにf(x)を定義し

 (define (f x)(- (* x x) 2))



以下のようにnewtonを呼び出せば、

 (newton f 5 0.0000000001 0.0000000001)



方程式のひとつの解が得られる。

 gosh> 1.4142135623730887



さてこれを、PHPで書いたらどうなるだろう?
再帰処理を使う場合には、次のようになるはずだ。

 function deriv($f,$x,$dx){
  return((call_user_func($f,$x+$dx)-call_user_func($f,$x))/$dx);
 }

 function newton($f,$a,$dx,$dy ){
  if(call_user_func($f,$a)<$dy){
   return($a);
  }else{
   return(newton($f,$a-(call_user_func($f,$a)/deriv($f,$a,$dx)),$dx,$dy));
  }
 }


さらに f(x) を定義し、newtonを呼び出せばいい。

 function f($x){
  return($x*$x-2);
 }

 echo newton('f',5,0.0000000001,0.0000000001);


Webブラウザからこれを実行すれば、以下のように表示される。

 1.4142135623731



Scheme/Gaucheのように関数内で関数を定義することもできるが、再帰処理を行う場合には内部で定義した関数が重複定義となるため、実行時にエラーになる。そのため微分値を求める deriv 関数は newton 関数の外で定義している。

再帰処理をループに置き換えれば、deriv 関数を newton 関数の中に定義することもできる。

 function newton( $f, $a, $dx, $dy ){
  function deriv( $f, $x, $dx){
   return( ( call_user_func( $f, $x + $dx ) - call_user_func( $f, $x ) ) / $dx );
  }
  while( call_user_func( $f, $a ) >= $dy ){
   $a = $a - ( call_user_func( $f, $a ) / deriv( $f, $a, $dx ) );
  }
  return( $a );
 }


使用法は同じである。

さて、この程度のプログラムであれば、どちらでも簡単に実現できる。ここで私が注目したいのは、どちらの方がシンプルで美しく見えるか、ということである。個人的にはScheme/Gaucheの方がまとまりがいいような気がする。例えばPHPの call_user_func は、ちょっとしたハックの匂いがする。関数名ではなくて、関数そのものを渡せればいいのになあ、と思っちゃうわけだ。

まあこれは、好みの問題なのかもしれませんけどね。

ベンチャーブログのランキングに参加しています。
下のバナーをクリックして応援していただけると嬉しいです。
にほんブログ村 ベンチャーブログへ

Scheme/Gaucheのスタディを開始。

Scheme/Gauche
2008.12.05
先週から本格的に「Scheme/Gauche」のスタディを開始した。実はそれ以前からも「プログラミングGauche」を手に入れて読んでいたのだが、今年秋に作成したPHPフレームワークもどき(PnFのこと)のことが気になって、なかなか集中できなかったのである。

すでに他のフレームワークを使っている人にとって、PnFはまったく意味をなさないだろうし、これからフレームワークを導入したい人にとっても選択肢にはなり得ないだろう。しかしPnFのソースコードは「自分を何とかしろ」と訴え続けていたのだ。単にお蔵入りにするのではなく、何らかの形で日の当たる場所に出せと。だからPnFのソースコードを公開した。まだ実用性は乏しいかも知れない。でもこのソースコードを見ることで、オブジェクト指向のパワーを具体的な形で理解する人くらいは、いるかも知れない。もしいなくても構わない。これでコードに対する義理は果たしたのだ。

というわけで、PnFを公開したことで「一段落ついた」と感じている。これでようやく後ろ髪を引かれることなくScheme/Gaucheのスタディに専念できるようになった。とはいえ今の自分は坊主頭なので、物理的には「引かれるほどの後ろ髪」はないのだが。

Scheme/GaucheはLISP族の言語である。そしてここで正直に言ってしまえば、私は20年前にLISPに挫折したことがある。括弧の嵐や前置オペレータ、ラムダ、クロージャなどがうまく理解できなかったのである。それに当時の私にとって、プログラミング言語のヒーローはC言語だった。C言語さえ使いこなせれば何でもできる。そう思ったので、LISPが使いこなせなくても「まあいいや」と考えたのだ。

しかしScheme/Gaucheをスタディするようになって、その考え方は間違いだったと気づかされた。LISP族の言語はちょっとおかしな風貌をしているが、ものすごくパワフルだということがわかったのだ。今では括弧の嵐も好きになったし(Emacsなら対応する括弧もすぐわかるし)、前置オペレータの必然性も理解できる。またラムダやクロージャのパワーも感じている。それに強力なマクロや明示的な環境操作も面白い。この言語を使いこなすことで、すごいことができるのではないかと感じている。

入手可能な教材はけっこうある。「プログラミングGauche」は非常に内容が濃いし、ネット上にもそれなりに情報がある。また東京大学理学部の「Scheme演習」の講義用資料もダウンロード可能だ。この資料には「出席はとらないので必ずしも出席する必要は無い。遅刻、途中退室してもかまわない。」と明記されており、資料はネットからダウンロードすべきというスタンスらしい。こういう講義が増えれば、大学に行くことなく学習を進めることができる。私のような人間にとっては非常にありがたい。

Scheme/Gaucheのコードを見ると、それだけでわくわくする。こんな気持ちになったのは、C言語に出会って以来のことだ。読むだけでは理解できない場合は、とりあえずEmacsにコードを入力し、インタプリタで実行してみる。これだけで「ああ、そういうことだったのか」と思えることも少なくない。理解できればバリエーションを考えてみる。クロージャで記述されているコードをオブジェクト指向的に書き直してみるとか。これもまた面白い。

とはいえ、理解度はまだ半分くらい。継続という概念はまだ十分理解できたとはいえないし、これをWebアプリケーションで活用する方法についてもスタディが終わっていない。できるだけ短期間でマスターすべく、頑張っているところなのである。

ベンチャーブログのランキングに参加しています。
下のバナーをクリックして応援していただけると嬉しいです。
にほんブログ村 ベンチャーブログへ

PHPフレームワークもどき「PnF」(10)~ソースコード

PHP
2008.11.26
PnFのコアと「PHPフレームワークもどき「PnF」(3)~サンプルアプリを作ってみよう」に掲載したサンプルアプリのソースコードを公開します。以下のリンクをクリックすると、アーカイブファイルをダウンロードできます。

ダウンロード pnf_sample.tar.gz (32.1K)

このファイルを適当なところにダウンロードし、アーカイブを展開してください。Linux上で作成したtarボールなので、以下のLinuxコマンドで解凍できます。pnf_sampleというディレクトリが作成され、その下にファイルが展開されます。

tar xvzf pnf_sample.tar.gz

Windows上にダウンロードし、右クリック→即時解凍でも解凍できると思います(Windows XP Proで確認)。ただし日本語のエンコーディングがUTF-8なので、ファイルを読むときにはUTF-8をサポートするエディタを使用してください。コード本体には日本語文字列を使っていないはずですが、コメントはすべて日本語で記述されています。

PHPが動く環境で、Apacheのドキュメントルートの下にファイルを展開した場合には、サンプルアプリを実行できます。例えばドキュメントルート直下でアーカイブを展開した場合には、以下のURLでサンプルアプリにアクセスできるはずです。

http://<HTTPサーバーのサーバー名かIPアドレス>/pnf_sample/sample.php

なお申し訳ありませんが、現時点ではまともなドキュメントはありません。可読性を意識してソースを書いたつもりなので、もしよろしければソースコードを追いかけてみてください。sample.phpから呼び出されているMainProcedure.class.phpから順番にソースを追いかけていけば、何をしているのかがわかると思います。なおDataModelディレクトリにあるクラスファイルは、データベーステーブルの構成に依存する内容になっているので、とりあえずは無視してください。

大まかな内部処理は、以下のチャートのようになっています。
(クリックすると拡大表示されます)

処理の流れ

著作権は放棄しませんが、このソースコードをどのように使っていただいても構いません。ただし何らかのレスポンスをいただけることを期待しています。

よろしくお願いします。

ベンチャーブログのランキングに参加しています。
下のバナーをクリックして応援していただけると嬉しいです。
にほんブログ村 ベンチャーブログへ

PHPフレームワークもどき「PnF」(9)~サンプルコード、画面全体の構成

PHP
2008.11.24
最後に画面全体の構成をコードに落としていきましょう。まず前半部分です。

コード9-1

5~6行目
アプリケーション全体の設定ファイルと、PnFのメインプロシジャのファイルをインクルードしています。

9~11行目
この画面の名前(コントロール名)を設定しています。この設定はPnFの内部処理に使用するものです。

14~28行目
この画面で使用するVCを宣言しています。「ItemBox」が宣言されていないことに注意してください。別のVCの子VCとして生成されるVCは、ここで宣言する必要はありません。

31行目
PnFのメインプロシジャを呼び出しています。

なお前半部分でページ毎に記述が変わるのは、14~28行目の「使用するVCの宣言」の部分だけです。他のコード記述は固定です。

次に後半部分です。

コード9-2

HTMLテンプレートの記述です。画面全体のHTMLテンプレートも、PHPの関数として記述します。47~56行目はヘッダ部分、58~72行目がボディ部分です。ボディ部分に${vc[VC名]}という記述が埋め込まれています。$vcはこのHTMLテンプレートがPnFコアから呼び出される時に引き渡される引数であり、ここに使用するすべてのVCのHTML記述が連想配列として格納されているのです。

なお「config.php」の内容と、CSSファイルの内容は以下の通りです。

config.php
コード9-3

CSSファイル(style.css)
コード9-4

以上でサンプルアプリケーションのコード解説を終わります。簡単なものでしたが、PnFを使ったコーディングの概要がご理解いただけたのではないかと思います。

コード量は決して大幅に減るわけではないのですが、画面全体、各VC、各VPの独立性が極めて高く、簡単に分離・結合できる点が最大のメリットです。そのため複雑な画面構成を持つアプリケーションでも、適当な要素に分割して開発生産性を高めることができ、特定要素の修正が他の部分に与える影響も最小化できます。もちろんいったん作成したVCやVPは、簡単に再利用できます。イベント名と引き渡されるイベントパラメーターの整合性さえ取れていれば、画面全体構成のコードに追加するだけでいいからです。

ただし最初に指摘したとおり、まだ十分に練れていない部分もかなりあります。例えばGET変数をVCで処理するのが適切なのか、まだ十分に検討されていません。他にも検討の余地が残っている部分があります。

ここまでの内容に対してそれなりの反応があれば、さらに詳細な説明を行い、PnF内部のコードの公開も検討したいと思っています。もし芳しい反応がなければ、公開作業は中断します。質問や意見などがございましたら、各エントリーのコメントの形で投げてください。それではよろしくお願いします。

ベンチャーブログのランキングに参加しています。
下のバナーをクリックして応援していただけると嬉しいです。
にほんブログ村 ベンチャーブログへ

PHPフレームワークもどき「PnF」(8)~サンプルコード「ItemBox」

PHP
2008.11.24
VCのコードとしてはこれが最後です。「ItemBox」のコードです。

コード8-1

3~5行目
まずVCの親クラスをインクルードし「VcItemBox」クラスを派生させます。

14~22行目
「ItemBox」が保持すべきプロパティ情報を宣言します。ここでは「詳細」を表示するか否かのステータス情報を保持する「ShowDescription」を宣言しています。

24~58行目
「ItemBox」で使用するVPを宣言しています。「Name」「Mail」「Description」はテキスト表示要素、「Navigation」はひとつの要素だけを持つナビゲーションリンクです。このナビゲーション要素は「SWITCH_DESCRIPTION」というローカルイベントを発生させるように設定されていますが、表示文字列はブランクになっています。表示すべき文字列は「詳細」の表示状態によって変わるからです。

コード8-2

61行目
「ItemBox」が引き受けるGET変数の定義です。このVCはGET変数を引き受けないため、空配列を記述しておきます。

64~78行目
「ItemBox」がサブスクライブするイベント名と、各イベント名に対応するアクションメソッド名の定義です。「SWITCH_DESCRIPTION」を受け取った時には「switchDescription」、「CLEAR_LIST」を受け取った時には「clearItem」、「REFRESH」を受け取った時には「refreshViewData」を呼び出します。

コード8-3

85~109行目
イベント処理チェーンに入る直前に実行したい処理を「前処理」として記述します。「ItemBox」は生成されたときに表示すべき情報を受け取るため、その情報をVPプロパティに反映させる必要があります。またナビゲーションの表示文字列も「詳細」の表示状態に合わせて変更する必要があります。例えば「詳細」が表示されていないのであれば「詳細を表示する」、表示されているのであれば「詳細を隠す」にするわけです。ここではこれらの処理を行っています。

111~138行目
アクションメソッド「switchDescription」の処理内容です。このアクションメソッドは「詳細」の表示状態を切り替えます。まず現在の表示状態を「$this->getVcProperty」で取得し、その内容に応じて値をスイッチし、スイッチした値を「$this->setVcProperty」でセットします。またこの時、ナビゲーションの表示文字列も変更します。

140~144行目
アクションメソッド「cleaItem」の処理内容です。自分自身に割り当てられたSESSION変数の内容をアンセットします。これを行わないと「アイテムを登録」→「アイテムリストのクリア」→「再びアイテムを登録」を行った時にVC名が使い回されるため、古いSESSION変数が使用され、不適切な表示状態になる可能性があるからです。動的に生成され、VC名が使い回される可能性のあるVCでは、必ずこのような処理を行う必要があります。

146~147行目
REFRESHイベントに対応した処理の記述です。ここでは何も行いません。

コード8-4

HTMLテンプレートです。「ShowDescription」の内容によって「詳細(description)」の表示を切り替えています。

これでサンプルアプリケーションに必要なVCのコードがすべて揃いました。

ベンチャーブログのランキングに参加しています。
下のバナーをクリックして応援していただけると嬉しいです。
にほんブログ村 ベンチャーブログへ

FC2Ad

相続 会社設立

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。