def test_circuit_generation(self): """Test creating a series of circuits parametrically""" theta = Parameter('θ') qr = QuantumRegister(1) qc = QuantumCircuit(qr) qc.rx(theta, qr) backend = BasicAer.get_backend('qasm_simulator') qc_aer = transpile(qc, backend) # generate list of circuits for assign_fun in ['bind_parameters', 'assign_parameters']: with self.subTest(assign_fun=assign_fun): circs = [] theta_list = numpy.linspace(0, numpy.pi, 20) for theta_i in theta_list: circs.append(getattr(qc_aer, assign_fun)({theta: theta_i})) qobj = assemble(circs) for index, theta_i in enumerate(theta_list): self.assertEqual(float(qobj.experiments[index].instructions[0].params[0]), theta_i)
def test_schedule_block_in_instmap(self): """Test schedule block in instmap can be scheduled.""" duration = Parameter("duration") with build() as pulse_prog: play(Gaussian(duration, 0.1, 10), DriveChannel(0)) instmap = InstructionScheduleMap() instmap.add("block_gate", (0,), pulse_prog, ["duration"]) qc = QuantumCircuit(1) qc.append(Gate("block_gate", 1, [duration]), [0]) qc.assign_parameters({duration: 100}, inplace=True) sched = schedule(qc, self.backend, inst_map=instmap) ref_sched = Schedule() ref_sched += Play(Gaussian(100, 0.1, 10), DriveChannel(0)) self.assertEqual(sched, ref_sched)
def test_single_parameterized_circuit(self, basis): """Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter('theta') qc.p(0.3, qr) qc.p(0.4, qr) qc.p(theta, qr) qc.p(0.1, qr) qc.p(0.2, qr) passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(qc) self.assertTrue( Operator(qc.bind_parameters({theta: 3.14})).equiv( Operator(result.bind_parameters({theta: 3.14}))))
def test_matrix_op_parameterized_evolution(self): """ parameterized MatrixOp evolution test """ # pylint: disable=no-member theta = Parameter('θ') op = (-1.052373245772859 * I ^ I) + \ (0.39793742484318045 * I ^ Z) + \ (0.18093119978423156 * X ^ X) + \ (-0.39793742484318045 * Z ^ I) + \ (-0.01128010425623538 * Z ^ Z) op = op * theta wf = (op.to_matrix_op().exp_i()) @ CX @ (H ^ I) @ Zero self.assertIn(theta, wf.to_circuit().parameters) op = op.assign_parameters({theta: 1}) exp_mat = op.to_matrix_op().exp_i().to_matrix() ref_mat = scipy.linalg.expm(-1j * op.to_matrix()) np.testing.assert_array_almost_equal(ref_mat, exp_mat) wf = wf.assign_parameters({theta: 3}) self.assertNotIn(theta, wf.to_circuit().parameters)
def disassemble_value( value_expr: Union[float, str]) -> Union[float, ParameterExpression]: """A helper function to format instruction operand. If parameter in string representation is specified, this method parses the input string and generates Qiskit ParameterExpression object. Args: value_expr: Operand value in Qobj. Returns: Parsed operand value. ParameterExpression object is returned if value is not number. """ if isinstance(value_expr, str): str_expr = parse_string_expr(value_expr, partial_binding=False) value_expr = str_expr( **{pname: Parameter(pname) for pname in str_expr.params}) return value_expr
def test_parameter_expression_circuit_for_device(self): """Verify that a circuit including expressions of parameters can be transpiled for a device backend.""" qr = QuantumRegister(2, name='qr') qc = QuantumCircuit(qr) theta = Parameter('theta') square = theta * theta qc.rz(square, qr[0]) transpiled_qc = transpile( qc, backend=FakeMelbourne(), initial_layout=Layout.generate_trivial_layout(qr)) qr = QuantumRegister(14, 'q') expected_qc = QuantumCircuit(qr) expected_qc.u1(square, qr[0]) self.assertEqual(expected_qc, transpiled_qc)
def test_single_parameter_binds(self): """Test passing parameter binds as a dictionary to the circuit sampler.""" try: from qiskit.providers.aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return x = Parameter('x') circuit = QuantumCircuit(1) circuit.ry(x, 0) expr = ~StateFn(H) @ StateFn(circuit) sampler = CircuitSampler(Aer.get_backend('statevector_simulator')) res = sampler.convert(expr, params={x: 0}).eval() self.assertIsInstance(res, complex)
def test_parameterized_calibrations_transpile(self): """Check that gates can be matched to their calibrations before and after parameter assignment.""" tau = Parameter('tau') circ = QuantumCircuit(3, 3) circ.append(Gate('rxt', 1, [2 * 3.14 * tau]), [0]) def q0_rxt(tau): with pulse.build() as q0_rxt: pulse.play(pulse.library.Gaussian(20, 0.4 * tau, 3.0), pulse.DriveChannel(0)) return q0_rxt circ.add_calibration('rxt', [0], q0_rxt(tau), [2 * 3.14 * tau]) transpiled_circ = transpile(circ, FakeAlmaden()) self.assertEqual(set(transpiled_circ.count_ops().keys()), {'rxt'}) circ = circ.assign_parameters({tau: 1}) transpiled_circ = transpile(circ, FakeAlmaden()) self.assertEqual(set(transpiled_circ.count_ops().keys()), {'rxt'})
def test_assign_parameter_to_subroutine(self): """Test that assign parameter objects to subroutines.""" param1 = Parameter("amp") waveform = pulse.library.Constant(duration=100, amp=param1) program_layer0 = pulse.Schedule() program_layer0 += pulse.Play(waveform, DriveChannel(0)) reference = deepcopy(program_layer0).assign_parameters({param1: 0.1}) # to call instruction program_layer1 = pulse.Schedule() program_layer1 += pulse.instructions.Call(program_layer0) target = deepcopy(program_layer1).assign_parameters({param1: 0.1}) self.assertEqual(inline_subroutines(target), reference) # to nested call instruction program_layer2 = pulse.Schedule() program_layer2 += pulse.instructions.Call(program_layer1) target = deepcopy(program_layer2).assign_parameters({param1: 0.1}) self.assertEqual(inline_subroutines(target), reference)
def test_qaoa_qc_mixer_many_parameters(self): """ QAOA test with a mixer as a parameterized circuit with the num of parameters > 1. """ optimizer = COBYLA() qubit_op, _ = self._get_operator(W1) num_qubits = qubit_op.num_qubits mixer = QuantumCircuit(num_qubits) for i in range(num_qubits): theta = Parameter('θ' + str(i)) mixer.rx(theta, range(num_qubits)) qaoa = QAOA(optimizer, reps=2, mixer=mixer, quantum_instance=self.statevector_simulator) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) self.log.debug(x) graph_solution = self._get_graph_solution(x) self.assertIn(graph_solution, S1)
def test_differentiable_param_is_array(self, analytic, tol): """Test that extracting the differentiable parameters works correctly for arrays""" qc = QuantumCircuit(3) qiskit_params = [Parameter("param_{}".format(i)) for i in range(3)] theta = 0.53 phi = -1.23 varphi = 0.8654 params = [ qml.numpy.tensor(theta), qml.numpy.tensor(phi), qml.numpy.tensor(varphi) ] qc.rx(qiskit_params[0], 0) qc.rx(qiskit_params[1], 1) qc.rx(qiskit_params[2], 2) qc.cx(0, 1) qc.cx(1, 2) # convert to a PennyLane circuit qc_pl = qml.from_qiskit(qc) dev = qml.device("default.qubit", wires=3, analytic=analytic) @qml.qnode(dev) def circuit(params): qiskit_param_mapping = dict(map(list, zip(qiskit_params, params))) qc_pl(qiskit_param_mapping) return qml.expval(qml.PauliX(0) @ qml.PauliY(2)) dcircuit = qml.grad(circuit, 0) res = dcircuit(params) expected = [ np.cos(theta) * np.sin(phi) * np.sin(varphi), np.sin(theta) * np.cos(phi) * np.sin(varphi), np.sin(theta) * np.sin(phi) * np.cos(varphi) ] assert np.allclose(res, expected, **tol)
def test_composed_op(self): """Tests OpflowQNN with ComposedOp as an operator.""" qc = QuantumCircuit(1) param = Parameter("param") qc.rz(param, 0) h_1 = PauliSumOp.from_list([("Z", 1.0)]) h_2 = PauliSumOp.from_list([("Z", 1.0)]) h_op = ListOp([h_1, h_2]) op = ~StateFn(h_op) @ StateFn(qc) # initialize QNN qnn = OpflowQNN(op, [], [param]) # create random data and weights for testing input_data = np.random.rand(2, qnn.num_inputs) weights = np.random.rand(qnn.num_weights) qnn.forward(input_data, weights) qnn.backward(input_data, weights)
def test_single_parameterized_circuit(self): """Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter("theta") qc.append(U1Gate(0.3), [qr]) qc.append(U1Gate(0.4), [qr]) qc.append(U1Gate(theta), [qr]) qc.append(U1Gate(0.1), [qr]) qc.append(U1Gate(0.2), [qr]) dag = circuit_to_dag(qc) expected = QuantumCircuit(qr) expected.append(U1Gate(0.7), [qr]) expected.append(U1Gate(theta), [qr]) expected.append(U1Gate(0.3), [qr]) after = Optimize1qGates().run(dag) self.assertEqual(circuit_to_dag(expected), after)
def create_circuit(self, shots, angle_degrees= 90): ''' Creates a parameterized circuit with one tunable parameter with angle_degrees. Parameters: ----------- shots : The total number of shots for which the quantum experiment will run angle_degrees : The angle in degrees, that the parameterized gate will be rotated by ''' self.angle_degrees = angle_degrees self.parameter = Parameter('param1') self.qc = QuantumCircuit(2, 2) state1 = [1,0] state2 = [1,0] self.qc.initialize(state1, 0) #initializing qubit 0 to state 0 self.qc.initialize(state2, 1) #initialing qubit 1 to state 1 self.qc.ry(self.parameter, 0) self.qc.barrier() self.qc.cx(0, 1) self.qc.barrier()
def test_gradient_rzx(self, method): """Test the state gradient for ZX rotation""" ham = Z ^ Z a = Parameter("a") q = QuantumRegister(2) qc = QuantumCircuit(q) qc.h(q) qc.rzx(a, q[0], q[1]) op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.0) params = [a] state_grad = Gradient(grad_method=method).convert(operator=op, params=params) values_dict = [{a: np.pi / 8}, {a: np.pi / 2}] correct_values = [[0.0], [0.0]] for i, value_dict in enumerate(values_dict): np.testing.assert_array_almost_equal( state_grad.assign_parameters(value_dict).eval(), correct_values[i], decimal=1)
def test_gradient_ryy(self, method): # pylint: disable=wrong-spelling-in-comment """Test the state gradient for YY rotation """ ham = Y ^ Y a = Parameter('a') q = QuantumRegister(2) qc = QuantumCircuit(q) qc.ryy(a, q[0], q[1]) op = ~StateFn(ham) @ CircuitStateFn(primitive=qc, coeff=1.) state_grad = Gradient(grad_method=method).convert(operator=op, params=a) values_dict = [{a: np.pi / 8}, {a: np.pi}] correct_values = [[0], [0]] for i, value_dict in enumerate(values_dict): np.testing.assert_array_almost_equal( state_grad.assign_parameters(value_dict).eval(), correct_values[i], decimal=1)
def test_transpiling_multiple_parameterized_circuits(self): """Verify several parameterized circuits can be transpiled at once.""" # ref: https://github.com/Qiskit/qiskit-terra/issues/2864 qr = QuantumRegister(1) qc1 = QuantumCircuit(qr) qc2 = QuantumCircuit(qr) theta = Parameter('theta') qc1.u3(theta, 0, 0, qr[0]) qc2.u3(theta, 3.14, 0, qr[0]) circuits = [qc1, qc2] job = execute(circuits, BasicAer.get_backend('unitary_simulator'), shots=512, parameter_binds=[{theta: 1}]) self.assertTrue(len(job.result().results), 2)
def create_mixer(self, initial_variables: List[float]) -> QuantumCircuit: """ Creates an evolved mixer circuit as Ry(theta)Rz(-2beta)Ry(-theta). Args: initial_variables: Already created initial variables. Returns: A quantum circuit to be used as a mixer in QAOA. """ circuit = QuantumCircuit(len(initial_variables)) beta = Parameter("beta") for index, relaxed_value in enumerate(initial_variables): theta = 2 * np.arcsin(np.sqrt(relaxed_value)) circuit.ry(-theta, index) circuit.rz(-2.0 * beta, index) circuit.ry(theta, index) return circuit
def test_single_parameterized_circuit(self): """Parameters should be treated as opaque gates.""" qr = QuantumRegister(1) qc = QuantumCircuit(qr) theta = Parameter('theta') qc.u1(0.3, qr) qc.u1(0.4, qr) qc.u1(theta, qr) qc.u1(0.1, qr) qc.u1(0.2, qr) dag = circuit_to_dag(qc) expected = QuantumCircuit(qr) expected.u1(0.7, qr) expected.u1(theta, qr) expected.u1(0.3, qr) after = Optimize1qGates().run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_run_path_multiple_circuits(self): """Test parameterized circuit path via backed.run()""" shots = 1000 backend = AerSimulator() circuit = QuantumCircuit(2) theta = Parameter('theta') circuit.rx(theta, 0) circuit.cx(0, 1) circuit.measure_all() parameter_binds = [{theta: [0, pi, 2 * pi]}] * 3 res = backend.run([circuit] * 3, shots=shots, parameter_binds=parameter_binds).result() counts = res.get_counts() self.assertEqual(counts, [{ '00': shots }, { '11': shots }, { '00': shots }] * 3)
def test_3q_hamiltonian(self): """test 3 qubit hamiltonian on non-consecutive bits""" qr = QuantumRegister(4) qc = QuantumCircuit(qr) qc.x(qr[0]) matrix = Operator.from_label('XZY') theta = Parameter('theta') uni3q = HamiltonianGate(matrix, theta) qc.append(uni3q, [qr[0], qr[1], qr[3]]) qc.cx(qr[3], qr[2]) # test of text drawer self.log.info(qc) qc = qc.bind_parameters({theta: -np.pi / 2}) dag = circuit_to_dag(qc) nodes = dag.multi_qubit_ops() self.assertEqual(len(nodes), 1) dnode = nodes[0] self.assertIsInstance(dnode.op, HamiltonianGate) for qubit in dnode.qargs: self.assertIn(qubit.index, [0, 1, 3]) np.testing.assert_almost_equal(dnode.op.to_matrix(), 1j * matrix.data)
def test_passing_parameter_into_qnode(self, qubit_device_2_wires): """Tests passing a circuit parameter into the QNode.""" theta = Parameter('θ') rotation_angle = 0.5 qc = QuantumCircuit(2) qc.rz(theta, [0]) @qml.qnode(qubit_device_2_wires) def circuit_loaded_qiskit_circuit(angle): load(qc)({theta: angle}) return qml.expval(qml.PauliZ(0)) @qml.qnode(qubit_device_2_wires) def circuit_native_pennylane(angle): qml.RZ(angle, wires=0) return qml.expval(qml.PauliZ(0)) assert circuit_loaded_qiskit_circuit(rotation_angle) == \ circuit_native_pennylane(rotation_angle)
def test_load_circuit_inside_of_qnode(self, qubit_device_2_wires): """Tests loading a QuantumCircuit inside of the QNode circuit definition.""" theta = Parameter("θ") angle = 0.5 qc = QuantumCircuit(2) qc.rz(theta, [0]) @qml.qnode(qubit_device_2_wires) def circuit_loaded_qiskit_circuit(): load(qc)({theta: angle}) return qml.expval(qml.PauliZ(0)) @qml.qnode(qubit_device_2_wires) def circuit_native_pennylane(): qml.RZ(angle, wires=0) return qml.expval(qml.PauliZ(0)) assert circuit_loaded_qiskit_circuit() == circuit_native_pennylane()
def test_qaoa_qc_mixer(self, w, prob, solutions, convert_to_matrix_op): """ QAOA test with a mixer as a parameterized circuit""" self.log.debug('Testing %s-step QAOA with MaxCut on graph with ' 'a mixer as a parameterized circuit\n%s', prob, w) optimizer = COBYLA() qubit_op, _ = self._get_operator(w) if convert_to_matrix_op: qubit_op = qubit_op.to_matrix_op() num_qubits = qubit_op.num_qubits mixer = QuantumCircuit(num_qubits) theta = Parameter('θ') mixer.rx(theta, range(num_qubits)) qaoa = QAOA(optimizer, prob, mixer=mixer, quantum_instance=self.statevector_simulator) result = qaoa.compute_minimum_eigenvalue(operator=qubit_op) x = self._sample_most_likely(result.eigenstate) graph_solution = self._get_graph_solution(x) self.assertIn(graph_solution, solutions)
def test_ef_rabi_circuit(self): """Test the EFRabi experiment end to end.""" anharm = -330e6 with pulse.build() as sched: pulse.shift_frequency(anharm, pulse.DriveChannel(2)) pulse.play(pulse.Gaussian(160, Parameter("amp"), 40), pulse.DriveChannel(2)) pulse.shift_frequency(-anharm, pulse.DriveChannel(2)) rabi12 = EFRabi(2, sched) rabi12.set_experiment_options(amplitudes=[0.5]) circ = rabi12.circuits()[0] with pulse.build() as expected: pulse.shift_frequency(anharm, pulse.DriveChannel(2)) pulse.play(pulse.Gaussian(160, 0.5, 40), pulse.DriveChannel(2)) pulse.shift_frequency(-anharm, pulse.DriveChannel(2)) self.assertEqual(circ.calibrations["Rabi"][((2, ), (0.5, ))], expected) self.assertEqual(circ.data[0][0].name, "x") self.assertEqual(circ.data[1][0].name, "Rabi")
def test_binding_across_broadcast_instruction(self): """Bind a parameter which was included via a broadcast instruction.""" # ref: https://github.com/Qiskit/qiskit-terra/issues/3008 from qiskit.circuit.library.standard_gates.rz import RZGate theta = Parameter('θ') n = 5 qc = QuantumCircuit(n, 1) qc.h(0) for i in range(n - 1): qc.cx(i, i + 1) qc.barrier() qc.rz(theta, range(n)) qc.barrier() for i in reversed(range(n - 1)): qc.cx(i, i + 1) qc.h(0) qc.measure(0, 0) theta_range = numpy.linspace(0, 2 * numpy.pi, 128) circuits = [ qc.assign_parameters({theta: theta_val}) for theta_val in theta_range ] self.assertEqual(len(circuits), len(theta_range)) for theta_val, bound_circ in zip(theta_range, circuits): rz_gates = [ inst for inst, qargs, cargs in bound_circ.data if isinstance(inst, RZGate) ] self.assertEqual(len(rz_gates), n) self.assertTrue( all(float(gate.params[0]) == theta_val for gate in rz_gates))
def test_single_circuit_calibrations(self): """Test that disassembler parses single circuit QOBJ calibrations (from QOBJ-level).""" theta = Parameter("theta") qc = QuantumCircuit(2) qc.h(0) qc.rx(np.pi, 0) qc.rx(theta, 1) qc = qc.assign_parameters({theta: np.pi}) with pulse.build() as h_sched: pulse.play(pulse.library.Drag(1, 0.15, 4, 2), pulse.DriveChannel(0)) with pulse.build() as x180: pulse.play(pulse.library.Gaussian(1, 0.2, 5), pulse.DriveChannel(0)) qc.add_calibration("h", [0], h_sched) qc.add_calibration(RXGate(np.pi), [0], x180) qobj = assemble(qc, FakeOpenPulse2Q()) output_circuits, _, _ = disassemble(qobj) self.assertCircuitCalibrationsEqual([qc], output_circuits)
def test_2q_hamiltonian(self): """test 2 qubit hamiltonian""" qr = QuantumRegister(2) cr = ClassicalRegister(2) qc = QuantumCircuit(qr, cr) matrix = Operator.from_label("XY") qc.x(qr[0]) theta = Parameter("theta") uni2q = HamiltonianGate(matrix, theta) qc.append(uni2q, [qr[0], qr[1]]) qc2 = qc.bind_parameters({theta: -np.pi / 2}) dag = circuit_to_dag(qc2) nodes = dag.two_qubit_ops() self.assertEqual(len(nodes), 1) dnode = nodes[0] self.assertIsInstance(dnode.op, HamiltonianGate) self.assertEqual(dnode.qargs, [qr[0], qr[1]]) # Equality based on Pauli exponential identity np.testing.assert_array_almost_equal(dnode.op.to_matrix(), 1j * matrix.data) qc3 = dag_to_circuit(dag) self.assertEqual(qc2, qc3)
def test_custom_gate_with_unbound_parameter(self): """Test custom gate with unbound parameter.""" parameter_a = Parameter("a") custom = QuantumCircuit(1, name="custom") custom.rx(parameter_a, 0) circuit = QuantumCircuit(1) circuit.append(custom.to_gate(), [0]) expected_qasm = "\n".join([ "OPENQASM 3;", 'include "stdgates.inc";', "gate custom(a) q_0 {", " rx(a) q_0;", "}", "input float[32] a;", "qubit[1] _q;", "let q = _q[0];", "custom(a) q[0];", "", ]) self.assertEqual(Exporter().dumps(circuit), expected_qasm)
def _spec_gate_schedule( self, backend: Optional[Backend] = None ) -> Tuple[pulse.ScheduleBlock, Parameter]: """Create the spectroscopy schedule.""" freq_param = Parameter("frequency") with pulse.build(backend=backend, name="spectroscopy") as schedule: pulse.shift_frequency(freq_param, pulse.DriveChannel(self.physical_qubits[0])) pulse.play( pulse.GaussianSquare( duration=self.experiment_options.duration, amp=self.experiment_options.amp, sigma=self.experiment_options.sigma, width=self.experiment_options.width, ), pulse.DriveChannel(self.physical_qubits[0]), ) pulse.shift_frequency(-freq_param, pulse.DriveChannel(self.physical_qubits[0])) return schedule, freq_param