Suppose that a matrix 



M


{\displaystyle M}

 contains complex numbers. Then the conjugate transpose of 



M


{\displaystyle M}

 is a matrix 




M

H




{\displaystyle M^{H}}

 containing the complex conjugates of the matrix transposition of 



M


{\displaystyle M}

.

 



(

M

H



)

j
i


=



M

i
j


¯




{\displaystyle (M^{H})_{ji}={\overline {M_{ij}}}}




This means that row 



j


{\displaystyle j}

, column 



i


{\displaystyle i}

 of the conjugate transpose equals the

complex conjugate of row 



i


{\displaystyle i}

, column 



j


{\displaystyle j}

 of the original matrix.



In the next list, 



M


{\displaystyle M}

 must also be a square matrix.

 A Hermitian matrix equals its own conjugate transpose: 




M

H


=
M


{\displaystyle M^{H}=M}

.
 A normal matrix is commutative in multiplication with its conjugate transpose: 




M

H


M
=
M

M

H




{\displaystyle M^{H}M=MM^{H}}

.
 A unitary matrix has its inverse equal to its conjugate transpose: 




M

H


=

M

−
1




{\displaystyle M^{H}=M^{-1}}

. 
 This is true iff 




M

H


M
=

I

n




{\displaystyle M^{H}M=I_{n}}

 and iff 



M

M

H


=

I

n




{\displaystyle MM^{H}=I_{n}}

, where 




I

n




{\displaystyle I_{n}}

 is the identity matrix.


Task

Given some matrix of complex numbers, find its conjugate transpose.

Also determine if the matrix is a:

 Hermitian matrix,
 normal matrix, or 
 unitary matrix.


See also

 MathWorld entry: conjugate transpose
 MathWorld entry: Hermitian matrix
 MathWorld entry: normal matrix
 MathWorld entry: unitary matrix


BEGIN # find and classify the complex conjugate transpose of a complex matrix #
    # returns the conjugate transpose of m #
    OP   CONJUGATETRANSPOSE = ( [,]COMPL m )[,]COMPL:
         BEGIN
            [ 2 LWB m : 2 UPB m, 1 LWB m : 1 UPB m ]COMPL result;
            FOR i FROM 1 LWB m TO 1 UPB m DO
                FOR j FROM 2 LWB m TO 2 UPB m DO
                    result[ j, i ] := CONJ m[ i, j ]
                OD
            OD;
            result
         END # CONJUGATETRANSPOSE # ;
    # returns TRUE if m is an identity matrix, FALSE otherwise #
    OP   ISIDENTITY  = ( [,]COMPL m )BOOL:
         IF 1 LWB m /= 2 LWB m OR 1 UPB m /= 2 UPB m THEN
            # non-square matrix #
            FALSE
         ELSE
            # the matrix is square #
            # returns TRUE IF v - e is nearly 0, FALSE Otherwise #
            PROC nearly equal = ( COMPL v, REAL e )BOOL: ABS re OF v - e < 1e-14 AND ABS im OF v < 1e-14;
            BOOL result := TRUE;
            FOR i FROM 1 LWB m TO 1 UPB m WHILE result DO
                IF result := nearly equal( m[ i, i ], 1 ) THEN
                    # the diagonal element is 1 - test the non-diagonals #
                    FOR j FROM 1 LWB m TO 1 UPB m WHILE result DO
                        IF i /= j THEN result := nearly equal( m[ i, j ], 0 ) FI
                    OD
                FI
            OD;
            result
         FI # ISIDENTITY # ;
    # returns m multiplied by n #
    PRIO X = 7;
    OP   X = ( [,]COMPL m, n )[,]COMPL:
         BEGIN
            [ 1 : 1 UPB m, 1 : 2 UPB n ]COMPL r;
            FOR i FROM 1 LWB m TO 1 UPB m DO
                FOR j FROM 2 LWB n TO 2 UPB n DO
                    r[ i, j ] := 0;
                    FOR k TO 2 UPB n DO
                        r[ i, j ] +:= m[ i, k ] * n[ k, j ]
                    OD
                OD
            OD;
            r
         END # X # ;
    # prints the complex matris m #
    PROC show matrix = ( [,]COMPL m )VOID:
         FOR i FROM 1 LWB m TO 1 UPB m DO
             print( ( "    " ) );
             FOR j FROM 2 LWB m TO 2 UPB m DO
                 print( ( "( ", fixed( re OF m[ i, j ], -8, 4 )
                        , ", ", fixed( im OF m[ i, j ], -8, 4 )
                        , "i )"
                        )
                      )
             OD;
             print( ( newline ) )
         OD # show matrix # ;
    # display the matrix m, its conjugate transpose and whether it is Hermitian, Normal and Unitary #
    PROC show = ( [,]COMPL m )VOID:
         BEGIN
            [,]COMPL c  = CONJUGATETRANSPOSE m;
            [,]COMPL cm = c X m;
            [,]COMPL mc = m X c;
            print( ( "Matrix:", newline ) );
            show matrix( m );
            print( ( "Conjugate Transpose:", newline ) );
            show matrix( c );
            BOOL is normal  = cm = mc;
            BOOL is unitary = IF   NOT is normal     THEN FALSE
                              ELSE     ISIDENTITY mc
                              FI;
            print( ( IF c = m      THEN "" ELSE "not " FI, "Hermitian; "
                   , IF is normal  THEN "" ELSE "not " FI, "Normal; "
                   , IF is unitary THEN "" ELSE "not " FI, "Unitary"
                   , newline
                   )
                 );
            print( ( newline ) )
         END # show # ;
    # test some matrices for Hermitian, Normal and Unitary                             #
    show( ( ( ( 3.0000 I  0.0000 ), ( 2.0000 I 1.0000 ) )
          , ( ( 2.0000 I -1.0000 ), ( 1.0000 I 0.0000 ) )
          )
        );
    show( ( ( ( 1.0000 I 0.0000 ), ( 1.0000 I  0.0000 ), ( 0.0000 I 0.0000 ) )
          , ( ( 0.0000 I 0.0000 ), ( 1.0000 I  0.0000 ), ( 1.0000 I 0.0000 ) )
          , ( ( 1.0000 I 0.0000 ), ( 0.0000 I  0.0000 ), ( 1.0000 I 0.0000 ) )
          )
        );
    REAL rh = sqrt( 0.5 );
    show( ( ( ( rh     I 0.0000 ), ( rh     I  0.0000 ), ( 0.0000 I 0.0000 ) )
          , ( ( 0.0000 I rh     ), ( 0.0000 I - rh    ), ( 0.0000 I 0.0000 ) )
          , ( ( 0.0000 I 0.0000 ), ( 0.0000 I  0.0000 ), ( 0.0000 I 1.0000 ) )
          )
        )
END