2025/9/27(土)

ComplexPlotというグラフ表示アプリを作った。製作期間は3日くらい。

https://complexplot.chaosplant.tech

この手の簡単なグラフ表示器といったらDesmosかGeoGebraだが、どちらも複素数をそのまま扱うことが出来ず、位相や絶対値を見たいと思う度に実数の式に書き直すのが癪で癪で仕方がなくて作ってしまった。

UIのHTMLとVueで出来ている部分は1時間くらいで作り終わってしまったのだが、そこから先が長かった。まず式の構文解析をしなければいけないのだが、外部ライブラリで良さげなのが見当たらなかったので、いい勉強の機会だと思ってググって自作することにした。

トークナイズ処理は自分で適当に作ったが、抽象構文木の生成は生半可に地頭だけでやろうとすると火傷することを以前に学んでいる。ちゃんと調べてみたところ、再帰下降解析というのが良さげだったのでそれを実装した。案外実装は軽量で、式評価部分を含めて300行も行かなかった。これで構文解析の基本的な知識が身に付いたので、以前にちょっと挑戦してやめたコンパイラ自作とかもその内再トライしたい。あと今回は再帰下降法を選択したが、操車場アルゴリズムなるものもあるらしいのでこれもその内試してみたい。

複数の式の評価は適当に依存順をトポロジカルソートするだけかと思いきや、そのトポロジカルソートの実装を久しぶりにやったらかなり忘れていた。やってたら思い出したので腕力で解決した。

そんな感じで大体出来たのだが、どうも対数表示でズームアウトしていくと割と容易に計算が破綻するラインに到達する。これはまずい。回路シミュレータとかは10の数十乗くらいのオーダーの数値を事も無げに扱っていると思うのだが、一体中身はどうなっているのか。

まあ思いつくのは対数での計算くらいだ。一般にどういうやり方をやるかをclaudeに聞いたところ、やっぱり対数がよくある手法という回答を得たのでそれを実装することにした。

数学的にはlog(z)=log(|z|)+iarg zなので、実部の対数+虚部の対数とかではなく絶対値の対数+偏角で管理した方が筋が良い。これによって乗算は本当に足し算だけで良くなる。

対数領域計算で大変なのが乗除算以外の計算、特に加算だ。どうやってもきれいな式にはならない。数式をこねこねした結果、以下の式が比較的マシで対称性も良さそうなのでこれをセレクトした。

$\log(e^z+e^w)=\mathrm{Re}[z]+\frac{1}{2}\log[(\cos(\mathrm{Im}[z])+\cos(\mathrm{Im}[w])e^{\mathrm{Re}[w]-\mathrm{Re}[z]})^2+(\sin(\mathrm{Im}[z])+\sin(\mathrm{Im}[w])e^{\mathrm{Re}[w]-\mathrm{Re}[z]})^2]+i\tan^{-1}(\frac{\sin(\mathrm{Im}[z])+\sin(\mathrm{Im}[w])e^{\mathrm{Re}[w]-\mathrm{Re}[z]}}{\cos(\mathrm{Im}[z])+\cos(\mathrm{Im}[w])e^{\mathrm{Re}[w]-\mathrm{Re}[z]}})$

重要なのがRe[w]-Re[z]の部分だ。指数を避けることは出来ないが、大きい指数が出てくると全てのメリットが消し飛ぶので、大きさ比較をしてRe[w]-Re[z]≦0とすることで

対数領域計算を実装したところ、とんでもないレンジで計算できるようになった。10^10^100とかいう訳の分からないオーダーで計算できる。

対数領域計算では負数の扱いが問題になる。もとから複素数前提なら偏角で管理しているので何も問題ないのだが、実数処理の場合は絶対値の対数+負数フラグのような形が無難なようだ。

プロダクトだけでなく「構文解析」「対数領域計算」と2つの新しい技術知識を手に入れた。かなり有意義な開発だったと思う。


ダイソーで売ってたラックで自室の据え置きゲーム機を整理した。WiiU、ファミコン、スーファミが狭いところに押し込められていたのを綺麗に3段重ねにして、カセットもまとめられた。


また中古ゲームを買った。バイナリィランド、さわるメイドインワリオ、マリオ3Dランドの3本。3Dランドは「リアルタイムのときにまあまあ気になったが結局強く親にねだることなく年月が過ぎて行った」ゲームの1つだ。時間が出来たら真面目に取り組みたい。

自分の子供の頃はそこまで多くのゲームソフトを買ってもらった訳ではない代わり、買ってもらったものは徹底的に遊びつくした思い出がある。一度全クリしたら大体投げている。今Steamのゲームも大体そういう遊び方をしているし、性分なのだろう。

Categories: