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


# Computes conjugate transpose of M
let conjTransp = function conjTransp(M) {
	return map(range(sizeof M[0]), function(row) {
		return map(range(sizeof M), function(col) {
			return cplx_conj(M[col][row]);
		});
	});
};
 
# Helper for cplxMatMul
let cplxVecScalarMul = function cplxVecScalarMul(A, B, row, col) {
	var M = { "re": 0.0, "im": 0.0 };
	let N = sizeof A;
	for (var i = 0; i < N; i++) {
		let P = cplx_mul(A[row][i], B[i][col]);
		M = cplx_add(M, P);
	}
	return M;
};
 
# Multiplies matrices A and B
# A and B are assumed to be square and of the same size,
# this condition is not checked.
let cplxMatMul = function cplxMatMul(A, B) {
	var R = {};
	let N = sizeof A;
	for (var row = 0; row < N; row++) {
		R[row] = {};
		for (var col = 0; col < N; col++) {
			R[row][col] = cplxVecScalarMul(A, B, row, col);
		}
	}
	return R;
};
 
# Helper for creating an array representing a complex number
# given its textual representation
let _ = function makeComplex(str) {
	let sep = indexof(str, "+", 1);
	if sep < 0 {
		sep = indexof(str, "-", 1);
	}
	let reStr = substrto(str, sep);
	let imStr = substrfrom(str, sep);
	return { "re": tofloat(reStr), "im": tofloat(imStr) };
};
 
# Formats a complex matrix
let printCplxMat = function printCplxMat(M) {
	foreach(M, function(i, row) {
		foreach(row, function(j, elem) {
			printf("    %.2f%+.2fi", elem.re, elem.im);
		});
		print();
	});
};
 
# A Hermitian matrix
let H = {
	{ _("3+0i"), _("2+1i") },
	{ _("2-1i"), _("0+0i") }
};
 
# A normal matrix
let N = {
	{ _("1+0i"), _("1+0i"), _("0+0i") },
	{ _("0+0i"), _("1+0i"), _("1+0i") },
	{ _("1+0i"), _("0+0i"), _("1+0i") }
};
 
# A unitary matrix
let U = {
	{ _("0.70710678118+0i"), _("0.70710678118+0i"), _("0+0i") },
	{ _("0-0.70710678118i"), _("0+0.70710678118i"), _("0+0i") },
	{ _("0+0i"),             _("0+0i"),             _("0+1i") }
};
 
 
print("Hermitian matrix:\nH = ");
printCplxMat(H);
print("H* = ");
printCplxMat(conjTransp(H));
print();
 
print("Normal matrix:\nN = ");
printCplxMat(N);
print("N* = ");
printCplxMat(conjTransp(N));
print("N* x N = ");
printCplxMat(cplxMatMul(conjTransp(N), N));
print("N x N* = ");
printCplxMat(cplxMatMul(N, conjTransp(N)));
print();
 
print("Unitary matrix:\nU = ");
printCplxMat(U);
print("U* = ");
printCplxMat(conjTransp(U));
print("U x U* = ");
printCplxMat(cplxMatMul(U, conjTransp(U)));
print();