# Matrix operations

The matrix $\mathbf{B}$, defined below, may be manipulated as follows: \begin{align*} \mathbf{B} = \left( \begin{array}{cc} 1 & 3-j \\ 3j & -1 + j \end{array} \right), & \quad \mathbf{B}^\mathrm{T} = \left( \begin{array}{cc} 1 & 3j \\ 3-j & -1 + j \end{array} \right)\\ \mathbf{B}^\mathrm{\dagger} = \left( \begin{array}{cc} 1 & -3j \\ 3+j & -1 - j \end{array} \right), & \quad \mathbf{B}^{-1} = \left( \begin{array}{cc} -\frac{1}{20}-\frac{3}{20}j & \frac{1}{20} - \frac{7}{20}j \\ \frac{3}{10}+\frac{3}{20}j & -\frac{1}{20} + \frac{1}{10}j \end{array} \right). \end{align*}

In [x]: B = np.matrix([[1, 3-1j], [3j, -1+1j]])
In [x]: print(B)
[[ 1.+0.j  3.-1.j]
[ 0.+3.j -1.+1.j]]

In [x]: print(B.T)
[[ 1.+0.j  0.+3.j]
[ 3.-1.j -1.+1.j]]

In [x]: print(B.H)
[[ 1.-0.j  0.-3.j]
[ 3.+1.j -1.-1.j]]

In [x]: print(B.I)
[[-0.05-0.15j  0.05-0.35j]
[ 0.30+0.15j -0.05+0.1j ]]


Note that although these derived matrices look like attributes, they are not calculated until requested (they are properties of the matrix class which in this case are really class methods masquerading as attributes) and so the use of the matrix class is not significantly slower than using regular ndarrays.

A few other common matrix operations are found elsewhere in the NumPy package, including the trace, determinant, eigenvalues and (right) eigenvectors:

In [x]: print(np.trace(B))
1j
In [x]: print(np.linalg.det(B))
(-4-8j)
In [x]: eigenvalues, eigenvectors = np.linalg.eig(B)
In [x]: print(eigenvalues, eigenvectors, sep='\n\n')
[ 2.50851535+2.09456868j -2.50851535-1.09456868j]

[[ 0.77468569+0.j         -0.52924821+0.38116633j]
[ 0.18832434+0.60365224j  0.75802940+0.j        ]]