2011-12-08 24 views
6

Ho bisogno di creare una matrice simbolica ortonormale 3 by 3 in Mathematica. Come posso fare?Creare una matrice ortonormale simbolica in matematica

+2

Che tipo di matrice? Mathematica ha incorporato funzioni per le matrici di rotazione e riflessione, entrambe sono ortonormali. – Niki

+0

Voglio costruire una matrice simbolica, in modo tale che la matrice venga sempre trattata come una matrice ortonormale, in calcoli successivi. Il comando RotationMatrix in mathematica NON fa questo. – marcellus

+0

C'è una domanda correlata sul calcolo scientifico stackexchange http://scicomp.stackexchange.com/questions/74/symbolic-software-packages-for-matrix-expressions – MRocklin

risposta

11

Non che io consiglio questo, ma ...

m = Array[a, {3, 3}]; 
{q, r} = QRDecomposition[m]; 
q2 = Simplify[q /. Conjugate -> Identity] 

Così Q2 è una matrice ortogonale simbolica (supponendo che lavoriamo su numeri reali).

+0

Daniel, grazie per la risposta. Vedi qualche modo per "direttamente" imporre le sei condizioni dell'ortonormalità e la condizione di det = 1, senza coinvolgere la decomposizione QR? Grazie. Marcello – marcellus

4

Sembra che tu voglia un po 'di parametrizzazione del gruppo SO(3) in Mathematica. Avrai solo 3 simboli indipendenti (variabili), dal momento che hai 6 vincoli da ortogonalità reciproca di vettori e norme pari a 1. Un modo è quello di costruire rotazioni indipendenti attorno ai 3 assi e moltiplicare quelle matrici. Ecco il codice (forse troppo complessa) per farlo:

