hirax.net::Keywords::「非定常」のブログ



2008-08-05[n年前へ]

エクセルでシミュレーション Vol.6 「夏にフライパンで卵焼き 編」 

 「表計算ソフトウェアでシミュレーションをする」という講習を見続け、何よりも面白かったのが「非定常の3次元熱計算を簡単に、それでいて、できる限りきちんと計算をやってみよう」という(I氏が講師の)シリーズです。

 一次元非定常の熱拡散問題を陰的解法で解く「熱伝導方程式を表計算ソフトで解くサンプル」は多いように思いますが、「非定常の3次元熱計算を表計算ソフトウェアで解く簡単にやるテクニック・サンプル」は、(私は)他では見たことがありません。しかも、このシリーズは本当に簡単で、なおかつ、できる限り精度を保証して解く、というとても稀有な例です。「難しい問題」を「簡単に」「きちんと」「精度を保証して」解く…といったようなものたちは相反することが多いわけですから、そういったものを兼ね備えているというのは、とても珍しいと思うわけです。

 下の例は、そのテキストを利用して、陽的解法で安定性条件が成り立つようにして、「夏の朝に、角型フライパンをコンロで加熱した際のフライパン温度分布」を計算した例になります。ある厚みを持ったフライパンが、コンロのガスの炎が当たっている部分が「100度」に(熱)されているような条件の時、フライパンの温度分布が時々刻々と変わっていくようすを計算した結果です。こんな計算をエクセルで数回しておけば、「美味しい卵焼きを作るための最適条件・最適なやり方」を導き出すことだってできるかも、と思わされるのです。エクセル上で、フライパンの厚みや熱伝導度を変え、コンロの炎分布を色々変えてみたりしたならば、究極・至高の卵焼きを作るための最適・必須条件が見つかるかもしれない、と楽しく思えてきたりします。

 ところで、この「非定常3次元熱計算」のエクセルシートは、本当に簡単に作ることができるのですが、その一方で、このシートは(簡単なのに)実に巧みに作られています。だからこそ、「難しい問題」を「簡単に」「きちんと」「精度を保証して」解くことができるわけです。

 その「巧みさ」を紐解いてみると、これが実に綺麗なパズルのようで、とても面白いのです。・・・というわけで、その「巧みさ」「面白さ」についての感想文は、また後ほど書いてみようと思います。

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スクリプトに自動で変換するプログラム」なんていうものを、(何だか馬鹿馬鹿しいけれど)意外に少し面白い笑える、そう思える人が一人でもいたら、幸いに思います。

2009-12-29[n年前へ]

「カルマンフィルタ」と「エクセルで解く2次元非定常熱伝導問題」 

 正月に、(自分用の)汎用「カルマンフィルタ」ライブラリをRubyとCとExcelで書いてみることにした。たとえば、さまざまなデータ、たとえば、信頼性が低く、誤差の大きなセンサデータや、安定性に欠ける実験データから、現実に近い状態量を推定するツールを作ってみることにした。そして、何か(解析式による)モデル計算や各種シミュレーション計算と比較をしてみたり、それらの計算改善へのフィードバック例を作ってみよう、と考えた。

 そこで、扱う題材を考えつつ、実際に上記のようなことを行っている例を探してみた。すると、たとえば、

  1. 簡単なカルマンフィルタの実験
  2. カルマンフィルターと有限要素法を用いた一次元非定常熱伝導問題に対する推定
  3. カルマンフィルタFEMを使った熱の擬似状態フィードバック制御
といったものがある。これらの記事が(下に張り付けた動画でその一端がわかると思うが)実にわかりやすく・面白くて楽しく・役に立ちそうに見える。何というか、つまるところ、魅力を持つに必要な三拍子がすべて備わっている。

 先日、「2次元非定常熱伝導問題を解く」エクセル・シート、しかも、そのシートに、センサ機能/フィードバック機能なども付けてみた。そんな素材・材料が揃ってきたこともあるので、まずは、PID制御で(疑似三次元空間における)温度制御を行う例をいくつか作り、その後は、上記記事を参考にしつつ「(誤差を付加した)センサ→カルマンフィルタ→制御量最適化」という例でも作ってみることにしよう。



■Powered by yagm.net