フレクサゴンのすべての不変式を連立方程式として書くと、合法的な状態の周りの小さな偏差は線形システムとして書くことができます。(x1,y1)
たとえば、との間の紙の硬さは(x2,y2)
、
(x1 - x2)**2 + (y1 - y2)**2 - L**2 == 0
これは柔らかくすることができます
chi2 = (x1 - x2)**2 + (y1 - y2)**2 - L**2 + other constraints...
、、chi2
に関するの導関数は、線形方程式を生成します。線形連立方程式は行列であり、その行列の固有値/固有ベクトル分解により、曲げやすいまたは曲げにくいパラメータ、、 、の線形結合が得られます。固有ベクトルは可能な方向の基本セットであり、それぞれに対応する固有値は、その方向に曲がるのがどれほど難しいかを示します。固有値が大きいほど、より制約されます。x1
x2
y1
y2
x1
x2
y1
y2
上記の問題は、真に許容される方向がある場合、つまり に関する の導関数chi2
がp
0 である場合 (元の制約が完全に満たされる場合)、行列は特異であり、反転して取得できないことです。固有系。絶対に許可された方向が何であるかだけを知りたい場合は、固有システムの代わりに行列のヌル空間を計算できます。ただし、「許可された」方向には少し曲がる必要があると思います(フレクサゴンで遊んだことはありません)。chi2
は小さいがゼロではない。次に、小さいがゼロ以外の固有値を探します。オブジェクト全体の平行移動や回転など、他の自由度は許容されますが、面白くありません。これを純粋な固有システムの問題 (null スペースがまったくない) に変えるには、任意の小さな定数ラムダを使用してシステムに制約を追加します。
chi2 += lambda_x * (x1 + x2)**2/4.0 + lambda_y * (y1 + y2)**2/4.0
各ラムダを変更すると変化するため、ソリューションでそれらを認識できます。(上記の例ではlambda_x
、xlambda_y
方向への移動と y 方向への移動にペナルティが課せられます。)
実装に関しては、任意の線形代数ソフトウェアを使用して解を計算し、ラムダによる変動をチェックできます。私は Python を使用して、このような問題のプロトタイプを作成しました (高エネルギー物理学における検出器の位置合わせ。この制約は、「この検出器はその検出器から 3 cm 離れています」などの測定値であり、chi2
は、不確実性「3 cm ± 0.1 cm」から導出されたものであり、その後、生産のためにソリューションを C++ (BLAS) に移植しました。Python 用の Numpy ライブラリには十分な線形代数がありました (フードの下には BLAS があります) が、行列ソリューションをデバッグするために Scipy の一般的な非線形最小化ツールも使用しました。最も困難な部分は、インデックスを正しく並べることです。これは、目的関数を一般的なミニマイザーに与える場合ではなく、マトリックスとしてキャストする場合に必要です (代わりに変数名を使用するため)。これはより Matlab または Mathematica の問題なので、どちらかの方が使い慣れている場合は、代わりにそれを使用してください。この問題には多くの試行錯誤が必要になるため、可能な限り最もインタラクティブなシステム (優れた REPL またはワークシート/ノートブック スタイルのインターフェイスを備えたもの) を使用してください。
接続のグラフ (プロットではなく、グラフ理論グラフ) を描画して、それらの制約にラベルを付けることも役立ちます。私にとって、これは方程式を書き出す前に必要な最初のステップでした。
x1
また、パラメーター値 (など) を受け取り、OpenGL (または他の 3-D メッシュ レンダラー) で Figure を描画する一連の関数を記述して、システムを視覚化することも役立つ場合があります。これは、メッシュ タイルが互いに通過するため、何らかの制約に違反しているかどうかを示すことができます。また、各固有ベクトルによって表される自由度を特定するのにも役立ちます。固有ベクトルによって表される線形結合によってパラメーターを変化させると、それが単に平行移動/回転しているだけなのか、それとも興味深いねじれや折り畳みを行っているのかがわかります。