Pozitivně definitní matice a kvadratické formy

Test pozitivní definitnosti a Choleského rozklad

Rozhodněte, zdali je následující matice pozitivně definitní pomocí Gaussovy eliminace a determinantů. Pokud ano, nalezněte její Choleského rozklad.

Nápověda:

Část prvního řádku matice $\boldsymbol A$ počínaje druhým sloupcem lze zapsat jako A[0,1:], podobně výběr podmatice lze provést A[1:,1:], atd.

In [ ]:
matrix([
    [1 , 2 ,  1 , 0 ],
    [2 , 8 ,  4 , 2 ],
    [1 , 4 , 11 , 1 ],
    [0 , 2 ,  1 , 2 ]])

matrix([
    [4 , 2 ,  2 , 0 ],
    [2 , 2 ,  4 , 1 ],
    [2 , 4 , 10 , 3 ],
    [0 , 1 ,  3 , 6 ]])

matrix([
    [4 , 0 ,  0 , 2 ],
    [0 , 1 ,  3 , 0 ],
    [0 , 3 , 10 , 1 ],
    [2 , 0 ,  1 , 3 ]])

matrix([
    [1  , -2 ,  1 ,  1 , -1], 
    [-2 ,  8 , -2 , -4 ,  8], 
    [1  , -2 ,  2 ,  3 , -1], 
    [1  , -4 ,  3 , 15 , -1], 
    [-1 ,  8 , -1 , -1 , 15]])

Součin pozitivně definitních matic

Dokažte nebo vyvraťte: Součin pozitivně definitních matic je pozitivně definitní.

In [ ]:
 

Soustava s pozitivně definitní maticí

Spočtěte Choleského rozklad následující matice $\boldsymbol A$.

Choleského rozklad použijte k řešení soustavy $\boldsymbol A\boldsymbol x = (10, 21, -32, 26, 23)^{\mathrm T}$.

Nápověda:

Choleského rozklad lze získat A.cholesky().

In [2]:
A = matrix([
    [ 1 ,  2 , -3 ,  2 ,  1], 
    [ 2 ,  5 , -6 ,  3 ,  2], 
    [-3 , -6 , 10 , -5 , -3], 
    [ 2 ,  3 , -5 , 15 , 11], 
    [ 1 ,  2 , -3 , 11 , 14]])

vector([10, 21, -32, 26, 23])

Změna báze formy

Kvadratická forma $g$ na vektorovém prostoru $\mathbb R^4$ má vzhledem ke standardní bázi $E$ analytické vyjádření $g(\boldsymbol u)=2x^2-2xy+y^2-2yt+t^2$, kde $\boldsymbol u=(x,y,z,t)^{\mathrm T}$.

Najděte její analytické vyjádření $g(u)_B$ vzhledem k bázi: $B=\{(1, 1, 1, 1)^{\mathrm T},(0, 1, 1, 1)^{\mathrm T},(0, 0, 1, 1)^{\mathrm T},(0, 0, 0, 1)^{\mathrm T}\}$.

Určete $g(\boldsymbol u)$ pro vektor $\boldsymbol u$, který má vůči bázi $B$ souřadnice $[\boldsymbol u]_B = (3, 1, 0, 0)^{\mathrm T}$.

In [ ]:
 

Řešení

Pokud si nevíte rady, můžete zde kliknout a ukáže se vám řešení (nebo alespoň jeho podstatná část):

Test pozitivní definitnosti - pomocí Gaussovy eliminace

Nejprve si výchozí matici pojmenujeme:

A = matrix([
    [1 , 2 , 1 , 0 ],
    [2 , 8 , 4 , 2],
    [1 , 4 , 11 , 1 ],
    [0 , 2 , 1 , 2 ]])

print('A - původní')
print(A)


Eliminace prvního sloupce pomocí Gaussovy eliminace odpovídá výpočtu matice $\boldsymbol B=\boldsymbol{A}'-\frac{1}{a_{1,1}}\boldsymbol a\boldsymbol a^\mathrm{T}$.

Zde $\boldsymbol{A}'$ vznikne odebráním prvního řádku a sloupce, neboli A[1:,1:], a $\boldsymbol{a}$ je odovídající zbytek prvního řádku, čili A[0,1:].

B  = A[1:,1:] - 1/A[0,0] * A[0,1:].transpose() * A[0,1:]
print('B - podmatice po eliminaci')
print(B)


Podobně lze pokračovat eliminací matice $\boldsymbol{B}$, atd.


Test pozitivní definitnosti - pomocí determinantů

Determinant výchozí matice je:

print(A)
print(A.determinant())


a poté lze pokračovat zmenšováním matice od levého horního rohu:

print(A[1:,1:])
print(A[1:,1:].determinant())
print(A[2:,2:])
print(A[2:,2:].determinant())


