Task: Conjugate transpose




Go: package main

import (
    "fmt"
    "math"
    "math/cmplx"
)


type matrix struct {
    ele  []complex128
    cols int
}


func (m *matrix) conjTranspose() *matrix {
    r := &matrix{make([]complex128, len(m.ele)), len(m.ele) / m.cols}
    rx := 0
    for _, e := range m.ele {
        r.ele[rx] = cmplx.Conj(e)
        rx += r.cols
        if rx >= len(r.ele) {
            rx -= len(r.ele) - 1
        }
    }
    return r
}


func main() {
    show("h", matrixFromRows([][]complex128{
        {3, 2 + 1i},
        {2 - 1i, 1}}))

    show("n", matrixFromRows([][]complex128{
        {1, 1, 0},
        {0, 1, 1},
        {1, 0, 1}}))

    show("u", matrixFromRows([][]complex128{
        {math.Sqrt2 / 2, math.Sqrt2 / 2, 0},
        {math.Sqrt2 / -2i, math.Sqrt2 / 2i, 0},
        {0, 0, 1i}}))
}

func show(name string, m *matrix) {
    m.print(name)
    ct := m.conjTranspose()
    ct.print(name + "_ct")

    fmt.Println("Hermitian:", m.equal(ct, 1e-14))

    mct := m.mult(ct)
    ctm := ct.mult(m)
    fmt.Println("Normal:", mct.equal(ctm, 1e-14))

    i := eye(m.cols)
    fmt.Println("Unitary:", mct.equal(i, 1e-14) && ctm.equal(i, 1e-14))
}


func matrixFromRows(rows [][]complex128) *matrix {
    m := &matrix{make([]complex128, len(rows)*len(rows[0])), len(rows[0])}
    for rx, row := range rows {
        copy(m.ele[rx*m.cols:(rx+1)*m.cols], row)
    }
    return m
}

func eye(n int) *matrix {
    r := &matrix{make([]complex128, n*n), n}
    n++
    for x := 0; x < len(r.ele); x += n {
        r.ele[x] = 1
    }
    return r
}


func (m *matrix) print(heading string) {
    fmt.Print("\n", heading, "\n")
    for e := 0; e < len(m.ele); e += m.cols {
        fmt.Printf("%6.3f ", m.ele[e:e+m.cols])
        fmt.Println()
    }
}


func (a *matrix) equal(b *matrix, ε float64) bool {
    for x, aEle := range a.ele {
        if math.Abs(real(aEle)-real(b.ele[x])) > math.Abs(real(aEle))*ε ||
            math.Abs(imag(aEle)-imag(b.ele[x])) > math.Abs(imag(aEle))*ε {
            return false
        }
    }
    return true
}


func (m1 *matrix) mult(m2 *matrix) (m3 *matrix) {
    m3 = &matrix{make([]complex128, (len(m1.ele)/m1.cols)*m2.cols), m2.cols}
    for m1c0, m3x := 0, 0; m1c0 < len(m1.ele); m1c0 += m1.cols {
        for m2r0 := 0; m2r0 < m2.cols; m2r0++ {
            for m1x, m2x := m1c0, m2r0; m2x < len(m2.ele); m2x += m2.cols {
                m3.ele[m3x] += m1.ele[m1x] * m2.ele[m2x]
                m1x++
            }
            m3x++
        }
    }
    return m3
}








Ada: 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;