六曜定義は、元々、某有名予定表置き換えソフトが利用するために、作成しました。
そちらは、現在対応待ちなのです。着想は昨年中からあり、クリエオーガナイザに、
六曜が搭載されていたときは本当にびっくりしました。
六曜の計算は、いわゆる旧暦(太陽太陰暦)を求めるところからはじめます。太陽太陰暦というのは、太陰暦……つまり月の朔望を基準に一ヶ月を定める……をベースに、季節との間に乖離が生じないように、太陽暦……いわゆる二十四節気……による補正をかけた暦です。
つまり、旧暦の計算には、二十四節気の導出のために太陽の黄道上の移動を、朔望の導出のために月の満ち欠けを計算してやらなければならないのです。詳しい計算式などは、天体の位置計算 増補版(長沢 工著)あたりを参照していただくとして、これをPalmOS上に再現するためにした苦労話をしようと思います。
とにかく、計算は、三角関数を多用するので、実数演算は避けられません。ところがPalmOSと来たら、一応、申し訳程度に浮動小数演算機能は持っているものの、大変低速(エミュレーションなので)であり、プロトタイピングに使ってみたのですが、発狂しそうな遅さでした。
おまけに、このエミュレーションは大域変数をこっそり利用するので、実装の自由度からも敬遠したいものでした。(当初、この計算は、PalmOS上にライブラリとして提供して、必要に応じて、問い合わせて利用するという形態を考えていました。)
そんなわけで、ある程度速度が出そうな、固定小数ルーチンを探すことにしたのですが、そこらにあるのは精度が不充分なものばかりで、結局、これの自作から入る必要がありました。
結局、整数部32bit、小数部32bitの実数表現と、加減乗除、三角関数の近似計算などを実装しました。
これを使って、計算を実装してみると、当初よりはマシなものの、一年分のデータを求めるのに、一分半近くかかってしまいました。さて、ここからは最適化の始まりです。固定小数の計算のうち、もっとも時間を食いそうなのが除算です。除算は、本当に除算していたらコストがかかりますから、ラフに解を見積もって、あとはニュートン法で収束するまで近似をします。ここで最初の見積もりを改良したり、近似ループの最適化をしたりすると、かなりの時間短縮を達成できました。そのほかの全体的な最適化もあわせると、結局最終的に、一年当たり20秒程度で求まるところまでつめられました。
とはいえ、こんなに時間がかかるのでは、ライブラリとしておいておいて、問い合わせのたびに計算するなんていう方法はとれません。断念です(^^;;
それはそれとして、更なる可能性を探るべく、ARMLETを試してみることにしました。計算の主たる部分を、ARMネイティブのコードで実装し、ARMアーキテクチャ上で実行させてみるとどうなるのか試してみました。すると、数秒で一年分を計算してしまいました。
そんなわけで、もし、Dragonball アーキテクチャのマシンと、ARMアーキテクチャのマシンとをお持ちの方は是非、両方で実行させてみて、速度の差を実感していただけたらと思います(^^;;
コメント