2009-12-07[n年前へ]
■エクセルの計算ワークシートをRuby計算スクリプトに変換してみよう
下記で使ったエクセルファイルは、自己参照部分がなく、つまり反復計算が必要ないものを使ってしまいました。反復収束計算が必要なエクセルファイルを「続 エクセルの計算ワークシートをRubyでC言語に変換してみよう」 でサーバ内に置きましたので、下記記事を読んだ後には、上記記事(さらにその後に続く記事など)を引き続きご覧ください。
目的に対して達成方法があまりに過剰、あるいは、あまりに的外れで荒唐無稽なものというのは、それはそれで何だか面白いような気がします。
今日は、そんなものを、ふと、けれど無性に作ってみたくなりました。
先日、Microsoft Excelのような「表計算ソフト」スプレッドシートを使った「静電界計算や非定常熱伝導シミュレーション計算」をみっちりしてきました。離散化された物理式を表計算ソフトウェアを用いて計算を行うというのは、「セル」というメッシュと空間が感覚的に近く感じられることから、とても自然にシミュレーション計算を行う空間分割と計算領域との対応を感じることができるのが、とても便利で良いと思っています。
もちろん、セル間の計算を「反復計算」を行うことで、複雑なことを気にせず、計算が自然に終わってしまう、というのも実に「自然」で「お手軽」で良い、と思っています。
とはいえ、私はエクセルは苦手です。毎年何回か、エクセルでのシミュレーション計算を(悩んでいる)人に教えるという作業をするのですが、それでもエクセルを使うのは苦手です。そこで、エクセルで作った離散化シミュレーション用.xlsシートをRuby Script(プログラム)に自動的に変換する、Rubyスクリプトを作ってみることにしました。そう、「エクセルで物理シミュレーションを学んだ人が、そのエクセルシートをそのまま多言語に移植することができる」スクリプトを作ってみよう、と考えてみたのです。
作ったコードxls2rb.rbは次のようになります(近日中にサーバに置いて置きます)。これは、「反復計算を使った」エクセルファイルを読み込み、それをRubyスクリプトに変換するスクリプトです。「表計算ソフト」スプレッドシートを使いった「静電界計算や非定常熱伝導シミュレーション計算」は、四則演算と周囲の空間が持つ値の計算だけで行うことができます。だから、そういう「条件」下では、そんなスクリプトを作るのも比較的簡単です。初期化や反復計算をそれぞれ「関数」化しているとはいえ、変数はすべてグローバル変数ですし、そこら辺の「エクセル感」も再現してみたスクリプトです。
require 'win32ole' def getAbsolutePath(filename) fso=WIN32OLE.new('Scripting.FileSystemObject') fso.GetAbsolutePathName(filename) end def getAlphabet(n) val=n.to_f/25.0 mod=n%25 result='' result+=('a'..'z').to_a[(n-val)/25] if val>1 result+=('a'..'z').to_a[mod] end def defFunc(state,book) src='' book.Worksheets.each do |sheet| y=1 sheet.UsedRange.Rows.each do |row| x=0 record=[] row.Columns.each do |cell| if state==:init &&cell.Value!='' record<<' '+'$'+getAlphabet(x)+y.to_s+ '='+cell.Value.to_s if cell.Value.to_s!='' end if state==:calc &&cell.Formula!='' t=cell.Formula.sub(/[=$]/,'') t=t.downcase.gsub(/([a-zA-Z]+\d+)/,'$\1') record<<' '+'$'+getAlphabet(x)+y.to_s+'='+t end x+=1 end src+=record.join("\n")+"\n" if record.join('').gsub("\n",'')!='' y+=1 end end return src end filename=getAbsolutePath(ARGV[0]) excel=WIN32OLE.new('Excel.Application') book=excel.Workbooks.Open(filename) initsrc=defFunc(:init,book) calcsrc=defFunc(:calc,book) book.close excel.quit GC.start puts <<INIT # autocreated ruby script from excel file # jun hirabayashi jun@irax.net http://www.hirax.net def init #{initsrc}end def calc #{calcsrc}end 10.times do calc end INIT
ちなみに、このスクリプトを
ruby xls2rb.rb ex.xlsという具合にして(引数は変換したいXLSファイルです)、実行すると、次のようなスクリプトができあがります。ちなみに、ここで使ったex.xlsファイルは、ラプラス方程式を3X3のセルに離散化し解く、実に単純なエクセルシートです。(この辺りのファイル一式を週末にでもサーバ上に置いておきます)
# autocreated ruby script from excel file # jun hirabayashi jun@irax.net http://www.hirax.net def init $a1=1.0 $b1=2.0 $c1=3.0 $a2=1.0 $b2=2.0 $c2=5.0 $a3=1.0 $b3=2.0 $c3=3.0 end def calc $a1=1 $b1=2 $c1=3 $a2=1 $b2=2 $c2=$b2+$c1 $a3=1 $b3=2 $c3=3 end 10.times do calc endつまり、今日私が作ったスクリプトの動作は、エクセルが最初に行う初期化ルーチンを"init"関数として定義(作成)し、次に行う反復計算を"calc"関数として定義(作成)し、それを(適当に決めた)10回繰り返すスクリプトを作り出す、という具合です。ポイントは初期化時には、cell.Valueを用いることで初期数値を設定し、逐次計算時にはcell.Formulaを使うことで数式を使う、という「使い分け」になります。反復計算自体は、ガウスザイデル法によって行われます。
あとは適当に、知りたい値を出力する(たとえば、"puts $c2"といった)出力処理文でも書き足せば、はい、シミュレーション・rubyプログラムのできあがり、というわけです。
離散化された物理計算をするために作成したエクセル・シートを、Rubyスクリプトに自動で変換し、好きに加工できるプログラム…って便利なような、そもそもそんな用途ってある訳ないような…というのが正直で的確な感想だと思います。つまり、それはかなり無意味なツールです。
他の言語に置き換えて、高速化指向の変換プログラムを書いてみるのも(一回くらいはやってみようと思いますが、今ひとつ「魅力」に欠けるように思います。
今日作った、「離散化された物理現象を計算するために作成したエクセル・シートを、Rubyスクリプトに自動で変換するプログラム」なんていうものを、(何だか馬鹿馬鹿しいけれど)意外に少し面白い笑える、そう思える人が一人でもいたら、幸いに思います。
2012-07-02[n年前へ]
■ポアソン方程式は「ふたつの胸の膨らみ」で、ラプラス方程式は「胸の谷間の曲面」だ!?
真空中に円板(平坦)状の電荷分布が離れて「ふたつ」あった場合の電位分布、それをポアソン(ラプラス)方程式を解いてグラフにしてみました。円板状といっても、つまりはとても「平坦」な電荷分布が作り出す電位分布は、実に魅力的な曲面です。下に貼り付けた曲面グラフは、小さな平円板状電荷が離れてあった場合の電位分布を計算してみた結果です。
ラプラス作用素 ∇・(∇)は、この曲面でこそ、一番わかりやすく実感できます。 ラプラス作用素 がゼロでない値になるという「ポワソン方程式」は、「平面を押し上げるふたつの胸の膨らみ」で「 ラプラス作用素 がゼロでない=盛り上がっていること(あるいは堀りえぐれていること)」実感することができます。…そして、ラプラス作用素 がゼロになるというラプラス方程式は、「胸の谷間の”馬の鞍”状の双曲面」のように、ある軸に曲がりがあったとしたら・(その軸の曲がりを生むように)その他の軸は逆の向きに曲がっているという状態を実感できるはずなのです。
2017-09-01[n年前へ]
■下着マチ部分の「わずかな凹凸」がなぜボトムスの上から視認されるのか?
平日のラッシュ時間、駅のホームから上がる階段は、人がギュウギュウに詰まっている。 その階段を登りながら、こう考えた。
職場や学校に向かうだろ多くの人に挟まれて、密度高く窮屈に階段を昇っていると、ちょうど1メートルくらい先の正面に、階段を上る女性がいる。 私の顔のちょうど正面に彼女のヒップがあるせいか、それとも何か他のユング心理学的な何か深層心理の原因があるせいか、とにかくその球面状のヒップが目に入る。 もしかしたら、そのヒップが気になったのは、下着の線が浮かび上がっていたせいかもしれない。 女性はストレッチ素材のボトムス(ズボン)をはいていて、階段を昇るために足を上げる動作をするせいか、ボトムスに明瞭に下着の線が浮き上がっている。 それは、下着のアウトラインだけでなく、股部分の左右を繋ぐ「マチ」も線となり浮き上がり、それはまさにあだち充が描く「ムフ♡!」的な気持ちを思い起こさせた。
人が何に「ムフ♡!」を感じるかは、それはまさに個性で、その人次第に違いない。 けれど、私の場合は、下股部分の左右を繋ぐ、上を凸とする「マチ」の円弧状の曲線に、「ムフ♡!」を感じるらしい。それはもしかしたら、あだち充ではなくて、桂正和の影響だったのかもしれない。
そこまで考えが漂流してきた時に、こんな疑問が湧いてくる。 「なぜ、下着のマチ部分を、ボトムスの上から見ることができるのだろう?」 「マチ部分には確かに凹凸ができるだろうけど、それほど大きくなさそうな凹凸を、なんで視認することができるのだろう?」 そこで、目の前のヒップを観察しながら階段を登りつつ考えた。
下着のマチ部分は、他の部分に比べて約2ミリメートルくらい厚い。 つまり、女性の丸いお尻が下着をはくと、丸い曲面上に「下着のマチ」という高さ約2ミリメートル程度の山脈ができる。
そんな山を持つ曲面面を、さらにストレッチ素材のボトムスが覆うとき、収縮しようとするストレッチ素材の生地を支配する方程式は、ポテンシャル曲面は可能な限り「滑らか」になるというラプラス方程式である。 つまり、下着のマチ部分を覆うストレッチ素材のボトムスがどう見えるかを考えるときには、ラプラス方程式の解を求めればよい。
自然界の多くの現象がラプラス方程式を使って解くことができるように、下着のマチ厚みが作るボトムス表面形状を、ラプラス方程式で求めることにしよう。…そのために、まずは、下着のマチ部分あたりの女性のヒップを、直径8センチメートルの球面形状だとしてみる。 すると、ラプラス方程式の解を概算すると、下着のマチ部分のストレッチ素材のボトムスは、ざっくり「高さ2ミリメートルで、両側になだらかな斜面が約9ミリメートルほどつづく山(凸形状)」ができることになる。
すると、次の疑問がさらに湧く。
「高さ2ミリメートルで、両側になだらかな斜面が約9ミリメートルほどつづく山(凸形状)」を人は視認することができるものだろうか?
約1メートル離れて、視線方向への2ミリの凹凸となると、両眼視差で形状を捉えるようなスケールではない。 となると、そのオフホワイト単色のボトムスに浮かぶ凹凸を識別する手掛かりは、陰影情報だけだろう。
物体に照明があたるとき、その表面の陰影はコサイン(照明角度)で表される。 ということは、高さ2ミリメートルの下着マチ山脈の陰影は、「両側に約9ミリメートル続くなだらかな斜面」の角度(斜度)を計算し、そのコサインを評価してやれば良いことになる。 ちなみに、下着マチ山脈の斜度を計算してみると、約13度だ。 照明が約45度方向から照らすなら、下着マチ山脈の片側斜面は(他の部分より)約8パーセント明るく、もう片側の斜面はその逆に約8パーセント暗いということになる。
人の視覚が濃淡模様を識別する特性を考えると、約1メートル離れた9ミリメートルピッチつまり角度約1度の濃淡模様は、数十分の1程度でも識別することができる。 つまり、下着マチ部分の濃淡は、その高さがわずか2ミリメートルだとしても、明瞭に視認されることになる。 もちろん、いわゆる視力的にも角度約1度は約0.02に相当するから、全くもって問題は無い。 結局のところ、「下着のマチ部分の凹凸はわずかでも、その陰影は視認するのに十分な濃淡になる」ということになる。
と、考えがさらにここまで漂流してきた瞬間、駅の階段を踏み損なって転びかけた。足の先を強く打ち痛い思いはしたけれど、幸い何ともなかった。 階段を昇る目の前の女性のヒップに浮かぶ「ムフ♡!」を眺めつつ、考えごとをすることは、有意義と言うよりは少し危険なことなのかもしれない。