ToDo:
Christopher K. Allenの3D RMS Beam Envelope Simulation内で使われている Matrix Operatorの最適化といか再実装...
ざっと見たけど、MatrixFunctions.nは Fortran/C使いだった SAD初心者が書くコードですね。(私も、最初は似たようなコードを 書いた記憶が...) 行列演算が、ForループとPart演算子で記述されている。 これは書き直せば、絶対早くなると確信して作業開始。
結果、MatrixInnerProd2($L^2$ノルムな行列の内積)は、 リスト操作に直したらエラー処理込みで 3行に圧縮出来る上に、 速度は 17倍になった。また、MatrixNorm2[A]が MatrixInnerProd2[A,A]で実装されているので、 Plus@@(Flatten[{A}]^2)に変えてみると約 30倍早くなる。 (倍率は、Random[6, 6]で作った 6x6の乱数行列に対するベンチマーク)
これらを使っているMatrixExpとか MatrixLogも 4〜5倍に高速化した。
ちなみに、MarixNorm2[A](すべての要素の2乗和)の実装だが、 Plus@@Flatten[{A^2}]よりもPlus@@(Flatten[{A}]^2)の方が 何割か早いのは、二重リストへの Power[]演算子よりも リニアなリストへの Power[]演算子の方が、ループ段数が少なく 結果を格納する一時オブジェクトの確保にかかるコストが少ないためと 思われる。
SADで速いコードを書こうとすると、後ろで動作している インタープリターの挙動を意識しなければならない点は、 初心者向きでは無いと思う。Mathematicaと言うか、Lisp的な言語なので 世に普及している手続き型言語とプログラムの組立てかたが異なるが、 関数言語的な思考が出来れば結構書きやすいのだが...
実行効率を求めるとバイトコンパイルや最適化をやらない インタープリターは、他の関数言語の実装に比べると不利だと思う (純粋関数言語なHaskellとかでは、ソースコードをコンパイルして 最適化するので、ものによっては Cで書くより速く動くらしぃ)
MatrixCommutatorとかは、行列積オペレータ(.)が使われており 小手先の改良を行う余地はなさそうなので、Cで実装する方向で... src/sim/sad_api.hとかに必要なプロトタイプを実装する
カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記