Message Boards Message Boards

1
|
14954 Views
|
8 Replies
|
13 Total Likes
View groups...
Share
Share this post:

Block-diagonalization of a real skew-symmetric matrix

Posted 12 years ago
Hi all,

I'm in trouble with this problem. It is well known (by everyone but me, it seems) that a real skew-symmetric matrix can be put in a block-diagonal form, where the diagonal matrices are real symplectic 2x2 matrices, each one multiplied by real coefficient, linked to the original matrix eigenvalues; moreover, the transformation leading to this block-diagonal form shall be orthogonal. My question is: is there a way, using Mathematica, to explicitly get this trasformation?

Thanks everyone!
POSTED BY: Luca Taddia
8 Replies
Posted 12 years ago
Itai,
thank you very much! In exactly one line what you wrote makes the job. Actually I did not understand very well what you wrote, but I am going to study it!
POSTED BY: Luca Taddia
Posted 12 years ago
Jose,
thank you very much, but what you wrote puts the matrix in the block-diagonal form, that is a thing i was already able to do. My question is about the orthogonal transformation putting my matrix that way...
POSTED BY: Luca Taddia
Posted 12 years ago
That's right.  For a normal matrix, the Schur decomposition and spectral decomposition coincide.  Our Schur decomposition is limited to approximate numeric matrices, so depending on whether support is needed for exact and/or symbolic inputs, it may be a good choice.  realDiagnolization, above, uses the fact that we have a very specific matrix type to provide an answer that works for symbolic and exact numeric inputs as well.
POSTED BY: Itai Seggev
I get something along these lines using SchurDecomposition.
 Chop[
   SchurDecomposition[
    N@{{0, 10, 10, 9}, {-10, 0, 8, 1}, {-10, -8, 0, 4}, {-9, -1, -4,
       0}}]]
 
 {{{0.913074613626,
    0.0263138475375, -0.117925531533, -0.389481579016}, \
 {0.308870821239, 0.592532858842, 0.342614325914,
    0.660393103127}, {-0.180772611642,
   0.681158781925, -0.689006457281, -0.169156964123}, \
{-0.195486134086, 0.429226171646,
   0.627677540235, -0.619331066909}}, {{0, 18.1802797984, 0,
   0}, {-18.1802797984, 0, 0, 0}, {0, 0, 0, 5.61047470838}, {0,
   0, -5.61047470838, 0}}}
POSTED BY: Daniel Lichtblau
Posted 12 years ago
There is no builtin function which does this, but it isn't hard to construct one yourself. The basic process is quite similar to the normal diagonalization of matrices; the key point is that the real and imaginary parts of the eigenvectors are part of the same two-dimensional subspace. Thus, rather than constructing the orthogonal matrix out of eigenvectors, you use the real and imaginary parts from each complex-conjugate pair. Since the function Eigenvectors keeps the conjugate pairs together, you can do this:
realDiagnolization[skew_] :=Normalize /@ Flatten[{Re[#], Im[#]}&/@ Eigenvectors[skew][[1;;-1;;2]],1]
Here [[1;;-1;;2]] selects only the odd eigenvectors, Map (/@) is used to create the real and imaginary parts, Flatten is used to ensure we get n vectors (instead of n/2 pairs of vectors), and Normalize makes them all unit. You can then construct the diagnoal form as
realDiagnolization[skew]. skew. Transpose[realDiagnolization[skew]]
For example, consider this matrix:
In[150]:= skew//MatrixForm
Out[150]//MatrixForm= (0 10 10 9
-10 0 8 1
-10 -8 0 4
-9 -1 -4 0
)
We have (I'm using N and Chop to create a numerical approximate that fits on a screen):
In[148]:= (u=realDiagnolization[skew]//N//Chop)//MatrixForm
Out[148]//MatrixForm= (-0.354501 0.411221 0.694821 0.471646
-0.841859 -0.526682 -0.11781 0
0.189613 -0.219952 -0.371642 0.881788
-0.360068 0.710721 -0.604339 0
)
And
In[149]:= u . skew . Transpose[u]//Chop//MatrixForm
Out[149]//MatrixForm= (0 18.1803 0 0
-18.1803 0 0 0
0 0 0 5.61047
0 0 -5.61047 0
)
This is in fact the matrix returned by Jose's CanonicalAntisymmetricMatrix function
In[145]:= CanonicalAntisymmetricMatrix//N//MatrixForm
Out[145]//MatrixForm= (0. 18.1803 0. 0.
-18.1803 0. 0. 0.
0. 0. 0. 5.61047
0. 0. -5.61047 0.
)
POSTED BY: Itai Seggev
I think this function taking the original antisymmetric matrix will do what you need:
 CanonicalAntisymmetricMatrix[asmatrix : {{0 | 0.}}] := asmatrix;
 CanonicalAntisymmetricMatrix[asmatrix_] := With[{n = Length[asmatrix]},
   If[EvenQ[n],
     KroneckerProduct[
      DiagonalMatrix[
       Take[-I Eigenvalues[asmatrix], {1, n, 2}]], {{0, 1}, {-1, 0}}],
     ArrayPad[
      KroneckerProduct[
       DiagonalMatrix[
       Take[-I Eigenvalues[asmatrix], {1, n - 1, 2}]], {{0, 1}, {-1,
        0}}], {{0, 1}, {0, 1}}]
    ] /; n >= 2
  ]

Jose.
Posted 12 years ago
I don't think it's any of them...
POSTED BY: Luca Taddia
Maybe you are looking for one of these matrix decomposition functions (possibly JordanDecomposition)?

http://reference.wolfram.com/mathematica/guide/MatrixDecompositions.html
POSTED BY: Arnoud Buzing
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract