Ejemplo n.º 1
0
def get_all_topology(params, n_qubits, static_entangler):
    """Builds an entangling layer according to the all-to-all topology.

    Args:
        n_qubits (int): number of qubits in the circuit.
        params (numpy.array): parameters of the circuit.
        static_entangler (str): gate specification for the entangling layer.

    Returns:
        Circuit: a zquantum.core.circuit.Circuit object
    """

    assert (params.shape[0] == int((n_qubits * (n_qubits - 1)) / 2))
    output = Circuit()
    qubits = [Qubit(qubit_index) for qubit_index in range(n_qubits)]
    output.qubits = qubits
    i = 0
    for qubit1_index in range(0, n_qubits - 1):
        for qubit2_index in range(qubit1_index + 1, n_qubits):
            output.gates.append(
                Gate(static_entangler,
                     [qubits[qubit1_index], qubits[qubit2_index]],
                     [params[i]]))
            i += 1
    return output
Ejemplo n.º 2
0
    def _generate_circuit(self,
                          params: Optional[np.ndarray] = None) -> Circuit:
        """Returns a parametrizable circuit represention of the ansatz.
        By convention the initial state is taken to be the |+..+> state and is
        evolved first under the cost Hamiltonian and then the mixer Hamiltonian.
        Args:
            params: parameters of the circuit.
        """
        if params is not None:
            Warning(
                "This method retuns a parametrizable circuit, params will be ignored."
            )
        circuit = Circuit()
        qubits = [
            Qubit(qubit_index) for qubit_index in range(self.number_of_qubits)
        ]
        circuit.qubits = qubits

        # Prepare initial state
        circuit += create_layer_of_gates(self.number_of_qubits, "H")

        # Add time evolution layers
        pyquil_cost_hamiltonian = qubitop_to_pyquilpauli(
            change_operator_type(self._cost_hamiltonian, QubitOperator))
        pyquil_mixer_hamiltonian = qubitop_to_pyquilpauli(
            self._mixer_hamiltonian)

        for i in range(self.number_of_layers):
            circuit += time_evolution(pyquil_cost_hamiltonian,
                                      sympy.Symbol(f"gamma_{i}"))
            circuit += time_evolution(pyquil_mixer_hamiltonian,
                                      sympy.Symbol(f"beta_{i}"))

        return circuit
Ejemplo n.º 3
0
    def test_optimization_level_of_transpiler(self):
        # Given
        noise_model, connectivity = get_qiskit_noise_model(
            "ibmqx2", api_token=os.getenv("ZAPATA_IBMQ_API_TOKEN")
        )
        simulator = QiskitSimulator(
            "qasm_simulator",
            n_samples=8192,
            noise_model=noise_model,
            device_connectivity=connectivity,
            optimization_level=0,
        )
        qubit_operator = QubitOperator("Z0")
        # Initialize in |1> state
        circuit = Circuit(Program(X(0)))
        # Flip qubit an even number of times to remain in the |1> state, but allow decoherence to take effect
        circuit += Circuit(Program([X(0) for _ in range(50)]))

        # When
        expectation_values_no_compilation = simulator.get_expectation_values(
            circuit, qubit_operator
        )

        simulator.optimization_level = 3
        expectation_values_full_compilation = simulator.get_expectation_values(
            circuit, qubit_operator
        )

        # Then
        assert (
            expectation_values_full_compilation.values[0]
            < expectation_values_no_compilation.values[0]
        )
Ejemplo n.º 4
0
def get_entangling_layer_line_topology(params: np.ndarray, n_qubits: int,
                                       entangling_gate: str) -> Circuit:
    """Builds a circuit representing an entangling layer according to the line topology.

    Args:
        params (numpy.array): parameters of the circuit.
        n_qubits (int): number of qubits in the circuit.
        entangling_gate (str): gate specification for the entangling layer.

    Returns:
        Circuit: a zquantum.core.circuit.Circuit object
    """
    assert params.shape[0] == n_qubits - 1

    circuit = Circuit()
    circuit.qubits = [Qubit(qubit_index) for qubit_index in range(n_qubits)]
    for qubit1_index in range(0, n_qubits - 1):
        circuit.gates.append(
            Gate(
                entangling_gate,
                [
                    circuit.qubits[qubit1_index],
                    circuit.qubits[qubit1_index + 1]
                ],
                [params[qubit1_index]],
            ))
    return circuit
Ejemplo n.º 5
0
    def test_ansatz_circuit_four_layers(self, number_of_qubits, topology):
        # Given
        number_of_layers = 4
        ansatz = QCBMAnsatz(
            number_of_layers=number_of_layers,
            number_of_qubits=number_of_qubits,
            topology=topology,
        )

        params = [
            np.ones(2 * number_of_qubits),
            np.ones(int((number_of_qubits * (number_of_qubits - 1)) / 2)),
            np.ones(3 * number_of_qubits),
            np.ones(int((number_of_qubits * (number_of_qubits - 1)) / 2)),
        ]

        expected_pycircuit = Program()
        for i in range(number_of_qubits):
            expected_pycircuit += Program(pyquil.gates.RX(params[0][i], i))
        for i in range(number_of_qubits):
            expected_pycircuit += Program(
                pyquil.gates.RZ(params[0][i + number_of_qubits], i)
            )
        expected_first_layer = Circuit(expected_pycircuit)
        expected_second_layer = get_entangling_layer(
            params[1], number_of_qubits, "XX", topology
        )
        expected_pycircuit = Program()
        for i in range(number_of_qubits):
            expected_pycircuit += Program(pyquil.gates.RX(params[2][i], i))
        for i in range(number_of_qubits):
            expected_pycircuit += Program(
                pyquil.gates.RZ(params[2][i + number_of_qubits], i)
            )
        for i in range(number_of_qubits):
            expected_pycircuit += Program(
                pyquil.gates.RX(params[2][i + 2 * number_of_qubits], i)
            )
        expected_third_layer = Circuit(expected_pycircuit)
        expected_fourth_layer = get_entangling_layer(
            params[3], number_of_qubits, "XX", topology
        )
        expected_circuit = (
            expected_first_layer
            + expected_second_layer
            + expected_third_layer
            + expected_fourth_layer
        )

        params = np.concatenate(params)

        # When
        circuit = ansatz.get_executable_circuit(params)

        # Then
        assert circuit == expected_circuit
Ejemplo n.º 6
0
 def target_unitary(self, beta, gamma, symbols_map):
     target_circuit = Circuit()
     target_circuit.gates = []
     target_circuit.gates.append(Gate("H", [Qubit(0)]))
     target_circuit.gates.append(Gate("H", [Qubit(1)]))
     target_circuit.gates.append(Gate("Rz", [Qubit(0)], [2.0 * gamma]))
     target_circuit.gates.append(Gate("Rz", [Qubit(1)], [2.0 * gamma]))
     target_circuit.gates.append(Gate("Rx", [Qubit(0)], [2.0 * beta]))
     target_circuit.gates.append(Gate("Rx", [Qubit(1)], [2.0 * beta]))
     return target_circuit.evaluate(symbols_map).to_unitary()
Ejemplo n.º 7
0
    def test_create_circuits_from_qubit_operator(self):
        # Initialize target
        qubits = [Qubit(i) for i in range(0, 2)]

        gate_Z0 = Gate("Z", [qubits[0]])
        gate_X1 = Gate("X", [qubits[1]])

        gate_Y0 = Gate("Y", [qubits[0]])
        gate_Z1 = Gate("Z", [qubits[1]])

        circuit1 = Circuit()
        circuit1.qubits = qubits
        circuit1.gates = [gate_Z0, gate_X1]

        circuit2 = Circuit()
        circuit2.qubits = qubits
        circuit2.gates = [gate_Y0, gate_Z1]

        target_circuits_list = [circuit1, circuit2]

        # Given
        qubit_op = QubitOperator("Z0 X1") + QubitOperator("Y0 Z1")

        # When
        pauli_circuits = create_circuits_from_qubit_operator(qubit_op)

        # Then
        self.assertEqual(pauli_circuits[0].gates, target_circuits_list[0].gates)
        self.assertEqual(pauli_circuits[1].gates, target_circuits_list[1].gates)
        self.assertEqual(
            str(pauli_circuits[0].qubits), str(target_circuits_list[0].qubits)
        )
        self.assertEqual(
            str(pauli_circuits[1].qubits), str(target_circuits_list[1].qubits)
        )
Ejemplo n.º 8
0
    def test_expectation_value_with_noisy_simulator(self, noisy_simulator):
        # Given
        # Initialize in |1> state
        circuit = Circuit(Program(X(0)))
        # Flip qubit an even number of times to remain in the |1> state, but allow decoherence to take effect
        circuit += Circuit(Program([X(0) for _ in range(10)]))
        qubit_operator = QubitOperator("Z0")
        noisy_simulator.n_samples = 8192
        # When
        expectation_values_10_gates = noisy_simulator.get_expectation_values(
            circuit, qubit_operator
        )
        # Then
        assert isinstance(expectation_values_10_gates, ExpectationValues)
        assert len(expectation_values_10_gates.values) == 1
        assert expectation_values_10_gates.values[0] > -1
        assert expectation_values_10_gates.values[0] < 0.0
        assert isinstance(noisy_simulator, QiskitSimulator)
        assert noisy_simulator.device_name == "qasm_simulator"
        assert noisy_simulator.n_samples == 8192
        assert isinstance(noisy_simulator.noise_model, AerNoise.NoiseModel)
        assert noisy_simulator.device_connectivity is not None
        assert noisy_simulator.basis_gates is not None

        # Given
        # Initialize in |1> state
        circuit = Circuit(Program(X(0)))
        # Flip qubit an even number of times to remain in the |1> state, but allow decoherence to take effect
        circuit += Circuit(Program([X(0) for _ in range(50)]))
        qubit_operator = QubitOperator("Z0")
        noisy_simulator.n_samples = 8192
        # When
        expectation_values_50_gates = noisy_simulator.get_expectation_values(
            circuit, qubit_operator
        )
        # Then
        assert isinstance(expectation_values_50_gates, ExpectationValues)
        assert len(expectation_values_50_gates.values) == 1
        assert expectation_values_50_gates.values[0] > -1
        assert expectation_values_50_gates.values[0] < 0.0
        assert (
            expectation_values_50_gates.values[0]
            > expectation_values_10_gates.values[0]
        )
        assert isinstance(noisy_simulator, QiskitSimulator)
        assert noisy_simulator.device_name == "qasm_simulator"
        assert noisy_simulator.n_samples == 8192
        assert isinstance(noisy_simulator.noise_model, AerNoise.NoiseModel)
        assert noisy_simulator.device_connectivity is not None
        assert noisy_simulator.basis_gates is not None
Ejemplo n.º 9
0
def build_qaoa_circuit(params, hamiltonians):
    """Generates a circuit for QAOA. This is not only for QAOA proposed by Farhi
    et al., but also general ansatz where alternating layers of time evolution under 
    two different Hamiltonians H1 and H2 are considered.

    Args:
        hamiltonians (list):
            A list of dict or zquantum.core.qubitoperator.QubitOperator objects representing Hamiltonians
            H1, H2, ..., Hk which forms one layer of the ansatz
                    exp(-i Hk tk) ... exp(-i H2 t2) exp(-i H1 t1)
            For example, in the case of QAOA proposed by Farhi et al, the list the list is then
            [H1, H2] where
                H1 is the Hamiltonian for which the ground state is sought, and
                H2 is the Hamiltonian for which the time evolution act as a diffuser 
                    in the search space.
        params (numpy.ndarray): 
            A list of sets of parameters. Each parameter in a set specifies the time
            duration of evolution under each of the Hamiltonians H1, H2, ... Hk.
            
    Returns:
        zquantum.core.circuit.Circuit: the ansatz circuit
    """

    if mod(len(params), len(hamiltonians)) != 0:
        raise Warning('There are {} input parameters and {} Hamiltonians. Since {} does not divide {} the last layer will be incomplete.'.\
            format(len(params), len(hamiltonians), len(params), len(hamiltonians)))

    # Convert qubit operators from dicts to QubitOperator objects, if needed
    for index, hamiltonian in enumerate(hamiltonians):
        if isinstance(hamiltonian, dict):
            hamiltonians[index] = convert_dict_to_qubitop(hamiltonian)

    output = Circuit()

    # Start with a layer of Hadarmard gates
    n_qubits = count_qubits(hamiltonians[0])
    qubits = [Qubit(qubit_index) for qubit_index in range(n_qubits)]
    output.qubits = qubits
    for qubit_index in range(n_qubits):
        output.gates.append(Gate('H', (qubits[qubit_index], )))

    # Add time evolution layers
    for i in range(params.shape[0]):
        hamiltonian_index = mod(i, len(hamiltonians))
        current_hamiltonian = qubitop_to_pyquilpauli(
            hamiltonians[hamiltonian_index])
        output += time_evolution(current_hamiltonian, params[i])

    return output
