まず、linalg
は助けにはなりません任意の結果を持っていない:不明Aはそれ自体で乗算されます。あなたは9つの未知数を持つ18の二次方程式の系を解きたがっています。一般的なシステムでは、何の解決策も期待しませんが、ここにはたくさんの構造があります。
私のバージョンのSymPy(1.1.1)では、行列式A*B*A=B*A*B
またはA*A=I
のいずれかを直接解決しようとすると、合理的な時間内に終了できません。ですから、saintsfan342000のアドバイスに従い、最小化の問題として数値的に問題にアプローチしましょう。これは私がそれをやった方法です:
import numpy as np
from scipy.optimize import minimize
B = np.array([[1,0,0], [0,-1,0], [0,0,1]])
def func(A, B):
A = A.reshape((3, 3))
return np.linalg.norm(A.dot(B).dot(A)-B.dot(A).dot(B))**2 + np.linalg.norm(A.dot(A)-np.eye(3))**2
while True:
guess = np.random.uniform(-2, 2, size=(9,))
res = minimize(func, guess, args=(B,))
if res.fun < 1e-15:
A = res.x.reshape((3, 3))
print(A)
最小限に抑える機能がA*B*A-B*A*B
とA*A-I
のフロベニウスノルムの二乗和です。 minimize
が詰まってしまう局所的な最小値があるので、最小化をループに入れます。見つかった最小値が十分にゼロに近くないときは、結果を無視してやり直します。中央要素A [1,1] 1/2 ある
この情報は、SymPyがシステムを解決するのに役立ちます。私はまだ両方の方程式を投げたくないので、一度に1つずつ取得しようとします。
from sympy import *
var('a:h') # a quick way to declare a bunch of symbols
B = Matrix([[1, 0, 0], [0, -1, 0], [0, 0, 1]])
A = Matrix([[a, b, c], [d, S(1)/2, f], [g, h, S(1)/2-a]]) # S(1)/2 is a way to get rational 1/2 instead of decimal 0.5
print(solve(A*B*A - B*A*B))
print(solve(A*A - eye(3)))
は今solve
は成功し、次出力します
[{b: h*(4*f*h - 3)/(2*g), d: -g/(2*h), a: 2*f*h - 1/2, c: -f*h*(4*f*h - 3)/g}]
[{b: h*(4*f*h - 3)/(2*g), d: -g/(2*h), a: 2*f*h - 1/2, c: -f*h*(4*f*h - 3)/g}]
おっと!数値的に見つかった2つの制約条件の両方で、両方の行列方程式は等価です!それを予想しなかった。だから我々はすでに解を持っている:
A = Matrix([[2*f*h - S(1)/2, h*(4*f*h - 3)/(2*g), -f*h*(4*f*h - 3)/g], [-g/(2*h), S(1)/2, f], [g, h, 1 - 2*f*h]])
任意のf、g、hについて。
注:A = Bは、A [1,1] = 1/2の要件によって上記から除外された簡単な解です。私はこれが意図だったと思います。対称グループS の忠実な3次元表現を探していたようです。
「sympy」を使用すると、記号の記号と記号の値で答えが得られます。だから、あなたのコードの最後の行を 'print sp.solve(A * B * A - B * A * A)'に修正すれば、アルゲラの答えが表示されます。それはあなたが望むものか、実際の数値解を求めていますか? – DrBwts
私はいくつかの自由があることを知っています。たとえば、私は 'g'と 'h'を使用して回答をしたい – Nikita
申し訳ありませんが私は明確ではありません。記号の点で答えが必要な場合は、コードが機能します。 – DrBwts