makeOrthogonalMatrix[p_Symbol, q_Symbol, t_Symbol] := 
    Module[{permute, matrixGeneratingFunctions}, 
    permute = Function[perm, Permute[Transpose[Permute[#, perm]], perm] &]; 
    matrixGeneratingFunctions = 
     Function /@ FoldList[ 
      permute[#2][#1] &, 
      {{Cos[#], 0, Sin[#]}, {0, 1, 0}, {-Sin[#], 0, Cos[#]}}, 
      {{2, 1, 3}, {3, 2, 1}}]; 
    #1.#2.#3 & @@ MapThread[Compose, {matrixGeneratingFunctions, {p, q, t}}]]; 

Ecco come funziona:

In[62]:= makeOrthogonalMatrix[x,y,z] 
Out[62]= 
{{Cos[x] Cos[z]+Sin[x] Sin[y] Sin[z],Cos[z] Sin[x] Sin[y]-Cos[x] Sin[z],Cos[y] Sin[x]}, 
{Cos[y] Sin[z],Cos[y] Cos[z],-Sin[y]}, 
{-Cos[z] Sin[x]+Cos[x] Sin[y] Sin[z],Cos[x] Cos[z] Sin[y]+Sin[x] Sin[z],Cos[x] Cos[y]}} 

è possibile verificare che la matrice è ortonormale, utilizzando Simplify sulle varie colonne (o riga) prodotti punto.

+0

Leonid, Grazie per la risposta. In realtà voglio definire una generica matrice simbolica SO (3), senza partire dagli angoli di Eulero come fai tu. Fondamentalmente voglio impostare una matrice generica (es. Usando mat = Table [Subscript [m, i, j], {i, 3}, {j, 3}]) e impone che gli elementi di questa matrice vengano trattati sempre come soddisfacendo le condizioni di ortonormalità e la condizione determinante = 1, senza la necessità di specificarlo più avanti. Marcello – marcellus

+0

@ user1087909 Quindi, la risposta di Daniel dovrebbe essere la strada da percorrere. –

+1

Stranamente, nel rispondere al commento/domanda sotto la mia, stavo per dire che Leonid era il modo appropriato. –

3

Marcellus, è necessario utilizzare alcune parametrizzazioni di SO (3), poiché la matrice generale deve riflettere RP3 topology of the group. Nessuna parametrizzazione singola coprirà l'intero gruppo senza multivalore o punti singolari. Wikipedia ha una bella pagina sui vari charts on SO(3).

Forse una delle più concettualmente più semplici è la mappa esponenziale dall'algebra di Lie così (3). Definire un antisimmetrica, real A (che attraversa in modo (3))

A = {{0, a, -c}, 
    {-a, 0, b}, 
    {c, -b, 0}}; 

Poi MatrixExp[A] è un elemento di SO(3). Possiamo controllare che sia così, utilizzando

Transpose[MatrixExp[A]].MatrixExp[A] == IdentityMatrix[3] // Simplify 

Scrivendo t^2 = a^2 + b^2 + c^2, possiamo semplificare la matrice esponenziale fino a

{{ b^2 + (a^2 + c^2) Cos[t] , b c (1 - Cos[t]) + a t Sin[t], a b (1 - Cos[t]) - c t Sin[t]}, 
{b c (1 - Cos[t]) - a t Sin[t], c^2 + (a^2 + b^2) Cos[t] , a c (1 - Cos[t]) + b t Sin[t]}, 
{a b (1 - Cos[t]) + c t Sin[t], a c (1 - Cos[t]) - b t Sin[t], a^2 + (b^2 + c^2) Cos[t]}}/t^2 

noti che questo è fondamentalmente la stessa parametrizzazione come RotationMatrix dà. Confronta con l'uscita dal

RotationMatrix[s, {b, c, a}] // ComplexExpand // Simplify[#, Trig -> False] &; 
% /. a^2 + b^2 + c^2 -> 1 
+0

Esplicito ma vero – acl

+0

Ottima risposta. Tuttavia, preferisco definire una matrice che soddisfi le condizioni SO (3) più direttamente ... vedi la mia risposta sopra, e fammi sapere cosa ne pensi. Marcello – marcellus

4

ho trovato un modo "diretto" per imporre ortogonalità speciale. Vedi sotto.

(*DEFINITION OF ORTHOGONALITY AND SELF ADJUNCTNESS CONDITIONS:*) 
MinorMatrix[m_List?MatrixQ] := Map[Reverse, Minors[m], {0, 1}] 
CofactorMatrix[m_List?MatrixQ] := MapIndexed[#1 (-1)^(Plus @@ #2) &, MinorMatrix[m], {2}] 
UpperTriangle[ m_List?MatrixQ] := {m[[1, 1 ;; 3]], {0, m[[2, 2]], m[[2, 3]]}, {0, 0, m[[3, 3]]}}; 
FlatUpperTriangle[m_List?MatrixQ] := Flatten[{m[[1, 1 ;; 3]], m[[2, 2 ;; 3]], m[[3, 3]]}]; 
Orthogonalityconditions[m_List?MatrixQ] := Thread[FlatUpperTriangle[m.Transpose[m]] == FlatUpperTriangle[IdentityMatrix[3]]]; 
Selfadjunctconditions[m_List?MatrixQ] := Thread[FlatUpperTriangle[CofactorMatrix[m]] == FlatUpperTriangle[Transpose[m]]]; 
SO3conditions[m_List?MatrixQ] := Flatten[{Selfadjunctconditions[m], Orthogonalityconditions[m]}]; 

(*Building of an SO(3) matrix*) 
mat = Table[Subscript[m, i, j], {i, 3}, {j, 3}]; 
$Assumptions = SO3conditions[mat] 

Poi

Simplify[Det[mat]] 

dà 1; ... e

MatrixForm[Simplify[mat.Transpose[mat]] 

dà la matrice identità; ... finalmente

MatrixForm[Simplify[CofactorMatrix[mat] - Transpose[mat]]] 

dà una matrice zero.

========================================= ===========

Questo è quello che stavo cercando quando ho fatto la mia domanda! Tuttavia, fammi sapere il tuo pensiero su questo metodo.

Marcello

2

Anche se mi piace molto l'idea di risposta Marcello alla sua domanda, non è del tutto corretta. Purtroppo, le condizioni in cui arriva determinano anche

Simplify[Transpose[mat] - mat] 

valutazione su una matrice zero! Questo chiaramente non è giusto. Ecco un approccio che è sia corretta e più diretto:

OrthogonalityConditions[m_List?MatrixQ] := Thread[Flatten[m.Transpose[m]] == Flatten[IdentityMatrix[3]]]; 
SO3Conditions[m_List?MatrixQ] := Flatten[{OrthogonalityConditions[m], Det[m] == 1}]; 

cioè moltiplicando una matrice di rotazione per i suoi risultati di trasposizione nella matrice di identità, e il determinante di una matrice di rotazione è 1.

Problemi correlati