Ejemplo n.º 10
0
 def estimation_tasks(self):
     task_1 = EstimationTask(IsingOperator("Z0"),
                             circuit=Circuit(Program(X(0))),
                             number_of_shots=10)
     task_2 = EstimationTask(
         IsingOperator("Z0"),
         circuit=Circuit(Program(RZ(np.pi / 2, 0))),
         number_of_shots=20,
     )
     task_3 = EstimationTask(
         IsingOperator((), coefficient=2.0),
         circuit=Circuit(Program(RY(np.pi / 4, 0))),
         number_of_shots=30,
     )
     return [task_1, task_2, task_3]
Ejemplo n.º 11
0
def get_expectation_values_for_qubit_operator(
    backend_specs: Specs,
    circuit: Union[str, Circuit, Dict],
    qubit_operator: Union[str, SymbolicOperator, Dict],
):
    """Measure the expection values of the terms in an input operator with respect to the state prepared by the input
    circuit on the backend described by the backend_specs. The results are serialized into a JSON under the
    file: "expectation-values.json"

    ARGS:
        backend_specs (Union[dict, str]): The backend on which to run the quantum circuit
        circuit (Union[str, Circuit]): The circuit that prepares the state to be measured
        qubit_operator (Union[str, SymbolicOperator]): The operator to measure
    """
    if isinstance(circuit, str):
        circuit = load_circuit(circuit)
    elif isinstance(circuit, dict):
        circuit = Circuit.from_dict(circuit)
    if isinstance(qubit_operator, str):
        qubit_operator = load_qubit_operator(qubit_operator)
    elif isinstance(qubit_operator, dict):
        qubit_operator = convert_dict_to_qubitop(qubit_operator)
    if isinstance(backend_specs, str):
        backend_specs = json.loads(backend_specs)
    backend = create_object(backend_specs)

    expectation_values = backend.get_expectation_values(
        circuit, qubit_operator)
    save_expectation_values(expectation_values, "expectation-values.json")
Ejemplo n.º 12
0
def build_singlet_uccsd_circuit(parameters, n_mo, n_electrons, transformation):
    """Constructs the circuit for a singlet UCCSD ansatz with HF initial state.

    Args:
        parameters (numpy.ndarray): Vector of coupled-cluster amplitudes
        n_mo (int): number of molecular orbitals
        n_electrons (int): number of electrons

    Returns:
        qprogram (pyquil.quil.Program): a program for simulating the ansatz
    """
    qprogram = Program()

    # Set initial state with correct number of electrons
    for i in range(n_electrons):
        qubit_index = n_electrons-i-1
        qprogram += X(qubit_index)

    # Build UCCSD generator
    fermion_generator = uccsd_singlet_generator(parameters,
                                                2*n_mo,
                                                n_electrons,
                                                anti_hermitian=True)
    evolution_operator = exponentiate_fermion_operator(fermion_generator,
                                                       transformation)

    qprogram += evolution_operator
    return Circuit(qprogram)
Ejemplo n.º 13
0
    def test_group_greedily_all_different_groups(self):
        target_operator = 10.0 * QubitOperator("Z0")
        target_operator -= 3.0 * QubitOperator("Y0")
        target_operator += 1.0 * QubitOperator("X0")
        target_operator += 20.0 * QubitOperator("")

        expected_operators = [
            10.0 * QubitOperator("Z0"),
            -3.0 * QubitOperator("Y0"),
            1.0 * QubitOperator("X0"),
            20.0 * QubitOperator(""),
        ]

        circuit = Circuit(Program(X(0)))

        estimation_tasks = [EstimationTask(target_operator, circuit, None)]

        grouped_tasks = group_greedily(estimation_tasks)

        for task, operator in zip(grouped_tasks, expected_operators):
            assert task.operator == operator

        for initial_task, modified_task in zip(estimation_tasks,
                                               grouped_tasks):
            assert modified_task.circuit == initial_task.circuit
            assert modified_task.number_of_shots == initial_task.number_of_shots
def main(backend_specs):
    # Define registers and circuit
    q = QuantumRegister(2)
    c = ClassicalRegister(2)
    circuit = QuantumCircuit(q, c)

    # Quantum circuit starts here
    circuit.h(q[0])
    circuit.cnot(q[0], q[1])
    # Note we have to remove the Measurement to convert to Zapata's circuit format
    # End quantum circuit

    # After this point we use the power of Orquestra to use different backends!
    # Use Zapata's representation of quantum circuits
    zap_circuit = Circuit(circuit)

    # Build a backend from the specs we passed to the step
    if isinstance(backend_specs, str):
        backend_specs_dict = yaml.load(backend_specs, Loader=yaml.SafeLoader)
    else:
        backend_specs_dict = backend_specs
    backend = create_object(backend_specs_dict)

    # We can use this backend to get the bitstring distribution
    distribution = backend.get_bitstring_distribution(zap_circuit)

    # Finally, we can save the output!
    save_bitstring_distribution(distribution, "output-distribution.json")
Ejemplo n.º 15
0
def concatenate_circuits(circuit_set: Union[str, List[Circuit]]):
    if isinstance(circuit_set, str):
        circuit_set = load_circuit_set(circuit_set)
    result_circuit = Circuit()
    for circuit in circuit_set:
        result_circuit += circuit
    save_circuit(result_circuit, "result-circuit.json")
Ejemplo n.º 16
0
    def test_group_individually(self):
        target_operator = 10.0 * QubitOperator("Z0")
        target_operator += 5.0 * QubitOperator("Z1")
        target_operator -= 3.0 * QubitOperator("Y0")
        target_operator += 1.0 * QubitOperator("X0")
        target_operator += 20.0 * QubitOperator("")

        expected_operator_terms_per_frame = [
            (10.0 * QubitOperator("Z0")).terms,
            (5.0 * QubitOperator("Z1")).terms,
            (-3.0 * QubitOperator("Y0")).terms,
            (1.0 * QubitOperator("X0")).terms,
            (20.0 * QubitOperator("")).terms,
        ]

        circuit = Circuit(Program(X(0)))

        estimation_tasks = [EstimationTask(target_operator, circuit, None)]

        grouped_tasks = group_individually(estimation_tasks)

        assert len(grouped_tasks) == 5

        for task in grouped_tasks:
            assert task.operator.terms in expected_operator_terms_per_frame
Ejemplo n.º 17
0
 def test_get_exact_expectation_values_empty_op(self):
     # Given
     circuit = Circuit(Program(H(0), CNOT(0, 1), CNOT(1, 2)))
     qubit_operator = QubitOperator()
     # When
     expectation_values = self.wf_simulator.get_exact_expectation_values(
         circuit, qubit_operator)
     # Then
     self.assertAlmostEqual(sum(expectation_values.values), 0.0)
Ejemplo n.º 18
0
def get_single_qubit_layer(n_qubits, params, single_qubit_gate):
    """Builds a layer of single-qubit gates acting on all qubits in a quantum circuit.

    Args:
        n_qubits (int): number of qubits in the circuit.
        params (numpy.array): parameters of the single-qubit gates.
        single_qubit_gate (str): the gate to be applied to each qubit.

    Returns:
        Circuit: a zquantum.core.circuit.Circuit object
    """

    output = Circuit()
    qubits = [Qubit(qubit_index) for qubit_index in range(n_qubits)]
    output.qubits = qubits
    for qi in range(n_qubits):
        output.gates.append(Gate(single_qubit_gate, [qubits[qi]], [params[qi]]))
    return output
Ejemplo n.º 19
0
    def test_create_layer_of_gates_not_parametrized(self):
        # Given
        number_of_qubits = 4
        gate_name = "X"
        qubits = [Qubit(i) for i in range(0, number_of_qubits)]
        gate_0 = Gate(gate_name, qubits=[qubits[0]])
        gate_1 = Gate(gate_name, qubits=[qubits[1]])
        gate_2 = Gate(gate_name, qubits=[qubits[2]])
        gate_3 = Gate(gate_name, qubits=[qubits[3]])
        target_circuit = Circuit()
        target_circuit.qubits = qubits
        target_circuit.gates = [gate_0, gate_1, gate_2, gate_3]

        # When
        layer_of_x = create_layer_of_gates(number_of_qubits, gate_name)

        # Then
        self.assertEqual(layer_of_x, target_circuit)
Ejemplo n.º 20
0
 def test_run_circuit_and_measure(self):
     for simulator in self.all_simulators:
         # Given
         circuit = Circuit(Program(H(0), CNOT(0, 1), CNOT(1, 2)))
         # When
         simulator.n_samples = 100
         measurements = simulator.run_circuit_and_measure(circuit)
         # Then
         self.assertEqual(len(measurements), 100)
         self.assertEqual(len(measurements[0]), 3)
Ejemplo n.º 21
0
 def test_get_expectation_values(self):
     # Given
     circuit = Circuit(Program(H(0), CNOT(0, 1), CNOT(1, 2)))
     qubit_operator = IsingOperator('[] + [Z0 Z1] + [Z0 Z2] ')
     target_expectation_values = np.array([1, 1, 1])
     # When
     expectation_values = self.sampling_simulator.get_expectation_values(
         circuit, qubit_operator)
     # Then
     np.testing.assert_array_equal(expectation_values.values,
                                   target_expectation_values)
Ejemplo n.º 22
0
def build_qcbm_circuit_ion_trap(
    n_qubits, input_params, single_qubit_gate, static_entangler, topology="all"
):
    """Builds a qcbm ansatz circuit, using the ansatz in https://advances.sciencemag.org/content/5/10/eaaw9918/tab-pdf (Fig.2 - top).

    Args:
        n_qubits (int): number of qubits initialized for circuit.
        input_params (numpy.array): input parameters of the circuit (1d array).
        single_qubit_gate(str): Gate specification for the single-qubit layer (L0).
        static_entangler(str): Gate specification for the entangling layers (L1, L2, ... , Ln).
        topology (str): describes topology of qubits connectivity.

    Returns:
        Circuit: the qcbm circuit
    """
    assert n_qubits > 1
    n_params_layer_zero = 2 * n_qubits
    params_layer_zero = np.take(input_params, list(range(2 * n_qubits)))
    assert params_layer_zero.shape[0] == n_params_layer_zero
    assert params_layer_zero.ndim == 1

    n_params_per_layer = int((n_qubits * (n_qubits - 1) / 2))

    if (input_params.shape[0] - 2 * n_qubits) % n_params_per_layer == 0:
        n_layers = int((input_params.shape[0] - 2 * n_qubits) / n_params_per_layer)
    else:
        raise RuntimeError("incomplete layers are not supported yet.")
    assert n_layers > 0

    params_from_input = np.take(
        input_params, list(range(2 * n_qubits, input_params.shape[0]))
    )
    params = np.reshape(params_from_input, (n_layers, n_params_per_layer))
    assert params.shape[1] == n_params_per_layer

    assert single_qubit_gate in ["Rx"]
    assert static_entangler in ["XX"]
    assert topology in ["all"]

    # init circuit
    circuit = Circuit()
    circuit += get_single_qubit_layer(
        n_qubits, params_layer_zero[0:n_qubits], single_qubit_gate
    )
    circuit += get_single_qubit_layer(n_qubits, params_layer_zero[n_qubits:], "Rz")

    counter = 0
    for n in range(n_layers):
        circuit += get_entangling_layer(
            n_qubits, params[counter], static_entangler, single_qubit_gate, topology
        )
        counter += 1

    return circuit
