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 Ada.Text_IO; use Ada.Text_IO;
with Ada.Complex_Text_IO; use Ada.Complex_Text_IO;
with Ada.Numerics.Complex_Types; use Ada.Numerics.Complex_Types;
with Ada.Numerics.Complex_Arrays; use Ada.Numerics.Complex_Arrays;
procedure ConTrans is
   subtype CM is Complex_Matrix;
   S2O2 : constant Float := 0.7071067811865;
 
   procedure Print (mat : CM) is begin
      for row in mat'Range(1) loop for col in mat'Range(2) loop
         Put(mat(row,col), Exp=>0, Aft=>4);
      end loop; New_Line; end loop;
   end Print;
 
   function almostzero(mat : CM; tol : Float) return Boolean is begin
      for row in mat'Range(1) loop for col in mat'Range(2) loop
         if abs(mat(row,col)) > tol then return False; end if;
      end loop; end loop;
      return True;
   end almostzero;
 
   procedure Examine (mat : CM) is
      CT : CM := Conjugate (Transpose(mat));
      isherm, isnorm, isunit : Boolean;
   begin
      isherm := almostzero(mat-CT, 1.0e-6);
      isnorm := almostzero(mat*CT-CT*mat, 1.0e-6);
      isunit := almostzero(CT-Inverse(mat), 1.0e-6);
      Print(mat);
      Put_Line("Conjugate transpose:"); Print(CT);
      Put_Line("Hermitian?: " & isherm'Img);
      Put_Line("Normal?: " & isnorm'Img);
      Put_Line("Unitary?: " & isunit'Img);
   end Examine;
 
   hmat : CM := ((3.0+0.0*i, 2.0+1.0*i), (2.0-1.0*i, 1.0+0.0*i));
   nmat : CM := ((1.0+0.0*i, 1.0+0.0*i, 0.0+0.0*i),
                 (0.0+0.0*i, 1.0+0.0*i, 1.0+0.0*i),
                 (1.0+0.0*i, 0.0+0.0*i, 1.0+0.0*i));
   umat : CM := ((S2O2+0.0*i, S2O2+0.0*i, 0.0+0.0*i),
                 (0.0+S2O2*i, 0.0-S2O2*i, 0.0+0.0*i),
                 (0.0+0.0*i, 0.0+0.0*i, 0.0+1.0*i));
begin
   Put_Line("hmat:"); Examine(hmat); New_Line;
   Put_Line("nmat:"); Examine(nmat); New_Line;
   Put_Line("umat:"); Examine(umat);
end ConTrans;