Exemple #1
0
def ToffoliGate(nqubits: int, nlayers: int = 1):
    for _ in range(nlayers):
        for i in range(0, nqubits - 2, 3):
            yield gates.TOFFOLI(i, i + 1, i + 2)
        for i in range(1, nqubits - 2, 3):
            yield gates.TOFFOLI(i, i + 1, i + 2)
        for i in range(2, nqubits - 2, 3):
            yield gates.TOFFOLI(i, i + 1, i + 2)
Exemple #2
0
def test_toffoli(backend, applyx):
    if applyx:
        gatelist = [gates.X(0), gates.X(1), gates.TOFFOLI(0, 1, 2)]
    else:
        gatelist = [gates.X(1), gates.TOFFOLI(0, 1, 2)]
    final_state = apply_gates(gatelist, nqubits=3)
    target_state = np.zeros_like(final_state)
    if applyx:
        target_state[-1] = 1
    else:
        target_state[2] = 1
    K.assert_allclose(final_state, target_state)
Exemple #3
0
def test_toffoli(backend, applyx):
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    if applyx:
        gatelist = [gates.X(0), gates.X(1), gates.TOFFOLI(0, 1, 2)]
    else:
        gatelist = [gates.X(1), gates.TOFFOLI(0, 1, 2)]
    final_state = apply_gates(gatelist, nqubits=3)
    target_state = np.zeros_like(final_state)
    if applyx:
        target_state[-1] = 1
    else:
        target_state[2] = 1
    np.testing.assert_allclose(final_state, target_state)
    qibo.set_backend(original_backend)
Exemple #4
0
def test_toffoli_gate(backend):
    """Check applying Toffoli to three qubit density matrix."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    initial_psi = utils.random_numpy_state(3)
    initial_rho = np.outer(initial_psi, initial_psi.conj())
    circuit = models.Circuit(3, density_matrix=True)
    circuit.add(gates.TOFFOLI(0, 2, 1))
    final_rho = circuit(np.copy(initial_rho)).numpy()

    circuit = models.Circuit(3)
    circuit.add(gates.TOFFOLI(0, 2, 1))
    target_psi = circuit(np.copy(initial_psi)).numpy()
    target_rho = np.outer(target_psi, target_psi.conj())
    np.testing.assert_allclose(final_rho, target_rho)
    qibo.set_backend(original_backend)
Exemple #5
0
def test_multicontrol_xgate(backend):
    """Check that fallback method for X works for one or two controls."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    c1 = Circuit(3)
    c1.add(gates.X(0))
    c1.add(gates.X(2).controlled_by(0))
    final_state = c1.execute().numpy()
    c2 = Circuit(3)
    c2.add(gates.X(0))
    c2.add(gates.CNOT(0, 2))
    target_state = c2.execute().numpy()
    np.testing.assert_allclose(final_state, target_state)

    c1 = Circuit(3)
    c1.add(gates.X(0))
    c1.add(gates.X(2))
    c1.add(gates.X(1).controlled_by(0, 2))
    final_state = c1.execute().numpy()
    c2 = Circuit(3)
    c2.add(gates.X(0))
    c2.add(gates.X(2))
    c2.add(gates.TOFFOLI(0, 2, 1))
    target_state = c2.execute().numpy()
    np.testing.assert_allclose(final_state, target_state)
    qibo.set_backend(original_backend)
Exemple #6
0
def test_toffoli_gate(backend):
    """Check applying Toffoli to three qubit density matrix."""
    initial_rho = random_density_matrix(3)
    gate = gates.TOFFOLI(0, 1, 2)
    gate.density_matrix = True
    final_rho = gate(np.copy(initial_rho))

    matrix = K.to_numpy(gate.matrix)
    target_rho = np.einsum("ab,bc,cd->ad", matrix, initial_rho, matrix.conj().T)
    K.assert_allclose(final_rho, target_rho)
Exemple #7
0
def test_toffoli():
    c = Circuit(3)
    c.add(gates.Y(0))
    c.add(gates.TOFFOLI(0, 1, 2))
    c.add(gates.X(1))
    c.add(gates.TOFFOLI(0, 2, 1))
    c.add(gates.Z(2))
    c.add(gates.TOFFOLI(1, 2, 0))
    target = f"""// Generated by QIBO {__version__}
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
y q[0];
ccx q[0],q[1],q[2];
x q[1];
ccx q[0],q[2],q[1];
z q[2];
ccx q[1],q[2],q[0];"""
    assert_strings_equal(c.to_qasm(), target)
