extern crate num; // crate for complex numbers use num::complex::Complex; use std::ops::Mul; use std::fmt; #[derive(Debug, PartialEq)] struct Matrix { grid: [[Complex; 2]; 2], // used to represent matrix } impl Matrix { // implements a method call for calculating the conjugate transpose fn conjugate_transpose(&self) -> Matrix { Matrix {grid: [[self.grid[0][0].conj(), self.grid[1][0].conj()], [self.grid[0][1].conj(), self.grid[1][1].conj()]]} } } impl Mul for Matrix { // implements '*' (multiplication) for the matrix type Output = Matrix; fn mul(self, other: Matrix) -> Matrix { Matrix {grid: [[self.grid[0][0]*other.grid[0][0] + self.grid[0][1]*other.grid[1][0], self.grid[0][0]*other.grid[0][1] + self.grid[0][1]*other.grid[1][1]], [self.grid[1][0]*other.grid[0][0] + self.grid[1][1]*other.grid[1][0], self.grid[1][0]*other.grid[1][0] + self.grid[1][1]*other.grid[1][1]]]} } } impl Copy for Matrix {} // implemented to prevent 'moved value' errors in if statements below impl Clone for Matrix { fn clone(&self) -> Matrix { *self } } impl fmt::Display for Matrix { // implemented to make output nicer fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "({}, {})\n({}, {})", self.grid[0][0], self.grid[0][1], self.grid[1][0], self.grid[1][1]) } } fn main() { let a = Matrix {grid: [[Complex::new(3.0, 0.0), Complex::new(2.0, 1.0)], [Complex::new(2.0, -1.0), Complex::new(1.0, 0.0)]]}; let b = Matrix {grid: [[Complex::new(0.5, 0.5), Complex::new(0.5, -0.5)], [Complex::new(0.5, -0.5), Complex::new(0.5, 0.5)]]}; test_type(a); test_type(b); } fn test_type(mat: Matrix) { let identity = Matrix {grid: [[Complex::new(1.0, 0.0), Complex::new(0.0, 0.0)], [Complex::new(0.0, 0.0), Complex::new(1.0, 0.0)]]}; let mat_conj = mat.conjugate_transpose(); println!("Matrix: \n{}\nConjugate transpose: \n{}", mat, mat_conj); if mat == mat_conj { println!("Hermitian?: TRUE"); } else { println!("Hermitian?: FALSE"); } if mat*mat_conj == mat_conj*mat { println!("Normal?: TRUE"); } else { println!("Normal?: FALSE"); } if mat*mat_conj == identity { println!("Unitary?: TRUE"); } else { println!("Unitary?: FALSE"); } }