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


with javascript_semantics
include complex.e
 
procedure m_print(sequence a)
    a = deep_copy(a)
    integer l = length(a)
    for i=1 to l do
        for j=1 to l do
            a[i][j] = complex_sprint(a[i][j])
        end for
        a[i] = "["&join(a[i],",")&"]"
    end for
    puts(1,join(a,"\n")&"\n")
end procedure
 
function conjugate_transpose(sequence a)
    sequence res = deep_copy(a)
    integer l = length(a)
    for i=1 to l do
        for j=1 to l do
          res[i][j] = complex_conjugate(a[j][i])
        end for
    end for
    return res
end function
 
function m_unitary(sequence act)
-- note: a was normal and act = a*ct already
    integer l = length(act)
    for i=1 to l do
        for j=1 to l do
            atom {re,im} = act[i,j]
            -- round to nearest billionth
            -- (powers of 2 help the FPU out)
            re = round(re,1024*1024*1024)
            im = round(im,1024*1024*1024)
            if im!=0
            or (i=j and re!=1)
            or (i!=j and re!=0) then
                return 0
            end if
        end for
    end for
    return 1
end function
 
function m_mul(sequence a, sequence b)
    sequence res = sq_mul(a,0)
    integer l = length(a)
    for i=1 to l do
        for j=1 to l do
            for k=1 to l do
                res[i][j] = complex_add(res[i][j],complex_mul(a[i][k],b[k][j]))
            end for
        end for
    end for
    return res
end function
 
procedure test(sequence a)
    sequence ct = conjugate_transpose(a)
    printf(1,"Original matrix:\n")
    m_print(a)
    printf(1,"Conjugate transpose:\n")
    m_print(ct)
    -- note: rounding similar to that in m_unitary may be rqd (in a similar 
    --       loop in a new m_equal function) on these two equality tests, 
    --       but as it is, all tests pass with the builtin = operator.
    printf(1,"Hermitian?: %t\n",a=ct) -- (this one)
    sequence act = m_mul(a,ct), cta = m_mul(ct,a)
    bool normal = act=cta                                   -- (&this one)
    printf(1,"Normal?: %t\n",normal)
    printf(1,"Unitary?: %t\n\n",normal and m_unitary(act))
end procedure
 
constant x = sqrt(2)/2,
         tests = {{{{3, 0},{2,1}},
                   {{2,-1},{1,0}}},
 
                  {{{ 1, 0},{ 1, 1},{ 0, 2}},
                   {{ 1,-1},{ 5, 0},{-3, 0}},
                   {{ 0,-2},{-3, 0},{ 0, 0}}},
 
                  {{{0.5,+0.5},{0.5,-0.5}},
                   {{0.5,-0.5},{0.5,+0.5}}},
 
                  {{{ 1, 0},{ 1, 0},{ 0, 0}},
                   {{ 0, 0},{ 1, 0},{ 1, 0}},
                   {{ 1, 0},{ 0, 0},{ 1, 0}}},
 
                  {{{x, 0},{x, 0},{0, 0}},
                   {{0,-x},{0, x},{0, 0}},
                   {{0, 0},{0, 0},{0, 1}}},
 
                  {{{2,7},{9,-5}},
                   {{3,4},{8,-6}}}}
 
papply(tests,test)
