def test_linalg(self):
     A = QuantumGate(array([[0.0, 1.0], [0.0, 0.0]]))
     B = QuantumGate(array([[0.0, 0.0], [1.0, 0.0]]))
     self.assertTrue((A.H().matrix() == B.matrix()).all())
     X = A + B
     self.assertTrue((X.matrix() == x_gate().matrix()).all())
     self.assertTrue((dot(X, X).matrix() == eye(2)).all())
Example #2
0
def function_gate(f, m, k):
    """Factory method for a gate that implements a classical function.

    Args:
        f: A function that takes a sequence of bits of length m and returns
        another sequence of bits of length k. The bit sequences are represented
        by the integers they represent in binary: e.g. "00101" would be the
        integer 5.
        m: Length of bits for the input to f.
        k: Length of bits for the output to f.
    Returns:
        The resulting gate, Uf, takes as its input a qubit system of length m+k.
        Call the first m qubits in the system "x" and the last k qubits "y":
        then the action of Uf on a pure state |x, y> is to map it to
        |x, f(x) (+) y> where (+) represents bitwise addition mod 2 (equivalent
        to the XOR operation).  It is easily shown that the map
        |x, y> --> |x, f(x) (+) y> is a bijection, which implies that Uf is a
        permutation matrix (and is therefore unitary).
    """
    # the gate operates on an (m+k)-qubit system
    G = QuantumGate(zeros((2**(m+k), 2**(m+k))))
    # filter that zeros out all but the last k bits
    FILTER = (1 << k) - 1

    for j in range(G.matrix().shape[1]):
        y = j & FILTER # y is the last k bits of the jth state
        x = j >> k # x is the state ignoring the last k bits
        # The gate maps |x,y> to |x,y + f(x)>, where + is bitwise addition mod 2
        i = (x << k) + (y ^ f(x))
        G[i,j] = 1.

    return G