nebo od pravého dolního.

print(A[:3,:3])
print(A[:3,:3].determinant())
print(A[:2,:2])
print(A[:2,:2].determinant())


Poslední determinant podmatice řádu 1 je vidět rovnou.


Choleského rozklad

Postup lze odkrokovat

A = matrix(SR, [
    [0, 3, 4, 0],
    [0, 0, 5, 0],
    [2, 1, 0, 2]])

U = matrix(4)

U[0,0] = sqrt( A[0,0] )
U[0,1] = A[0,1] / U[0,0]
U[0,2] = A[0,2] / U[0,0]
U[0,3] = A[0,3] / U[0,0]

U[1,1] = sqrt( A[1,1] - vector(U[:1,1]) * vector(U[:1,1]) )
U[1,2] = ( A[1,2] - vector(U[:1,1]) * vector(U[:1,2]) ) / U[1,1]
U[1,3] = ( A[1,3] - vector(U[:1,1]) * vector(U[:1,3]) ) / U[1,1]

U[2,2] = sqrt( A[2,2] - vector(U[:2,2]) * vector(U[:2,2]) )
U[2,3] = ( A[2,3] - vector(U[:2,2]) * vector(U[:2,3]) ) / U[2,2]

U[3,3] = sqrt( A[3,3] - vector(U[:3,3]) * vector(U[:3,3]) )

print(U)

nebo přímo napsat celý algoritmus (tento je pro jednoduchost bez testování na nulu na diagonále)

U = matrix(4)
for i in range(A.nrows()) :
    if  i == 0 :
        U[0,0] = sqrt( A[0,0] )
    else :    
        U[i,i] = sqrt( A[i,i] - vector(U[:i,i]) * vector(U[:i,i]) )
    for j in range(i,A.nrows()) :
        if  j == 0 :
            U[0,j] = A[0,j] / U[0,0] 
        else :    
            U[i,j] = ( A[i,j] - vector(U[:i,i]) * vector(U[:i,j]) ) / U[i,i]
print(U);

Součin pozitivně definitních matic

Součin symetrických matic nemusí být symetrický, stačí tedy najít dvě pozitivně definitní matice, jejichž součin není symetrický, např.

(
matrix([
    [2 , 1 , 0],
    [1 , 2 , 0],
    [0 , 0 , 4]]) 
*
matrix([
    [3 , 1 , 0],
    [1 , 3 , 1],
    [0 , 1 , 3]])
)


(Pozn.: vnější oblé závorky umožňují rozepsat výraz na více řádků.)

Pozitivně definitní matice lze získat součinem $\boldsymbol{R}^{\mathrm H}\boldsymbol{R}$ z regulárních matic $\boldsymbol R$, např. z matic v odstupňovaném tvaru.


Soustava s pozitivně definitní maticí

Choleského rozklad se získá:

L = A.cholesky()
Pro rozklad $\boldsymbol A=\boldsymbol{LL}^{\mathrm T}\boldsymbol{x}$ zavedeme substituci $\boldsymbol{y}=\boldsymbol{L}^{\mathrm T}\boldsymbol{x}$. Poté řešíme soustavy $\boldsymbol{Ly}=\boldsymbol{b}$ a $\boldsymbol{L}^{\mathrm T}\boldsymbol{x}=\boldsymbol{y}$

Protože matice obou soustav jsou v odstupňovaném tvaru, stačí provést jen dvakrát zpětnou substituci.

b = vector([10, 21, -32, 26, 23])
y = L.solve_right(b)
L.transpose().solve_right(y)

Poslední řádek lze alternatině zapsat bez transpozice

L.solve_left(y)

Změna báze formy

Matici $\boldsymbol A_E$ formy $g$ vůči standardní bázi vynásobíme z obou stran maticí přechodu od báze $B$ k $E$ a dostaneme její matici $\boldsymbol A_B$ vůči bázi $B$.

$\boldsymbol A_B=[id]_{B,E}^{\mathrm T}\cdot \boldsymbol A_E \cdot [id]_{B,E}$

Klíčové je správné sestavení matic.

A_E = matrix([
    [2 , -1 , 0 ,  0],
    [-1,  1 , 0 , -1],
    [0 ,  0 , 0 ,  0],
    [0 , -1 , 0 ,  1]])

u_B = vector([3, 1, 0, 0])

id_B_E = matrix([
    [1 , 0 , 0 , 0],
    [1 , 1 , 0 , 0],
    [1 , 1 , 1 , 0],
    [1 , 1 , 1 , 1]])
    
A_B = id_B_E.transpose() * A_E * id_B_E

u = id_B_E * u_B


V obou případech vyjde výsledek stejně:

print (u * A_E * u)
print (u_B * A_B * u_B)