2017-09-21 25 views
2

行列AがA*B*A = B*A*Bで、B =(1,0,0)(0,0-1)(0,0,1)ならばA^2 = 1である必要があります。Pythonで2つの行列を使って方程式を解く方法は?

私はそれを試みましたsympyでそれ:sympy.solve(A*B*A - B*A*A)

import sympy as sp 
a,b,c,d,e,f,g,h,k = sp.symbols('a b c d e f g h k') 
B = sp.Matrix([[1,0,1],[0,-1,0],[0,0,1]]) 
A = sp.Matrix([[a,b,c],[d,e,f],[g,h,k]]) 
sp.solve([A*B*A - B*A*B,B**2-sp.eye(3)]) 

をしても、私はnumpy.linalgを試してみましたが、これは線形問題ではありませんように私は、すべての

+1

「sympy」を使用すると、記号の記号と記号の値で答えが得られます。だから、あなたのコードの最後の行を 'print sp.solve(A * B * A - B * A * A)'に修正すれば、アルゲラの答えが表示されます。それはあなたが望むものか、実際の数値解を求めていますか? – DrBwts

+0

私はいくつかの自由があることを知っています。たとえば、私は 'g'と 'h'を使用して回答をしたい – Nikita

+0

申し訳ありませんが私は明確ではありません。記号の点で答えが必要な場合は、コードが機能します。 – DrBwts

答えて

2

まず、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*BA*A-Iのフロベニウスノルムの二乗和です。 minimizeが詰まってしまう局所的な最小値があるので、最小化をループに入れます。見つかった最小値が十分にゼロに近くないときは、結果を無視してやり直します。中央要素A [1,1] 1/2 ある

  • :しばらく実行した後、スクリプトは

    全て共有する2つの重要な特徴
    [[ 0.70386835 0.86117949 -1.40305355] 
    [ 0.17193376 0.49999999 0.81461157] 
    [-0.25409118 0.73892171 -0.20386834]] 
    

    ような行列の束を印刷します

  • 行列のトレース(対角要素の合計)は1です。

この情報は、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次元表現を探していたようです。

関連する問題