Task: Conjugate transpose

C: 

#include<stdlib.h>
#include<stdio.h>
#include<complex.h>

typedef struct
{
  int rows, cols;
  complex **z;
} matrix;

matrix
transpose (matrix a)
{
  int i, j;
  matrix b;

  b.rows = a.cols;
  b.cols = a.rows;

  b.z = malloc (b.rows * sizeof (complex *));

  for (i = 0; i < b.rows; i++)
    {
      b.z[i] = malloc (b.cols * sizeof (complex));
      for (j = 0; j < b.cols; j++)
        {
          b.z[i][j] = conj (a.z[j][i]);
        }
    }

  return b;
}

int
isHermitian (matrix a)
{
  int i, j;
  matrix b = transpose (a);

  if (b.rows == a.rows && b.cols == a.cols)
    {
      for (i = 0; i < b.rows; i++)
        {
          for (j = 0; j < b.cols; j++)
            {
              if (b.z[i][j] != a.z[i][j])
                return 0;
            }
        }
    }

  else
    return 0;

  return 1;
}

matrix
multiply (matrix a, matrix b)
{
  matrix c;
  int i, j;

  if (a.cols == b.rows)
    {
      c.rows = a.rows;
      c.cols = b.cols;

      c.z = malloc (c.rows * (sizeof (complex *)));

      for (i = 0; i < c.rows; i++)
        {
          c.z[i] = malloc (c.cols * sizeof (complex));
          c.z[i][j] = 0 + 0 * I;
          for (j = 0; j < b.cols; j++)
            {
              c.z[i][j] += a.z[i][j] * b.z[j][i];
            }
        }

    }

  return c;
}

int
isNormal (matrix a)
{
  int i, j;
  matrix a_ah, ah_a;

  if (a.rows != a.cols)
    return 0;

  a_ah = multiply (a, transpose (a));
  ah_a = multiply (transpose (a), a);

  for (i = 0; i < a.rows; i++)
    {
      for (j = 0; j < a.cols; j++)
        {
          if (a_ah.z[i][j] != ah_a.z[i][j])
            return 0;
        }
    }

  return 1;
}

int
isUnitary (matrix a)
{
  matrix b;
  int i, j;
  if (isNormal (a) == 1)
    {
      b = multiply (a, transpose(a));

      for (i = 0; i < b.rows; i++)
        {
          for (j = 0; j < b.cols; j++)
            {
              if ((i == j && b.z[i][j] != 1) || (i != j && b.z[i][j] != 0))
                return 0;
            }
        }
      return 1;
    }
  return 0;
}


int
main ()
{
  complex z = 3 + 4 * I;
  matrix a, aT;
  int i, j;
  printf ("Enter rows and columns :");
  scanf ("%d%d", &a.rows, &a.cols);

  a.z = malloc (a.rows * sizeof (complex *));
  printf ("Randomly Generated Complex Matrix A is : ");
  for (i = 0; i < a.rows; i++)
    {
      printf ("\n");
      a.z[i] = malloc (a.cols * sizeof (complex));
      for (j = 0; j < a.cols; j++)
        {
          a.z[i][j] = rand () % 10 + rand () % 10 * I;
          printf ("\t%f + %fi", creal (a.z[i][j]), cimag (a.z[i][j]));
        }
    }

  aT = transpose (a);

  printf ("\n\nTranspose of Complex Matrix A is : ");
  for (i = 0; i < aT.rows; i++)
    {
      printf ("\n");
      aT.z[i] = malloc (aT.cols * sizeof (complex));
      for (j = 0; j < aT.cols; j++)
        {
          aT.z[i][j] = rand () % 10 + rand () % 10 * I;
          printf ("\t%f + %fi", creal (aT.z[i][j]), cimag (aT.z[i][j]));
        }
    }

  printf ("\n\nComplex Matrix A %s hermitian",
          isHermitian (a) == 1 ? "is" : "is not");
  printf ("\n\nComplex Matrix A %s unitary",
          isUnitary (a) == 1 ? "is" : "is not");
  printf ("\n\nComplex Matrix A %s normal",
          isNormal (a) == 1 ? "is" : "is not");



  return 0;
}







Python: def conjugate_transpose(m):
    return tuple(tuple(n.conjugate() for n in row) for row in zip(*m))

def mmul( ma, mb):
    return tuple(tuple(sum( ea*eb for ea,eb in zip(a,b)) for b in zip(*mb)) for a in ma)

def mi(size):
    'Complex Identity matrix'
    sz = range(size)
    m = [[0 + 0j for i in sz] for j in sz]
    for i in range(size):
        m[i][i] = 1 + 0j
    return tuple(tuple(row) for row in m)

def __allsame(vector):
    first, rest = vector[0], vector[1:]
    return all(i == first for i in rest)

def __allnearsame(vector, eps=1e-14):
    first, rest = vector[0], vector[1:]
    return all(abs(first.real - i.real) < eps and abs(first.imag - i.imag) < eps
               for i in rest)

def isequal(matrices, eps=1e-14):
    'Check any number of matrices for equality within eps'
    x = [len(m) for m in matrices]
    if not __allsame(x): return False
    y = [len(m[0]) for m in matrices]
    if not __allsame(y): return False
    for s in range(x[0]):
        for t in range(y[0]):
            if not __allnearsame([m[s][t] for m in matrices], eps): return False
    return True
    

def ishermitian(m, ct):
    return isequal([m, ct])

def isnormal(m, ct):
    return isequal([mmul(m, ct), mmul(ct, m)])

def isunitary(m, ct):
    mct, ctm = mmul(m, ct), mmul(ct, m)
    mctx, mcty, cmx, ctmy = len(mct), len(mct[0]), len(ctm), len(ctm[0])
    ident = mi(mctx)
    return isequal([mct, ctm, ident])

def printm(comment, m):
    print(comment)
    fields = [['%g%+gj' % (f.real, f.imag) for f in row] for row in m]
    width = max(max(len(f) for f in row) for row in fields)
    lines = (', '.join('%*s' % (width, f) for f in row) for row in fields)
    print('\n'.join(lines))

if __name__ == '__main__':
    for matrix in [
            ((( 3.000+0.000j), (+2.000+1.000j)), 
            (( 2.000-1.000j), (+1.000+0.000j))),

            ((( 1.000+0.000j), (+1.000+0.000j), (+0.000+0.000j)), 
            (( 0.000+0.000j), (+1.000+0.000j), (+1.000+0.000j)), 
            (( 1.000+0.000j), (+0.000+0.000j), (+1.000+0.000j))),

            ((( 2**0.5/2+0.000j), (+2**0.5/2+0.000j), (+0.000+0.000j)), 
            (( 0.000+2**0.5/2j), (+0.000-2**0.5/2j), (+0.000+0.000j)), 
            (( 0.000+0.000j), (+0.000+0.000j), (+0.000+1.000j)))]:
        printm('\nMatrix:', matrix)
        ct = conjugate_transpose(matrix)
        printm('Its conjugate transpose:', ct)
        print('Hermitian? %s.' % ishermitian(matrix, ct))
        print('Normal?    %s.' % isnormal(matrix, ct))
        print('Unitary?   %s.' % isunitary(matrix, ct))