Ejemplo n.º 23
0
def create_target_unitary(thetas, number_of_layers):
    target_circuit = Circuit()
    target_circuit.gates = []
    target_circuit.gates.append(Gate("Ry", [Qubit(0)], [thetas[0]]))
    target_circuit.gates.append(Gate("Ry", [Qubit(1)], [thetas[1]]))
    betas = create_betas(number_of_layers)
    gammas = create_gammas(number_of_layers)
    symbols_map = create_symbols_map(number_of_layers)
    for layer_id in range(number_of_layers):
        beta = betas[layer_id]
        gamma = gammas[layer_id]
        target_circuit.gates.append(Gate("Rz", [Qubit(0)], [2.0 * gamma]))
        target_circuit.gates.append(Gate("Rz", [Qubit(1)], [2.0 * gamma]))
        target_circuit.gates.append(Gate("Ry", [Qubit(0)], [-thetas[0]]))
        target_circuit.gates.append(Gate("Ry", [Qubit(1)], [-thetas[1]]))
        target_circuit.gates.append(Gate("Rz", [Qubit(0)], [-2.0 * beta]))
        target_circuit.gates.append(Gate("Rz", [Qubit(1)], [-2.0 * beta]))
        target_circuit.gates.append(Gate("Ry", [Qubit(0)], [thetas[0]]))
        target_circuit.gates.append(Gate("Ry", [Qubit(1)], [thetas[1]]))

    return target_circuit.evaluate(symbols_map).to_unitary()
Ejemplo n.º 24
0
    def _generate_circuit(self,
                          params: Optional[np.ndarray] = None) -> Circuit:
        """Returns a parametrizable circuit represention of the ansatz.
        Args:
            params: parameters of the circuit.
        """
        if params is not None:
            Warning(
                "This method retuns a parametrizable circuit, params will be ignored."
            )
        circuit = Circuit()
        qubits = [
            Qubit(qubit_index) for qubit_index in range(self.number_of_qubits)
        ]
        circuit.qubits = qubits

        # Prepare initial state
        circuit += create_layer_of_gates(self.number_of_qubits, "Ry",
                                         self._thetas)

        pyquil_cost_hamiltonian = qubitop_to_pyquilpauli(
            change_operator_type(self._cost_hamiltonian, QubitOperator))

        # Add time evolution layers
        for i in range(self.number_of_layers):
            circuit += time_evolution(pyquil_cost_hamiltonian,
                                      sympy.Symbol(f"gamma_{i}"))
            circuit += create_layer_of_gates(self.number_of_qubits, "Ry",
                                             -self._thetas)
            circuit += create_layer_of_gates(
                self.number_of_qubits,
                "Rz",
                [-2 * sympy.Symbol(f"beta_{i}")] * self.number_of_qubits,
            )
            circuit += create_layer_of_gates(self.number_of_qubits, "Ry",
                                             self._thetas)

        return circuit
Ejemplo n.º 25
0
    def test_perform_context_selection(self):
        target_operators = []
        target_operators.append(10.0 * QubitOperator("Z0"))
        target_operators.append(-3 * QubitOperator("Y0"))
        target_operators.append(1 * QubitOperator("X0"))
        target_operators.append(20 * QubitOperator(""))

        expected_operators = []
        expected_operators.append(10.0 * QubitOperator("Z0"))
        expected_operators.append(-3 * QubitOperator("Z0"))
        expected_operators.append(1 * QubitOperator("Z0"))
        expected_operators.append(20 * QubitOperator(""))

        base_circuit = Circuit(Program(X(0)))
        x_term_circuit = Circuit(Program(RX(np.pi / 2, 0)))
        y_term_circuit = Circuit(Program(RY(-np.pi / 2, 0)))

        expected_circuits = [
            base_circuit,
            base_circuit + x_term_circuit,
            base_circuit + y_term_circuit,
            base_circuit,
        ]

        estimation_tasks = [
            EstimationTask(operator, base_circuit, None)
            for operator in target_operators
        ]

        tasks_with_context_selection = perform_context_selection(
            estimation_tasks)

        for task, expected_circuit, expected_operator in zip(
                tasks_with_context_selection, expected_circuits,
                expected_operators):
            assert task.operator.terms == expected_operator.terms
            assert task.circuit == expected_circuit
