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
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
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] )
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
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
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()
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) )
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
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
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]
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")
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)
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")
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")
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
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)
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
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)
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)
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)
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
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()
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
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
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
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)
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)
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)
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