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


package require struct::matrix
package require math::complexnumbers
 
proc complexMatrix.equal {m1 m2 {epsilon 1e-14}} {
    if {[$m1 rows] != [$m2 rows] || [$m1 columns] != [$m2 columns]} {
	return 0
    }
    # Compute the magnitude of the difference between two complex numbers
    set ceq [list apply {{epsilon a b} {
	expr {[mod [- $a $b]] < $epsilon}
    } ::math::complexnumbers} $epsilon]
    for {set i 0} {$i<[$m1 columns]} {incr i} {
	for {set j 0} {$j<[$m1 rows]} {incr j} {
	    if {![{*}$ceq [$m1 get cell $i $j] [$m2 get cell $i $j]]} {
		return 0
	    }
	}
    }
    return 1
}
 
proc complexMatrix.multiply {a b} {
    if {[$a columns] != [$b rows]} {
        error "incompatible sizes"
    }
    # Simplest to use a lambda in the complex NS
    set cpm {{sum a b} {
	+ $sum [* $a $b]
    } ::math::complexnumbers}
    set c0 [math::complexnumbers::complex 0.0 0.0];   # Complex zero
    set c [struct::matrix]
    $c add columns [$b columns]
    $c add rows [$a rows]
    for {set i 0} {$i < [$a rows]} {incr i} {
        for {set j 0} {$j < [$b columns]} {incr j} {
            set sum $c0
	    foreach rv [$a get row $i] cv [$b get column $j] {
		set sum [apply $cpm $sum $rv $cv]
            }
	    $c set cell $j $i $sum
        }
    }
    return $c
}
 
proc complexMatrix.conjugateTranspose {matrix} {
    set mat [struct::matrix]
    $mat = $matrix
    $mat transpose
    for {set c 0} {$c < [$mat columns]} {incr c} {
	for {set r 0} {$r < [$mat rows]} {incr r} {
	    set val [$mat get cell $c $r]
	    $mat set cell $c $r [math::complexnumbers::conj $val]
	}
    }
    return $mat
}