Ejemplo n.º 26
0
def get_single_qubit_layer(params, n_qubits, single_qubit_gates):
    """Builds a layer of single-qubit gates acting on all qubits in a quantum circuit.

    Args:
        n_qubits (int): number of qubits in the circuit.
        params (numpy.array): parameters of the single-qubit gates.
        single_qubit_gates (str): a list of single qubit gates to be applied to each qubit.

    Returns:
        Circuit: a zquantum.core.circuit.Circuit object
    """
    assert (len(params) == len(single_qubit_gates) * n_qubits)
    output = Circuit()
    qubits = [Qubit(qubit_index) for qubit_index in range(n_qubits)]
    output.qubits = qubits
    parameter_index = 0
    for gate in single_qubit_gates:
        for qubit_index in range(n_qubits):
            # Add single_qubit_gate to each qubit
            output.gates.append(
                Gate(gate, [qubits[qubit_index]], [params[parameter_index]]))
            parameter_index += 1

    return output
Ejemplo n.º 27
0
    def test_run_circuitset_and_measure(self, sampling_simulator):
        # Given
        circuit = Circuit(Program(X(0), CNOT(1, 2)))
        # When
        sampling_simulator.n_samples = 100
        measurements_set = sampling_simulator.run_circuitset_and_measure([circuit])
        # Then
        assert len(measurements_set) == 1
        for measurements in measurements_set:
            assert len(measurements.bitstrings) == 100
            assert all(bitstring == (1, 0, 0) for bitstring in measurements.bitstrings)

        # Given
        circuit = Circuit(Program(X(0), CNOT(1, 2)))
        # When
        sampling_simulator.n_samples = 100
        measurements_set = sampling_simulator.run_circuitset_and_measure(
            [circuit] * 100
        )
        # Then
        assert len(measurements_set) == 100
        for measurements in measurements_set:
            assert len(measurements.bitstrings) == 100
            assert all(bitstring == (1, 0, 0) for bitstring in measurements.bitstrings)
Ejemplo n.º 28
0
 def test_get_bitstring_distribution(self):
     for simulator in self.all_simulators:
         # Given
         circuit = Circuit(Program(H(0), CNOT(0, 1), CNOT(1, 2)))
         # When
         bitstring_distribution = simulator.get_bitstring_distribution(
             circuit)
         # Then
         self.assertEqual(type(bitstring_distribution),
                          BitstringDistribution)
         self.assertEqual(bitstring_distribution.get_qubits_number(), 3)
         self.assertGreater(bitstring_distribution.distribution_dict["000"],
                            1 / 3)
         self.assertGreater(bitstring_distribution.distribution_dict["111"],
                            1 / 3)
Ejemplo n.º 29
0
    def test_concatenate_circuits_python_objects(self, circuit_set):
        # Given
        expected_concatenated_circuit_filename = "result-circuit.json"
        expected_concatenated_circuit = Circuit()
        for circuit in copy.deepcopy(circuit_set):
            expected_concatenated_circuit += circuit

        # When
        concatenate_circuits(circuit_set)

        # Then
        try:
            concatenated_circuit = load_circuit(expected_concatenated_circuit_filename)
            assert concatenated_circuit.gates == expected_concatenated_circuit.gates
        finally:
            remove_file_if_exists(expected_concatenated_circuit_filename)
Ejemplo n.º 30
0
    def test_readout_correction_works_run_circuitset_and_measure(self):
        # Given
        ibmq_api_token = os.getenv("ZAPATA_IBMQ_API_TOKEN")
        backend = QiskitBackend(
            device_name="ibmq_qasm_simulator",
            n_samples=1000,
            api_token=ibmq_api_token,
            readout_correction=True,
        )
        circuit = Circuit(Program(X(0), CNOT(1, 2)))

        # When
        backend.run_circuitset_and_measure([circuit] * 10)

        # Then
        assert backend.readout_correction
        assert backend.readout_correction_filter is not None