def test_controlled_x_vs_toffoli(backend):
    c1 = Circuit(3)
    c1.add(gates.X(0))
    c1.add(gates.X(2))
    c1.add(gates.X(1).controlled_by(0, 2))
    c2 = Circuit(3)
    c2.add(gates.X(0))
    c2.add(gates.X(2))
    c2.add(gates.TOFFOLI(0, 2, 1))
    K.assert_allclose(c1(), c2())
Exemple #9
0
def test_toffoli_cirq():
    c1 = Circuit(3)
    c1.add(gates.Y(0))
    c1.add(gates.TOFFOLI(0, 1, 2))
    c1.add(gates.X(1))
    c1.add(gates.TOFFOLI(0, 2, 1))
    c1.add(gates.Z(2))
    c1.add(gates.TOFFOLI(1, 2, 0))
    final_state_c1 = c1()

    c2 = circuit_from_qasm(c1.to_qasm())
    c2depth = len(cirq.Circuit(c2.all_operations()))
    assert c1.depth == c2depth
    final_state_c2 = cirq.Simulator().simulate(c2).final_state
    np.testing.assert_allclose(final_state_c1, final_state_c2, atol=_atol)

    c3 = Circuit.from_qasm(c2.to_qasm())
    assert c3.depth == c2depth
    final_state_c3 = c3()
    np.testing.assert_allclose(final_state_c3, final_state_c2, atol=_atol)
Exemple #10
0
def test_toffoli_no_effect(backend):
    """Check Toffoli gate is working properly on |010>."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    c = Circuit(3)
    c.add(gates.X(1))
    c.add(gates.TOFFOLI(0, 1, 2))
    final_state = c.execute().numpy()
    target_state = np.zeros_like(final_state)
    target_state[2] = 1.0
    np.testing.assert_allclose(final_state, target_state)
    qibo.set_backend(original_backend)
Exemple #11
0
def test_construct_unitary(backend):
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    target_matrix = np.array([[1, 1], [1, -1]]) / np.sqrt(2)
    np.testing.assert_allclose(gates.H(0).unitary, target_matrix)
    target_matrix = np.array([[0, 1], [1, 0]])
    np.testing.assert_allclose(gates.X(0).unitary, target_matrix)
    target_matrix = np.array([[0, -1j], [1j, 0]])
    np.testing.assert_allclose(gates.Y(0).unitary, target_matrix)
    target_matrix = np.array([[1, 0], [0, -1]])
    np.testing.assert_allclose(gates.Z(1).unitary, target_matrix)

    target_matrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1],
                              [0, 0, 1, 0]])
    np.testing.assert_allclose(gates.CNOT(0, 1).unitary, target_matrix)
    target_matrix = np.diag([1, 1, 1, -1])
    np.testing.assert_allclose(gates.CZ(1, 3).unitary, target_matrix)
    target_matrix = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0],
                              [0, 0, 0, 1]])
    np.testing.assert_allclose(gates.SWAP(2, 4).unitary, target_matrix)
    target_matrix = np.array([[1, 0, 0, 0, 0, 0, 0,
                               0], [0, 1, 0, 0, 0, 0, 0, 0],
                              [0, 0, 1, 0, 0, 0, 0,
                               0], [0, 0, 0, 1, 0, 0, 0, 0],
                              [0, 0, 0, 0, 1, 0, 0,
                               0], [0, 0, 0, 0, 0, 1, 0, 0],
                              [0, 0, 0, 0, 0, 0, 0, 1],
                              [0, 0, 0, 0, 0, 0, 1, 0]])
    np.testing.assert_allclose(gates.TOFFOLI(1, 2, 3).unitary, target_matrix)

    theta = 0.1234
    target_matrix = np.array([[np.cos(theta / 2.0), -1j * np.sin(theta / 2.0)],
                              [-1j * np.sin(theta / 2.0),
                               np.cos(theta / 2.0)]])
    np.testing.assert_allclose(gates.RX(0, theta).unitary, target_matrix)
    target_matrix = np.array([[np.cos(theta / 2.0), -np.sin(theta / 2.0)],
                              [np.sin(theta / 2.0),
                               np.cos(theta / 2.0)]])
    np.testing.assert_allclose(gates.RY(0, theta).unitary, target_matrix)
    target_matrix = np.diag(
        [np.exp(-1j * theta / 2.0),
         np.exp(1j * theta / 2.0)])
    np.testing.assert_allclose(gates.RZ(0, theta).unitary, target_matrix)
    target_matrix = np.diag([1, np.exp(1j * theta)])
    np.testing.assert_allclose(gates.U1(0, theta).unitary, target_matrix)
    target_matrix = np.diag([1, 1, 1, np.exp(1j * theta)])
    np.testing.assert_allclose(gates.CU1(0, 1, theta).unitary, target_matrix)
    from qibo import matrices
    target_matrix = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0],
                              [0, 0, 0, 1]])
    np.testing.assert_allclose(matrices.SWAP, target_matrix)
    qibo.set_backend(original_backend)
Exemple #12
0
def test_controlled_x_vs_toffoli(backend):
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    c1 = Circuit(3)
    c1.add(gates.X(0))
    c1.add(gates.X(2))
    c1.add(gates.X(1).controlled_by(0, 2))
    c2 = Circuit(3)
    c2.add(gates.X(0))
    c2.add(gates.X(2))
    c2.add(gates.TOFFOLI(0, 2, 1))
    np.testing.assert_allclose(c1(), c2())
    qibo.set_backend(original_backend)
Exemple #13
0
def test_fuse_circuit_three_qubit_gate(backend, max_qubits):
    """Check circuit fusion in circuit with three-qubit gate."""
    c = Circuit(4)
    c.add((gates.H(i) for i in range(4)))
    c.add(gates.CZ(0, 1))
    c.add(gates.CZ(2, 3))
    c.add(gates.TOFFOLI(0, 1, 2))
    c.add(gates.SWAP(1, 2))
    c.add((gates.H(i) for i in range(4)))
    c.add(gates.CNOT(0, 1))
    c.add(gates.CZ(2, 3))
    fused_c = c.fuse(max_qubits=max_qubits)
    K.assert_allclose(fused_c(), c(), atol=1e-12)
Exemple #14
0
def n_mCNOT(controls, target, work, err):
    """Decomposition of a multi-controlled NOT gate with m qubits of work space.
    Args:
        controls (list): quantum register used as a control for the gate.
        target (int): qubit where the NOT gate is applied.
        work (list): quantum register used as work space.
        err (float): error probability.

    Returns:
        quantum gate generator for the multi-controlled NOT gate with m qubits of work space.
    """
    i = 0
    yield gates.TOFFOLI(controls[-1], work[-1], target)
    yield error_gate(controls[-1], err)
    yield error_gate(work[-1], err)
    yield error_gate(target, err)
    for i in range(1, len(controls) - 2):
        yield gates.TOFFOLI(controls[-1 - i], work[-1 - i], work[-1 - i + 1])
        yield error_gate(controls[-1 - i], err)
        yield error_gate(work[-1 - i], err)
        yield error_gate(work[-1 - i + 1], err)
    yield gates.TOFFOLI(controls[0], controls[1], work[-1 - i])
    yield error_gate(controls[0], err)
    yield error_gate(controls[1], err)
    yield error_gate(work[-1 - i], err)
    for i in reversed(range(1, len(controls) - 2)):
        yield gates.TOFFOLI(controls[-1 - i], work[-1 - i], work[-1 - i + 1])
        yield error_gate(controls[-1 - i], err)
        yield error_gate(work[-1 - i], err)
        yield error_gate(work[-1 - i + 1], err)
    yield gates.TOFFOLI(controls[-1], work[-1], target)
    yield error_gate(controls[-1], err)
    yield error_gate(work[-1], err)
    yield error_gate(target, err)
    for i in range(1, len(controls) - 2):
        yield gates.TOFFOLI(controls[-1 - i], work[-1 - i], work[-1 - i + 1])
        yield error_gate(controls[-1 - i], err)
        yield error_gate(work[-1 - i], err)
        yield error_gate(work[-1 - i + 1], err)
    yield gates.TOFFOLI(controls[0], controls[1], work[-1 - i])
    yield error_gate(controls[0], err)
    yield error_gate(controls[1], err)
    yield error_gate(work[-1 - i], err)
    for i in reversed(range(1, len(controls) - 2)):
        yield gates.TOFFOLI(controls[-1 - i], work[-1 - i], work[-1 - i + 1])
        yield error_gate(controls[-1 - i], err)
        yield error_gate(work[-1 - i], err)
        yield error_gate(work[-1 - i + 1], err)
def test_toffoli_gate(backend):
    """Check applying Toffoli to three qubit density matrix."""
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    initial_rho = random_density_matrix(3)
    gate = gates.TOFFOLI(0, 1, 2)
    gate.density_matrix = True
    final_rho = gate(np.copy(initial_rho))

    matrix = np.array(gate.unitary)
    target_rho = np.einsum("ab,bc,cd->ad", matrix, initial_rho,
                           matrix.conj().T)
    np.testing.assert_allclose(final_rho, target_rho)
    qibo.set_backend(original_backend)
Exemple #16
0
def test_fused_gate_construct_unitary(backend, nqubits):
    gate = gates.FusedGate(0, 1)
    gate.append(gates.H(0))
    gate.append(gates.H(1))
    gate.append(gates.CZ(0, 1))
    hmatrix = np.array([[1, 1], [1, -1]]) / np.sqrt(2)
    czmatrix = np.diag([1, 1, 1, -1])
    target_matrix = czmatrix @ np.kron(hmatrix, hmatrix)
    if nqubits > 2:
        gate.append(gates.TOFFOLI(0, 1, 2))
        toffoli = np.eye(8)
        toffoli[-2:, -2:] = np.array([[0, 1], [1, 0]])
        target_matrix = toffoli @ np.kron(target_matrix, np.eye(2))
    K.assert_allclose(gate.matrix, target_matrix)
def test_toffoli_cirq(backend):
    import qibo
    original_backend = qibo.get_backend()
    qibo.set_backend(backend)
    c1 = Circuit(3)
    c1.add(gates.Y(0))
    c1.add(gates.TOFFOLI(0, 1, 2))
    c1.add(gates.X(1))
    c1.add(gates.TOFFOLI(0, 2, 1))
    c1.add(gates.Z(2))
    c1.add(gates.TOFFOLI(1, 2, 0))
    final_state_c1 = c1()

    c2 = circuit_from_qasm(c1.to_qasm())
    c2depth = len(cirq.Circuit(c2.all_operations()))
    assert c1.depth == c2depth
    final_state_c2 = cirq.Simulator().simulate(c2).final_state_vector  # pylint: disable=no-member
    np.testing.assert_allclose(final_state_c1, final_state_c2, atol=_atol)

    c3 = Circuit.from_qasm(c2.to_qasm())
    assert c3.depth == c2depth
    final_state_c3 = c3()
    np.testing.assert_allclose(final_state_c3, final_state_c2, atol=_atol)
    qibo.set_backend(original_backend)
Exemple #18
0
def test_fusion_errors():
    group = fusion.FusionGroup()
    with pytest.raises(ValueError):
        group.first_gate(2)

    group = fusion.FusionGroup()
    group.add(gates.Flatten(np.ones(4)))
    group.can_add(gates.H(0))
    with pytest.raises(RuntimeError):
        group.add(gates.H(0))

    group = fusion.FusionGroup()
    group.can_add(gates.H(0))
    group.add(gates.H(0))
    group.can_add(gates.RX(0, theta=0.1234).controlled_by(1))
    with pytest.raises(ValueError):
        group.add(gates.Flatten(np.ones(4)))

    group = fusion.FusionGroup()
    group.add(gates.RX(0, theta=0.1234).controlled_by(1))
    with pytest.raises(ValueError):
        group.add(gates.H(2))

    group = fusion.FusionGroup()
    group.add(gates.RX(0, theta=0.1234).controlled_by(1))
    with pytest.raises(ValueError):
        group.add(gates.CZ(1, 2))

    group = fusion.FusionGroup()
    with pytest.raises(ValueError):
        group.add(gates.TOFFOLI(0, 1, 2))

    group = fusion.FusionGroup()
    with pytest.raises(RuntimeError):
        group.calculate()

    # Fuse distributed circuit after gates are set
    import qibo
    if qibo.get_backend() == "custom":
        c = Circuit(4, accelerators={"/GPU:0": 2})
        c.add((gates.H(i) for i in range(4)))
        final_state = c()
        with pytest.raises(RuntimeError):
            fused_c = c.fuse()
Exemple #19
0
def adder_mod2n(a, b, x):
    """Quantum circuit for the adder modulo 2^n operation.
    Args:
        a (list): quantum register for the first number to be added.
        b (list): quantum register for the second number to be added, will be replaced by solution.
        x (int): ancillary qubit needed for the adder circuit.

    Returns:
        quantum gate generator that applies the quantum gates for addition modulo 2^n.
    """
    n = int(len(a))
    for i in range(n - 2, -1, -1):
        yield gates.CNOT(a[i], b[i])
    yield gates.CNOT(a[n - 2], x)
    yield gates.TOFFOLI(a[n - 1], b[n - 1], x)
    yield gates.CNOT(a[n - 3], a[n - 2])
    yield gates.TOFFOLI(x, b[n - 2], a[n - 2])
    yield gates.CNOT(a[n - 4], a[n - 3])
    for i in range(n - 3, 1, -1):
        yield gates.TOFFOLI(a[i + 1], b[i], a[i])
        yield gates.CNOT(a[i - 2], a[i - 1])
    yield gates.TOFFOLI(a[2], b[1], a[1])
    for i in range(n - 2, 0, -1):
        yield gates.X(b[i])
    yield gates.CNOT(x, b[n - 2])
    for i in range(n - 3, -1, -1):
        yield gates.CNOT(a[i + 1], b[i])
    yield gates.TOFFOLI(a[2], b[1], a[1])
    for i in range(2, n - 2):
        yield gates.TOFFOLI(a[i + 1], b[i], a[i])
        yield gates.CNOT(a[i - 2], a[i - 1])
        yield gates.X(b[i - 1])
    yield gates.TOFFOLI(x, b[n - 2], a[n - 2])
    yield gates.CNOT(a[n - 4], a[n - 3])
    yield gates.X(b[n - 3])
    yield gates.TOFFOLI(a[n - 1], b[n - 1], x)
    yield gates.CNOT(a[n - 3], a[n - 2])
    yield gates.X(b[n - 2])
    yield gates.CNOT(a[n - 2], x)
    for i in range(n - 1, -1, -1):
        yield gates.CNOT(a[i], b[i])
Exemple #20
0
def r_adder_mod2n(a, b, x):
    """Reversed quantum circuit for the adder modulo 2^n operation.
    Args:
        a (list): quantum register for the first number to be added.
        b (list): quantum register for result of the addition.
        x (int): ancillary qubit needed for the adder circuit.

    Returns:
        quantum gate generator that applies the quantum gates for addition modulo 2^n in reverse.
    """
    n = int(len(a))
    for i in reversed(range(n - 1, -1, -1)):
        yield gates.CNOT(a[i], b[i])
    yield gates.CNOT(a[n - 2], x)
    yield gates.X(b[n - 2])
    yield gates.CNOT(a[n - 3], a[n - 2])
    yield gates.TOFFOLI(a[n - 1], b[n - 1], x)
    yield gates.X(b[n - 3])
    yield gates.CNOT(a[n - 4], a[n - 3])
    yield gates.TOFFOLI(x, b[n - 2], a[n - 2])
    for i in reversed(range(2, n - 2)):
        yield gates.X(b[i - 1])
        yield gates.CNOT(a[i - 2], a[i - 1])
        yield gates.TOFFOLI(a[i + 1], b[i], a[i])
    yield gates.TOFFOLI(a[2], b[1], a[1])
    for i in reversed(range(n - 3, -1, -1)):
        yield gates.CNOT(a[i + 1], b[i])
    yield gates.CNOT(x, b[n - 2])
    for i in reversed(range(n - 2, 0, -1)):
        yield gates.X(b[i])
    yield gates.TOFFOLI(a[2], b[1], a[1])
    for i in reversed(range(n - 3, 1, -1)):
        yield gates.CNOT(a[i - 2], a[i - 1])
        yield gates.TOFFOLI(a[i + 1], b[i], a[i])
    yield gates.CNOT(a[n - 4], a[n - 3])
    yield gates.TOFFOLI(x, b[n - 2], a[n - 2])
    yield gates.CNOT(a[n - 3], a[n - 2])
    yield gates.TOFFOLI(a[n - 1], b[n - 1], x)
    yield gates.CNOT(a[n - 2], x)
    for i in reversed(range(n - 2, -1, -1)):
        yield gates.CNOT(a[i], b[i])