単純な方法としては連立方程式を解くというやり方があります。
しかし、連立方程式を解くのは少し大変です。
二元連立なら公式がありますが、三元連立だとググっても「掃き出し法を使えよ」と言われます。
昔調べた時はそうだった気がしますが、今「三元連立方程式 プログラム」でググったらありました。
http://www.usamimi.info/~geko/arch_acade/elf001_simult/
・・・著作権の問題とかもありそうだし(言い訳)、見なかったことに。
目標として、次の連立方程式を解くことを考えます。 ただ、普通に文字式を解こうとすると、分母が0になるコーナーケースの場合分けが大量に必要になり、めんどくさくなります。
そこで、今回はコーナーケースを気にせず計算をし、最後に代入して方程式が成り立てば、合ってるとみなすことにしました。
こうすることで、最終結果の分母が0になる場合のみ考えればよくなり、比較的簡単になります。
というわけで、普通に連立方程式を解くように計算(加減法)。
ax+by+cz=d
ex+fy+gz=h
ix+jy+kz=l
aex+bey+cez=de
aex+afy+agz=ah
(be-af)y+(ce-ag)z=(de-ah)
eix+fiy+giz=hi
eix+ejy+ekz=el
(fi-ej)y+(gi-ek)z=(hi-el)
(be-af)(fi-ej)y+(ce-ag)(fi-ej)z=(de-ah)(fi-ej)
(be-af)(fi-ej)y+(be-af)(gi-ek)z=(be-af)(hi-el)
((ce-ag)(fi-ej)-(be-af)(gi-ek))z=((de-ah)(fi-ej)-(be-af)(hi-el))
z=((de-ah)(fi-ej)-(be-af)(hi-el))/((ce-ag)(fi-ej)-(be-af)(gi-ek))
(be-af)(gi-ek)y+(ce-ag)(gi-ek)z=(de-ah)(gi-ek)
(ce-ag)(fi-ej)y+(ce-ag)(gi-ek)z=(ce-ag)(hi-el)
((be-af)(gi-ek)-(ce-ag)(fi-ej))y=((de-ah)(gi-ek)-(ce-ag)(hi-el))
y=((de-ah)(gi-ek)-(ce-ag)(hi-el))/((be-af)(gi-ek)-(ce-ag)(fi-ej))
afx+bfy+cfz=df
bex+bfy+bgz=bh
(af-be)x+(cf-bg)z=(df-bh)
ejx+fjy+gjz=hj
fix+fjy+fkz=fl
(ej-fi)x+(gj-fk)z=(hj-fl)
(af-be)(gj-fk)x+(cf-bg)(gj-fk)z=(df-bh)(gj-fk)
(cf-bg)(ej-fi)x+(cf-bg)(gj-fk)z=(cf-bg)(hj-fl)
((af-be)(gj-fk)-(cf-bg)(ej-fi))x=((df-bh)(gj-fk)-(cf-bg)(hj-fl))
x=((df-bh)(gj-fk)-(cf-bg)(hj-fl))/((af-be)(gj-fk)-(cf-bg)(ej-fi))
result
x=((df-bh)(gj-fk)-(cf-bg)(hj-fl))/((af-be)(gj-fk)-(cf-bg)(ej-fi))
y=((de-ah)(gi-ek)-(ce-ag)(hi-el))/((be-af)(gi-ek)-(ce-ag)(fi-ej))
z=((de-ah)(fi-ej)-(be-af)(hi-el))/((ce-ag)(fi-ej)-(be-af)(gi-ek))
(wxMaximaを直接ビルドしようとするとconfigureでエラーが出たが、MaximaをインストールしたらwxMaximaがおまけでついてきた)
次に、WolframAlphaで、結果の分母が0になる条件を確認。
xの分母(ry
yの分母(ry
zの分母(ry さらに、xの分母(ryにはf==0という条件が追加されていました。
本当に、こんなに条件がついていても、解ける三元連立一次方程式は全て解けるのでしょうか?
理論上、行列[a b c;e f g;i j k]の行列式が0でなければ、逆行列を計算して解けるはずです。
wxMaximaで行列式を計算して、WolframAlphaで0になる条件を計算。
行列式が0になる条件
上で求めた条件(f==0以外)ときれいに一致しました。
あとはf==0を回避できれば、大勝利です。
式の順番を入れ替えても答えが変わるわけないので、f==0を回避できない状況はyの係数が全て0の状況です。
これは、どう考えても完全には解けませんね。(途中まで解いても、解の自由度が0にならない)
よって、解ける連立方程式が与えられれば、必ずyの係数のどれかは0ではないはずなので、それをfの位置に持って来れば勝ちです。
あとはこの式をプログラムに落とし込み、それを使った処理を書けば完成でしょう。