quantum2/gate.rs
1//! Gate library code (public for pedagogical reasons).
2
3use ket::Ket;
4use matrix::Matrix;
5
6/// Represents a _quantum gate_: a quantum regster transformation.
7///
8/// This gate is tagged with a `width`, and contains a unitary matrix
9/// representing the numerical transformation in the computational
10/// basis.
11///
12/// This gate may be _applied_ to a ket to update the ket's state.
13///
14/// Currently we do not check whether the matrix is unitary.
15///
16/// See [Wikipedia](https://en.wikipedia.org/wiki/Quantum_computing#Operation)
17/// for more information.
18#[derive(Debug, PartialEq)]
19pub struct Gate {
20 width: usize,
21 matrix: Matrix,
22}
23
24impl Gate {
25 /// Construct a new quantum gate, given `width` and computational basis matrix.
26 ///
27 /// Currently we do not check whether the matrix is unitary.
28 ///
29 /// # Panics
30 ///
31 /// We panic if the supplied matrix is non-square or not of dimension `width`.
32 pub fn new(width: usize, matrix: Matrix) -> Gate {
33 assert_eq!(Ket::size(width), matrix.size());
34
35 // TODO check that det(matrix) == 1
36
37 Gate {
38 width: width,
39 matrix: matrix,
40 }
41 }
42
43 /// Width of the gate.
44 pub fn width(&self) -> usize {
45 self.width
46 }
47
48 /// Representative matrix.
49 pub fn matrix(&self) -> &Matrix {
50 &self.matrix
51 }
52
53 /// Permute the qubits on which we act.
54 ///
55 /// Qubit _i_ will be acted on as qubit _permutation[i]_ was before.
56 ///
57 /// TODO: The consumer has to work out the (complicated) matrix permutation. We ought to
58 /// be able to compute this ourselves from a qubit permutation.
59 ///
60 /// # Panics
61 ///
62 /// We panic if set(permutation) != {0, ..., self.size - 1}.
63 pub fn permute(&self, permutation: Vec<usize>) -> Gate {
64 let m = self.matrix.permute_rows(permutation);
65
66 Gate::new(self.width, m)
67 }
68}