CodeDom + ラムダ式 + WPF

この前の連休中作ってた Expression Tree の記号計算ライブラリのその後。連休中では終わらなくてちょっと未完成部分が残ったんだけど、形になってきたんでここいらで。

最近流行の動的計算、C# 3.0 のラムダ式WPF で 3D と、なかなかいい感じの話題を盛り込めたんじゃないかと。

どういうことがしたかったのかというと、昔作った力学シミュレーションプログラムに統合したかった(→ サンプルプログラム - クラスライブラリ | ++C++; // 未確認飛行 C)。

で、

  • 物体の拘束面の方程式を動的に指定できるようにしたい → CodeDom
  • 複雑な式を入れたときの処理が重たい&精度が落ちるのを防ぎたい → 式木の最適化

というのを追加したかった。

その結果↓

http://ufcpp.net/study/csharp/fig/dynamics2.png
ソース一式Visual Studio 2008で作成。ZIP 圧縮)。

  • CodeDom で文字列から Expression Tree を動的生成
  • 作った Expression Tree を記号計算して、運動方程式を立てる
  • 数値的に微分方程式を解いて、WPF の Viewport3D でリアルタイム表示

記号計算ライブラリの中身的には、結局、以下のような感じに。

  • System.Linq.Expressions.Expression を、一度自作の Expression クラスに変換
    • Expression 同士の operator を実装
  • 結構な最適化がかかる
    • 共通因子のくくりだしとか、分母・分子の約分までやる
      • x * x / x * x / x / x みたいなのが 1 に
      • (x * x + x) / (x + 1) が x に
    • 関数の特殊な最適化もある程度実装
      • Sin(x) * Sin(x) が 0.5 - 0.5 * Cos(2 * x) に
      • Sin(x) * Sin(x) + Cos(x) * Cos(x) はちゃんと 1 になる
      • Exp(Log(x)) が x に
  • 微分とか共通因子のくくりだし・約分計算にキャッシュ機構を導入して高速化