def _build(self): if self._data is not None: return super()._build() # keep old parameter order: first cost operator, then mixer operators num_cost = 0 if _is_pauli_identity(self.cost_operator) else 1 if isinstance(self.mixer_operator, QuantumCircuit): num_mixer = self.mixer_operator.num_parameters else: num_mixer = 0 if _is_pauli_identity(self.mixer_operator) else 1 betas = ParameterVector("β", self.reps * num_mixer) gammas = ParameterVector("γ", self.reps * num_cost) # Create a permutation to take us from (cost_1, mixer_1, cost_2, mixer_2, ...) # to (cost_1, cost_2, ..., mixer_1, mixer_2, ...), or if the mixer is a circuit # with more than 1 parameters, from (cost_1, mixer_1a, mixer_1b, cost_2, ...) # to (cost_1, cost_2, ..., mixer_1a, mixer_1b, mixer_2a, mixer_2b, ...) reordered = [] for rep in range(self.reps): reordered.extend(gammas[rep * num_cost:(rep + 1) * num_cost]) reordered.extend(betas[rep * num_mixer:(rep + 1) * num_mixer]) self.assign_parameters(dict(zip(self.ordered_parameters, reordered)), inplace=True)
def generate_parameter_vector(): """Generate tests for parameter vector element ordering.""" qc = QuantumCircuit(11) input_params = ParameterVector("x_par", 11) user_params = ParameterVector("θ_par", 11) for i, param in enumerate(user_params): qc.ry(param, i) for i, param in enumerate(input_params): qc.rz(param, i) return qc
def test_parameter_vector(self): """Test a circuit with a parameter vector for gate parameters.""" qc = QuantumCircuit(11) input_params = ParameterVector("x_par", 11) user_params = ParameterVector("θ_par", 11) for i, param in enumerate(user_params): qc.ry(param, i) for i, param in enumerate(input_params): qc.rz(param, i) qpy_file = io.BytesIO() dump(qc, qpy_file) qpy_file.seek(0) new_circuit = load(qpy_file)[0] expected_params = [x.name for x in qc.parameters] self.assertEqual([x.name for x in new_circuit.parameters], expected_params)
def test_parameter_vector_global_phase(self): """Test that a circuit with a standalone ParameterVectorElement phase works.""" vec = ParameterVector("phase", 1) qc = QuantumCircuit(1, global_phase=vec[0]) qpy_file = io.BytesIO() dump(qc, qpy_file) qpy_file.seek(0) new_circuit = load(qpy_file)[0] self.assertEqual(qc, new_circuit)
def generate_parameter_vector_expression(): # pylint: disable=invalid-name """Generate tests for parameter vector element ordering.""" qc = QuantumCircuit(7) entanglement = [[i, i + 1] for i in range(7 - 1)] input_params = ParameterVector("x_par", 14) user_params = ParameterVector("\u03B8_par", 1) for i in range(qc.num_qubits): qc.ry(user_params[0], qc.qubits[i]) for source, target in entanglement: qc.cz(qc.qubits[source], qc.qubits[target]) for i in range(qc.num_qubits): qc.rz(-2 * input_params[2 * i + 1], qc.qubits[i]) qc.rx(-2 * input_params[2 * i], qc.qubits[i]) return qc
def test_parameter_vector_incomplete_warns(self): """Test that qpy's deserialization warns if a ParameterVector isn't fully identical.""" vec = ParameterVector("test", 3) qc = QuantumCircuit(1, name="fun") qc.rx(vec[1], 0) qpy_file = io.BytesIO() dump(qc, qpy_file) qpy_file.seek(0) with self.assertWarnsRegex(UserWarning, r"^The ParameterVector.*Elements 0, 2.*fun$"): new_circuit = load(qpy_file)[0] self.assertEqual(qc, new_circuit)
def test_parameter_vector_element_in_expression(self): """Test a circuit with a parameter vector used in a parameter expression.""" qc = QuantumCircuit(7) entanglement = [[i, i + 1] for i in range(7 - 1)] input_params = ParameterVector("x_par", 14) user_params = ParameterVector("\u03B8_par", 1) for i in range(qc.num_qubits): qc.ry(user_params[0], qc.qubits[i]) for source, target in entanglement: qc.cz(qc.qubits[source], qc.qubits[target]) for i in range(qc.num_qubits): qc.rz(-2 * input_params[2 * i + 1], qc.qubits[i]) qc.rx(-2 * input_params[2 * i], qc.qubits[i]) qpy_file = io.BytesIO() dump(qc, qpy_file) qpy_file.seek(0) new_circuit = load(qpy_file)[0] expected_params = [x.name for x in qc.parameters] self.assertEqual([x.name for x in new_circuit.parameters], expected_params)
def test_evolutiongate_param_vec_time(self): """Test loading a an evolution gate that has a param vector element for time.""" synthesis = LieTrotter(reps=2) time = ParameterVector("TimeVec", 1) evo = PauliEvolutionGate((Z ^ I) + (I ^ Z), time=time[0], synthesis=synthesis) qc = QuantumCircuit(2) qc.append(evo, range(2)) qpy_file = io.BytesIO() dump(qc, qpy_file) qpy_file.seek(0) new_circ = load(qpy_file)[0] self.assertEqual(qc, new_circ) self.assertEqual([x[0].label for x in qc.data], [x[0].label for x in new_circ.data]) new_evo = new_circ.data[0][0] self.assertIsInstance(new_evo, PauliEvolutionGate)
def _build(self) -> None: """Build the circuit.""" if self._data: return self._check_configuration() self._data = [] # calculate bounds, num_parameters, mixer self._calculate_parameters() # parameterize circuit and build it param_vector = ParameterVector("θ", self._num_parameters) circuit = self._construct_circuit(param_vector) # append(replace) the circuit to this self.compose(circuit, inplace=True)
def _read_parameter_vec(file_obj, vectors): data = formats.PARAMETER_VECTOR_ELEMENT( *struct.unpack( formats.PARAMETER_VECTOR_ELEMENT_PACK, file_obj.read(formats.PARAMETER_VECTOR_ELEMENT_SIZE), ), ) param_uuid = uuid.UUID(bytes=data.uuid) name = file_obj.read(data.vector_name_size).decode(common.ENCODE) if name not in vectors: vectors[name] = (ParameterVector(name, data.vector_size), set()) vector = vectors[name][0] if vector[data.index]._uuid != param_uuid: vectors[name][1].add(data.index) vector._params[data.index] = ParameterVectorElement.__new__( ParameterVectorElement, vector, data.index, uuid=param_uuid) vector._params[data.index].__init__(vector, data.index) return vector[data.index]