From 8cc03ffb52595c953ef9d4f7de4d5d725927f614 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Tue, 29 Aug 2023 17:40:32 -0500 Subject: [PATCH 01/40] Add a public generate_cutting_experiments function --- circuit_knitting/cutting/__init__.py | 8 +- .../cutting/cutting_evaluation.py | 149 +++++++++++++++++- test/cutting/test_cutting_decomposition.py | 105 ++++++++++++ 3 files changed, 257 insertions(+), 5 deletions(-) diff --git a/circuit_knitting/cutting/__init__.py b/circuit_knitting/cutting/__init__.py index b8f65f9eb..f1ab411e4 100644 --- a/circuit_knitting/cutting/__init__.py +++ b/circuit_knitting/cutting/__init__.py @@ -27,6 +27,7 @@ partition_problem cut_gates decompose_gates + generate_cutting_experiments execute_experiments reconstruct_expectation_values @@ -86,7 +87,11 @@ decompose_gates, PartitionedCuttingProblem, ) -from .cutting_evaluation import execute_experiments, CuttingExperimentResults +from .cutting_evaluation import ( + execute_experiments, + CuttingExperimentResults, + generate_cutting_experiments, +) from .cutting_reconstruction import reconstruct_expectation_values from .wire_cutting_transforms import cut_wires, expand_observables @@ -95,6 +100,7 @@ "partition_problem", "cut_gates", "decompose_gates", + "generate_cutting_experiments", "execute_experiments", "reconstruct_expectation_values", "PartitionedCuttingProblem", diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 2f0a5cdf9..72240f23d 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -14,6 +14,7 @@ from __future__ import annotations from typing import Any, NamedTuple +from collections import defaultdict from collections.abc import Sequence from itertools import chain @@ -238,6 +239,131 @@ def _append_measurement_circuit( return qc +def generate_cutting_experiments( + circuits: QuantumCircuit | dict[str | int, QuantumCircuit], + observables: PauliList | dict[str | int, PauliList], + num_samples: int | float, +) -> tuple[ + list[QuantumCircuit] | dict[str | int, list[QuantumCircuit]], + list[tuple[float, WeightType]], +]: + """ + Generate cutting subexperiments and their associated weights. + + If the input circuit and observables are not split into multiple partitions, the output + subexperiments will be contained within a 1D array. + + If the input circuit and observables is split into multiple partitions, the output + subexperiments will be returned as a dictionary which maps a partition label to to + a 1D array containing the subexperiments associated with that partition. + + In both cases, the subexperiment lists are ordered as follows: + :math:`[sample_{0}observable_{0}, sample_{0}observable_{1}, ..., sample_{0}observable_{N}, ..., sample_{M}observable_{N}]` + + The weights will always be returned as a 1D array -- one weight for each unique sample. + + Args: + circuits: The circuit(s) to partition and separate + observables: The observable(s) to evaluate for each unique sample + num_samples: The number of samples to draw from the quasi-probability distribution. If set + to infinity, the weights will be generated rigorously rather than by sampling from + the distribution. + Returns: + A tuple containing the cutting experiments and their associated weights. + If the input circuits is a :class:`QuantumCircuit` instance, the output subexperiments + will be a sequence of circuits -- one for every unique sample and observable. If the + input circuits are represented as a dictionary keyed by partition labels, the output + subexperiments will also be a dictionary keyed by partition labels and containing + the subexperiments for each partition. + The weights are always a sequence of length-2 tuples, where each tuple contains the + weight and the :class:`WeightType`. Each weight corresponds to one unique sample. + + Raises: + ValueError: ``num_samples`` must either be an integer or infinity. + ValueError: :class:`SingleQubitQPDGate` instances must have the cut number + appended to the gate label. + ValueError: :class:`SingleQubitQPDGate` instances are not allowed in unseparated circuits. + """ + if isinstance(num_samples, float): + if num_samples != np.inf: + raise ValueError("num_samples must either be an integer or infinity.") + + # Retrieving the unique bases, QPD gates, and decomposed observables is slightly different + # depending on the format of the execute_experiments input args, but the 2nd half of this function + # can be shared between both cases. + if isinstance(circuits, QuantumCircuit): + is_separated = False + subcircuit_list = [circuits] + subobservables_by_subsystem = decompose_observables( + observables, "A" * len(observables[0]) + ) + subsystem_observables = { + label: ObservableCollection(subobservables) + for label, subobservables in subobservables_by_subsystem.items() + } + # Gather the unique bases from the circuit + bases, qpd_gate_ids = _get_bases(circuits) + subcirc_qpd_gate_ids = [qpd_gate_ids] + + else: + is_separated = True + subcircuit_list = [circuits[key] for key in sorted(circuits.keys())] + # Gather the unique bases across the subcircuits + subcirc_qpd_gate_ids, subcirc_map_ids = _get_mapping_ids_by_partition( + subcircuit_list + ) + bases = _get_bases_by_partition(subcircuit_list, subcirc_qpd_gate_ids) + + # Create the commuting observable groups + subsystem_observables = { + label: ObservableCollection(so) for label, so in observables.items() + } + + # Sample the joint quasiprobability decomposition + random_samples = generate_qpd_weights(bases, num_samples=num_samples) + + # Calculate terms in coefficient calculation + kappa = np.prod([basis.kappa for basis in bases]) + num_samples = sum([value[0] for value in random_samples.values()]) # type: ignore + + # Sort samples in descending order of frequency + sorted_samples = sorted(random_samples.items(), key=lambda x: x[1][0], reverse=True) + + # Generate the output experiments and weights + subexperiments_dict: dict[str | int, list[QuantumCircuit]] = defaultdict(list) + weights: list[tuple[float, WeightType]] = [] + for i, (subcircuit, label) in enumerate( + strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) + ): + for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): + actual_coeff = np.prod( + [basis.coeffs[map_id] for basis, map_id in strict_zip(bases, map_ids)] + ) + sampled_coeff = (redundancy / num_samples) * (kappa * np.sign(actual_coeff)) + if i == 0: + weights.append((sampled_coeff, weight_type)) + map_ids_tmp = map_ids + if is_separated: + map_ids_tmp = tuple(map_ids[j] for j in subcirc_map_ids[i]) + decomp_qc = decompose_qpd_instructions( + subcircuit, subcirc_qpd_gate_ids[i], map_ids_tmp + ) + so = subsystem_observables[label] + for j, cog in enumerate(so.groups): + meas_qc = _append_measurement_circuit(decomp_qc, cog) + subexperiments_dict[label].append(meas_qc) + + # If the circuit wasn't separated, return the subexperiments as a list + subexperiments_out: list[QuantumCircuit] | dict[ + str | int, list[QuantumCircuit] + ] = subexperiments_dict + assert isinstance(subexperiments_out, dict) + if len(subexperiments_out.keys()) == 1: + subexperiments_out = subexperiments_dict[list(subexperiments_dict.keys())[0]] + + return subexperiments_out, weights + + def _generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], @@ -377,7 +503,10 @@ def _get_mapping_ids_by_partition( subcirc_map_ids.append([]) for i, inst in enumerate(circ.data): if isinstance(inst.operation, SingleQubitQPDGate): - decomp_id = int(inst.operation.label.split("_")[-1]) + try: + decomp_id = int(inst.operation.label.split("_")[-1]) + except (AttributeError, ValueError): + _raise_bad_qpd_gate_labels() decomp_ids.add(decomp_id) subcirc_qpd_gate_ids[-1].append([i]) subcirc_map_ids[-1].append(decomp_id) @@ -385,6 +514,14 @@ def _get_mapping_ids_by_partition( return subcirc_qpd_gate_ids, subcirc_map_ids +def _raise_bad_qpd_gate_labels() -> None: + raise ValueError( + "BaseQPDGate instances in input circuit(s) should have their " + 'labels suffixed with "_" so that sibling SingleQubitQPDGate ' + "instances may be grouped and sampled together." + ) + + def _get_bases_by_partition( circuits: Sequence[QuantumCircuit], subcirc_qpd_gate_ids: list[list[list[int]]] ) -> list[QPDBasis]: @@ -393,9 +530,13 @@ def _get_bases_by_partition( bases_dict = {} for i, subcirc in enumerate(subcirc_qpd_gate_ids): for basis_id in subcirc: - decomp_id = int( - circuits[i].data[basis_id[0]].operation.label.split("_")[-1] - ) + try: + decomp_id = int( + circuits[i].data[basis_id[0]].operation.label.split("_")[-1] + ) + except (AttributeError, ValueError): # pragma: no cover + _raise_bad_qpd_gate_labels() # pragma: no cover + bases_dict[decomp_id] = circuits[i].data[basis_id[0]].operation.basis bases = [bases_dict[key] for key in sorted(bases_dict.keys())] diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 4118a6537..723169506 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -23,14 +23,17 @@ from circuit_knitting.cutting import ( partition_circuit_qubits, + generate_cutting_experiments, partition_problem, cut_gates, ) from circuit_knitting.cutting.instructions import Move from circuit_knitting.cutting.qpd import ( QPDBasis, + SingleQubitQPDGate, TwoQubitQPDGate, BaseQPDGate, + WeightType, ) @@ -284,3 +287,105 @@ def test_unused_qubits(self): ) assert subcircuits.keys() == {"A", "B"} assert subobservables.keys() == {"A", "B"} + + def test_generate_cutting_experiments(self): + with self.subTest("simple circuit and observable"): + qc = QuantumCircuit(2) + qc.append( + TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), + qargs=[0, 1], + ) + comp_weights = [ + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + ] + subexperiments, weights = generate_cutting_experiments( + qc, PauliList(["ZZ"]), np.inf + ) + assert weights == comp_weights + assert len(weights) == len(subexperiments) + for exp in subexperiments: + assert isinstance(exp, QuantumCircuit) + + with self.subTest("simple circuit and observable as dict"): + qc = QuantumCircuit(2) + qc.append( + SingleQubitQPDGate( + QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=0 + ), + qargs=[0], + ) + qc.append( + SingleQubitQPDGate( + QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=1 + ), + qargs=[1], + ) + comp_weights = [ + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + ] + subexperiments, weights = generate_cutting_experiments( + {"A": qc}, {"A": PauliList(["ZY"])}, np.inf + ) + assert weights == comp_weights + assert len(weights) == len(subexperiments) + for exp in subexperiments: + assert isinstance(exp, QuantumCircuit) + + with self.subTest("test bad num_samples"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 4.5) + assert ( + e_info.value.args[0] + == "num_samples must either be an integer or infinity." + ) + with self.subTest("test bad label"): + qc = QuantumCircuit(2) + qc.append( + TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), + qargs=[0, 1], + ) + partitioned_problem = partition_problem( + qc, "AB", observables=PauliList(["ZZ"]) + ) + partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments( + partitioned_problem.subcircuits, + partitioned_problem.subobservables, + np.inf, + ) + assert e_info.value.args[0] == ( + "BaseQPDGate instances in input circuit(s) should have their labels suffixed with " + '"_" so that sibling SingleQubitQPDGate instances may be grouped and sampled together.' + ) + with self.subTest("test bad observable size"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + assert e_info.value.args[0] == ( + "Quantum circuit qubit count (4) does not match qubit count of observable(s) (2)." + " Try providing `qubit_locations` explicitly." + ) + with self.subTest("test single qubit qpd gate in unseparated circuit"): + qc = QuantumCircuit(2) + qc.append( + SingleQubitQPDGate(QPDBasis.from_gate(CXGate()), 0, label="cut_cx_0"), + qargs=[0], + ) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + assert ( + e_info.value.args[0] + == "SingleQubitQPDGates are not supported in unseparable circuits." + ) From dbe0cae3c0de59ca4367bcaa302c3c8444dbd2da Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Tue, 29 Aug 2023 17:47:32 -0500 Subject: [PATCH 02/40] playing with diff --- circuit_knitting/cutting/__init__.py | 6 +++--- circuit_knitting/cutting/cutting_evaluation.py | 6 +++--- test/cutting/test_cutting_decomposition.py | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/circuit_knitting/cutting/__init__.py b/circuit_knitting/cutting/__init__.py index f1ab411e4..d91577380 100644 --- a/circuit_knitting/cutting/__init__.py +++ b/circuit_knitting/cutting/__init__.py @@ -27,7 +27,7 @@ partition_problem cut_gates decompose_gates - generate_cutting_experiments + _generate_cutting_experiments execute_experiments reconstruct_expectation_values @@ -90,7 +90,7 @@ from .cutting_evaluation import ( execute_experiments, CuttingExperimentResults, - generate_cutting_experiments, + _generate_cutting_experiments, ) from .cutting_reconstruction import reconstruct_expectation_values from .wire_cutting_transforms import cut_wires, expand_observables @@ -100,7 +100,7 @@ "partition_problem", "cut_gates", "decompose_gates", - "generate_cutting_experiments", + "_generate_cutting_experiments", "execute_experiments", "reconstruct_expectation_values", "PartitionedCuttingProblem", diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 72240f23d..c8c525b3a 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -123,7 +123,7 @@ def execute_experiments( subexperiments, coefficients, sampled_frequencies, - ) = _generate_cutting_experiments( + ) = generate_cutting_experiments( circuits, subobservables, num_samples, @@ -239,7 +239,7 @@ def _append_measurement_circuit( return qc -def generate_cutting_experiments( +def _generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], num_samples: int | float, @@ -364,7 +364,7 @@ def generate_cutting_experiments( return subexperiments_out, weights -def _generate_cutting_experiments( +def generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], num_samples: int, diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 723169506..a49c1a772 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -23,7 +23,7 @@ from circuit_knitting.cutting import ( partition_circuit_qubits, - generate_cutting_experiments, + _generate_cutting_experiments, partition_problem, cut_gates, ) @@ -303,7 +303,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights = generate_cutting_experiments( + subexperiments, weights = _generate_cutting_experiments( qc, PauliList(["ZZ"]), np.inf ) assert weights == comp_weights @@ -333,7 +333,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights = generate_cutting_experiments( + subexperiments, weights = _generate_cutting_experiments( {"A": qc}, {"A": PauliList(["ZY"])}, np.inf ) assert weights == comp_weights @@ -344,7 +344,7 @@ def test_generate_cutting_experiments(self): with self.subTest("test bad num_samples"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 4.5) + _generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 4.5) assert ( e_info.value.args[0] == "num_samples must either be an integer or infinity." @@ -360,7 +360,7 @@ def test_generate_cutting_experiments(self): ) partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" with pytest.raises(ValueError) as e_info: - generate_cutting_experiments( + _generate_cutting_experiments( partitioned_problem.subcircuits, partitioned_problem.subobservables, np.inf, @@ -372,7 +372,7 @@ def test_generate_cutting_experiments(self): with self.subTest("test bad observable size"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + _generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) assert e_info.value.args[0] == ( "Quantum circuit qubit count (4) does not match qubit count of observable(s) (2)." " Try providing `qubit_locations` explicitly." @@ -384,7 +384,7 @@ def test_generate_cutting_experiments(self): qargs=[0], ) with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + _generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) assert ( e_info.value.args[0] == "SingleQubitQPDGates are not supported in unseparable circuits." From 76f8998cf2f73958de076828b2bb69d8882ca52f Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Tue, 29 Aug 2023 18:05:22 -0500 Subject: [PATCH 03/40] diff --- circuit_knitting/cutting/__init__.py | 6 +++--- circuit_knitting/cutting/cutting_evaluation.py | 6 +++--- test/cutting/test_cutting_decomposition.py | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/circuit_knitting/cutting/__init__.py b/circuit_knitting/cutting/__init__.py index d91577380..f1ab411e4 100644 --- a/circuit_knitting/cutting/__init__.py +++ b/circuit_knitting/cutting/__init__.py @@ -27,7 +27,7 @@ partition_problem cut_gates decompose_gates - _generate_cutting_experiments + generate_cutting_experiments execute_experiments reconstruct_expectation_values @@ -90,7 +90,7 @@ from .cutting_evaluation import ( execute_experiments, CuttingExperimentResults, - _generate_cutting_experiments, + generate_cutting_experiments, ) from .cutting_reconstruction import reconstruct_expectation_values from .wire_cutting_transforms import cut_wires, expand_observables @@ -100,7 +100,7 @@ "partition_problem", "cut_gates", "decompose_gates", - "_generate_cutting_experiments", + "generate_cutting_experiments", "execute_experiments", "reconstruct_expectation_values", "PartitionedCuttingProblem", diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index c8c525b3a..72240f23d 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -123,7 +123,7 @@ def execute_experiments( subexperiments, coefficients, sampled_frequencies, - ) = generate_cutting_experiments( + ) = _generate_cutting_experiments( circuits, subobservables, num_samples, @@ -239,7 +239,7 @@ def _append_measurement_circuit( return qc -def _generate_cutting_experiments( +def generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], num_samples: int | float, @@ -364,7 +364,7 @@ def _generate_cutting_experiments( return subexperiments_out, weights -def generate_cutting_experiments( +def _generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], num_samples: int, diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index a49c1a772..723169506 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -23,7 +23,7 @@ from circuit_knitting.cutting import ( partition_circuit_qubits, - _generate_cutting_experiments, + generate_cutting_experiments, partition_problem, cut_gates, ) @@ -303,7 +303,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights = _generate_cutting_experiments( + subexperiments, weights = generate_cutting_experiments( qc, PauliList(["ZZ"]), np.inf ) assert weights == comp_weights @@ -333,7 +333,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights = _generate_cutting_experiments( + subexperiments, weights = generate_cutting_experiments( {"A": qc}, {"A": PauliList(["ZY"])}, np.inf ) assert weights == comp_weights @@ -344,7 +344,7 @@ def test_generate_cutting_experiments(self): with self.subTest("test bad num_samples"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: - _generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 4.5) + generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 4.5) assert ( e_info.value.args[0] == "num_samples must either be an integer or infinity." @@ -360,7 +360,7 @@ def test_generate_cutting_experiments(self): ) partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" with pytest.raises(ValueError) as e_info: - _generate_cutting_experiments( + generate_cutting_experiments( partitioned_problem.subcircuits, partitioned_problem.subobservables, np.inf, @@ -372,7 +372,7 @@ def test_generate_cutting_experiments(self): with self.subTest("test bad observable size"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: - _generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) assert e_info.value.args[0] == ( "Quantum circuit qubit count (4) does not match qubit count of observable(s) (2)." " Try providing `qubit_locations` explicitly." @@ -384,7 +384,7 @@ def test_generate_cutting_experiments(self): qargs=[0], ) with pytest.raises(ValueError) as e_info: - _generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) assert ( e_info.value.args[0] == "SingleQubitQPDGates are not supported in unseparable circuits." From 77c1c98bd06363feca1ce7b76a3097cb219d7305 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 07:46:00 -0500 Subject: [PATCH 04/40] diff --- .../cutting/cutting_evaluation.py | 240 +++++++----------- ...gate_cutting_to_reduce_circuit_depth.ipynb | 53 ++++ test/cutting/test_cutting_decomposition.py | 4 +- 3 files changed, 149 insertions(+), 148 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 72240f23d..2614156e6 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -120,10 +120,10 @@ def execute_experiments( # Generate the sub-experiments to run on backend ( - subexperiments, + _, coefficients, - sampled_frequencies, - ) = _generate_cutting_experiments( + subexperiments, + ) = generate_cutting_experiments( circuits, subobservables, num_samples, @@ -174,71 +174,6 @@ def execute_experiments( return CuttingExperimentResults(quasi_dists, coefficients) -def _append_measurement_circuit( - qc: QuantumCircuit, - cog: CommutingObservableGroup, - /, - *, - qubit_locations: Sequence[int] | None = None, - inplace: bool = False, -) -> QuantumCircuit: - """Append a new classical register and measurement instructions for the given ``CommutingObservableGroup``. - - The new register will be named ``"observable_measurements"`` and will be - the final register in the returned circuit, i.e. ``retval.cregs[-1]``. - - Args: - qc: The quantum circuit - cog: The commuting observable set for - which to construct measurements - qubit_locations: A ``Sequence`` whose length is the number of qubits - in the observables, where each element holds that qubit's corresponding - index in the circuit. By default, the circuit and observables are assumed - to have the same number of qubits, and the identity map - (i.e., ``range(qc.num_qubits)``) is used. - inplace: Whether to operate on the circuit in place (default: ``False``) - - Returns: - The modified circuit - """ - if qubit_locations is None: - # By default, the identity map. - if qc.num_qubits != cog.general_observable.num_qubits: - raise ValueError( - f"Quantum circuit qubit count ({qc.num_qubits}) does not match qubit " - f"count of observable(s) ({cog.general_observable.num_qubits}). " - f"Try providing `qubit_locations` explicitly." - ) - qubit_locations = range(cog.general_observable.num_qubits) - else: - if len(qubit_locations) != cog.general_observable.num_qubits: - raise ValueError( - f"qubit_locations has {len(qubit_locations)} element(s) but the " - f"observable(s) have {cog.general_observable.num_qubits} qubit(s)." - ) - if not inplace: - qc = qc.copy() - - # Append the appropriate measurements to qc - obs_creg = ClassicalRegister(len(cog.pauli_indices), name="observable_measurements") - qc.add_register(obs_creg) - # Implement the necessary basis rotations and measurements, as - # in BackendEstimator._measurement_circuit(). - genobs_x = cog.general_observable.x - genobs_z = cog.general_observable.z - for clbit, subqubit in enumerate(cog.pauli_indices): - # subqubit is the index of the qubit in the subsystem. - # actual_qubit is its index in the system of interest (if different). - actual_qubit = qubit_locations[subqubit] - if genobs_x[subqubit]: - if genobs_z[subqubit]: - qc.sdg(actual_qubit) - qc.h(actual_qubit) - qc.measure(actual_qubit, obs_creg[clbit]) - - return qc - - def generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], @@ -246,6 +181,7 @@ def generate_cutting_experiments( ) -> tuple[ list[QuantumCircuit] | dict[str | int, list[QuantumCircuit]], list[tuple[float, WeightType]], + list[list[list[QuantumCircuit]]], ]: """ Generate cutting subexperiments and their associated weights. @@ -329,6 +265,30 @@ def generate_cutting_experiments( # Sort samples in descending order of frequency sorted_samples = sorted(random_samples.items(), key=lambda x: x[1][0], reverse=True) + subexperiments_legacy: list[list[list[QuantumCircuit]]] = [] + weights_legacy: list[tuple[float, WeightType]] = [] + for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): + subexperiments_legacy.append([]) + actual_coeff = np.prod( + [basis.coeffs[map_id] for basis, map_id in strict_zip(bases, map_ids)] + ) + sampled_coeff = (redundancy / num_samples) * (kappa * np.sign(actual_coeff)) + weights_legacy.append((sampled_coeff, weight_type)) + for i, (subcircuit, label) in enumerate( + strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) + ): + map_ids_tmp = map_ids + if is_separated: + map_ids_tmp = tuple(map_ids[j] for j in subcirc_map_ids[i]) + decomp_qc = decompose_qpd_instructions( + subcircuit, subcirc_qpd_gate_ids[i], map_ids_tmp + ) + subexperiments_legacy[-1].append([]) + so = subsystem_observables[label] + for j, cog in enumerate(so.groups): + meas_qc = _append_measurement_circuit(decomp_qc, cog) + subexperiments_legacy[-1][-1].append(meas_qc) + # Generate the output experiments and weights subexperiments_dict: dict[str | int, list[QuantumCircuit]] = defaultdict(list) weights: list[tuple[float, WeightType]] = [] @@ -361,84 +321,7 @@ def generate_cutting_experiments( if len(subexperiments_out.keys()) == 1: subexperiments_out = subexperiments_dict[list(subexperiments_dict.keys())[0]] - return subexperiments_out, weights - - -def _generate_cutting_experiments( - circuits: QuantumCircuit | dict[str | int, QuantumCircuit], - observables: PauliList | dict[str | int, PauliList], - num_samples: int, -) -> tuple[list[list[list[QuantumCircuit]]], list[tuple[Any, WeightType]], list[float]]: - """Generate all the experiments to run on the backend and their associated coefficients.""" - # Retrieving the unique bases, QPD gates, and decomposed observables is slightly different - # depending on the format of the execute_experiments input args, but the 2nd half of this function - # can be shared between both cases. - if isinstance(circuits, QuantumCircuit): - is_separated = False - subcircuit_list = [circuits] - subobservables_by_subsystem = decompose_observables( - observables, "A" * len(observables[0]) - ) - subsystem_observables = { - label: ObservableCollection(subobservables) - for label, subobservables in subobservables_by_subsystem.items() - } - # Gather the unique bases from the circuit - bases, qpd_gate_ids = _get_bases(circuits) - subcirc_qpd_gate_ids = [qpd_gate_ids] - - else: - is_separated = True - subcircuit_list = [circuits[key] for key in sorted(circuits.keys())] - # Gather the unique bases across the subcircuits - subcirc_qpd_gate_ids, subcirc_map_ids = _get_mapping_ids_by_partition( - subcircuit_list - ) - bases = _get_bases_by_partition(subcircuit_list, subcirc_qpd_gate_ids) - - # Create the commuting observable groups - subsystem_observables = { - label: ObservableCollection(so) for label, so in observables.items() - } - - # Sample the joint quasiprobability decomposition - random_samples = generate_qpd_weights(bases, num_samples=num_samples) - - # Calculate terms in coefficient calculation - kappa = np.prod([basis.kappa for basis in bases]) - num_samples = sum([value[0] for value in random_samples.values()]) # type: ignore - - # Sort samples in descending order of frequency - sorted_samples = sorted(random_samples.items(), key=lambda x: x[1][0], reverse=True) - - # Generate the outputs -- sub-experiments, coefficients, and frequencies - subexperiments: list[list[list[QuantumCircuit]]] = [] - coefficients = [] - sampled_frequencies = [] - for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): - subexperiments.append([]) - actual_coeff = np.prod( - [basis.coeffs[map_id] for basis, map_id in strict_zip(bases, map_ids)] - ) - sampled_coeff = (redundancy / num_samples) * (kappa * np.sign(actual_coeff)) - coefficients.append((sampled_coeff, weight_type)) - sampled_frequencies.append(redundancy) - for i, (subcircuit, label) in enumerate( - strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) - ): - map_ids_tmp = map_ids - if is_separated: - map_ids_tmp = tuple(map_ids[j] for j in subcirc_map_ids[i]) - decomp_qc = decompose_qpd_instructions( - subcircuit, subcirc_qpd_gate_ids[i], map_ids_tmp - ) - subexperiments[-1].append([]) - so = subsystem_observables[label] - for j, cog in enumerate(so.groups): - meas_qc = _append_measurement_circuit(decomp_qc, cog) - subexperiments[-1][-1].append(meas_qc) - - return subexperiments, coefficients, sampled_frequencies + return subexperiments_out, weights, subexperiments_legacy def _run_experiments_batch( @@ -559,6 +442,71 @@ def _get_bases(circuit: QuantumCircuit) -> tuple[list[QPDBasis], list[list[int]] return bases, qpd_gate_ids +def _append_measurement_circuit( + qc: QuantumCircuit, + cog: CommutingObservableGroup, + /, + *, + qubit_locations: Sequence[int] | None = None, + inplace: bool = False, +) -> QuantumCircuit: + """Append a new classical register and measurement instructions for the given ``CommutingObservableGroup``. + + The new register will be named ``"observable_measurements"`` and will be + the final register in the returned circuit, i.e. ``retval.cregs[-1]``. + + Args: + qc: The quantum circuit + cog: The commuting observable set for + which to construct measurements + qubit_locations: A ``Sequence`` whose length is the number of qubits + in the observables, where each element holds that qubit's corresponding + index in the circuit. By default, the circuit and observables are assumed + to have the same number of qubits, and the identity map + (i.e., ``range(qc.num_qubits)``) is used. + inplace: Whether to operate on the circuit in place (default: ``False``) + + Returns: + The modified circuit + """ + if qubit_locations is None: + # By default, the identity map. + if qc.num_qubits != cog.general_observable.num_qubits: + raise ValueError( + f"Quantum circuit qubit count ({qc.num_qubits}) does not match qubit " + f"count of observable(s) ({cog.general_observable.num_qubits}). " + f"Try providing `qubit_locations` explicitly." + ) + qubit_locations = range(cog.general_observable.num_qubits) + else: + if len(qubit_locations) != cog.general_observable.num_qubits: + raise ValueError( + f"qubit_locations has {len(qubit_locations)} element(s) but the " + f"observable(s) have {cog.general_observable.num_qubits} qubit(s)." + ) + if not inplace: + qc = qc.copy() + + # Append the appropriate measurements to qc + obs_creg = ClassicalRegister(len(cog.pauli_indices), name="observable_measurements") + qc.add_register(obs_creg) + # Implement the necessary basis rotations and measurements, as + # in BackendEstimator._measurement_circuit(). + genobs_x = cog.general_observable.x + genobs_z = cog.general_observable.z + for clbit, subqubit in enumerate(cog.pauli_indices): + # subqubit is the index of the qubit in the subsystem. + # actual_qubit is its index in the system of interest (if different). + actual_qubit = qubit_locations[subqubit] + if genobs_x[subqubit]: + if genobs_z[subqubit]: + qc.sdg(actual_qubit) + qc.h(actual_qubit) + qc.measure(actual_qubit, obs_creg[clbit]) + + return qc + + def _validate_samplers(samplers: BaseSampler | dict[str | int, BaseSampler]) -> None: """Replace unsupported statevector-based Samplers with ExactSampler.""" if isinstance(samplers, BaseSampler): diff --git a/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb b/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb index e18d2bfc9..cd0962858 100644 --- a/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb +++ b/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb @@ -16,6 +16,59 @@ "- **reconstruct** the expectation value of the full-sized circuit" ] }, + { + "cell_type": "code", + "execution_count": 7, + "id": "eecc1a96-a1af-46c1-a4cc-cae5ae8356f4", + "metadata": {}, + "outputs": [ + { + "ename": "KeyError", + "evalue": "0", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[7], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m a \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124ma\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;241m2\u001b[39m}\n\u001b[0;32m----> 2\u001b[0m \u001b[43ma\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mKeyError\u001b[0m: 0" + ] + } + ], + "source": [ + "a = {\"a\": 2}\n", + "a.pop()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "69e100a1-b092-4bfc-b990-2a19bb0f46f0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[[ 1, 2, 3],\n", + " [ 4, 5, 6]],\n", + "\n", + " [[ 7, 8, 9],\n", + " [10, 11, 12]]])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy as np\n", + "\n", + "a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\n", + "\n", + "b = np.reshape(a, (2, 2, 3))\n", + "b" + ] + }, { "cell_type": "code", "execution_count": 1, diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 723169506..ca31c4381 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -303,7 +303,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights = generate_cutting_experiments( + subexperiments, weights, _ = generate_cutting_experiments( qc, PauliList(["ZZ"]), np.inf ) assert weights == comp_weights @@ -333,7 +333,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights = generate_cutting_experiments( + subexperiments, weights, _ = generate_cutting_experiments( {"A": qc}, {"A": PauliList(["ZY"])}, np.inf ) assert weights == comp_weights From d4b42a06058c5145d6f771001e1fc715900789fa Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 07:50:06 -0500 Subject: [PATCH 05/40] ruff --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 2614156e6..002c0ea59 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -13,7 +13,7 @@ from __future__ import annotations -from typing import Any, NamedTuple +from typing import NamedTuple from collections import defaultdict from collections.abc import Sequence from itertools import chain From 7a822bf2cbc75d655e1f21e8844f58d8ae272615 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 08:18:58 -0500 Subject: [PATCH 06/40] revert accidental change --- ...gate_cutting_to_reduce_circuit_depth.ipynb | 63 ++----------------- 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb b/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb index cd0962858..979571417 100644 --- a/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb +++ b/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb @@ -16,59 +16,6 @@ "- **reconstruct** the expectation value of the full-sized circuit" ] }, - { - "cell_type": "code", - "execution_count": 7, - "id": "eecc1a96-a1af-46c1-a4cc-cae5ae8356f4", - "metadata": {}, - "outputs": [ - { - "ename": "KeyError", - "evalue": "0", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[7], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m a \u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124ma\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;241m2\u001b[39m}\n\u001b[0;32m----> 2\u001b[0m \u001b[43ma\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpop\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mKeyError\u001b[0m: 0" - ] - } - ], - "source": [ - "a = {\"a\": 2}\n", - "a.pop()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "69e100a1-b092-4bfc-b990-2a19bb0f46f0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[[ 1, 2, 3],\n", - " [ 4, 5, 6]],\n", - "\n", - " [[ 7, 8, 9],\n", - " [10, 11, 12]]])" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import numpy as np\n", - "\n", - "a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]\n", - "\n", - "b = np.reshape(a, (2, 2, 3))\n", - "b" - ] - }, { "cell_type": "code", "execution_count": 1, @@ -305,7 +252,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABs0AAAE2CAYAAAAqK9xEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACMWklEQVR4nOzdd3gU5drH8e+mEtIgoYQSeu+9KCBVQJAqIiJFBQuCoohHVBQUUTyvDQsWFAsiYsEjeJQSAUHpvYO0ECD0QEIKKfv+sYfAkrZJtkx2f5/r4iKZtvfmnnme2b1nnjGZzWYzIiIiIiIiIiIiIiIiIh7My9UBiIiIiIiIiIiIiIiIiLiaimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj+ewolnHjh0ZP368w9cx6jZERERERERERERERESk6ChQ0Sw2NpYnnniCGjVqUKxYMcqWLcutt97KrFmzSExMtHeMdjVy5EhMJhMmkwk/Pz9q1KjByy+/TFpamqtDc5j777+fF154Icv0119/HZPJpAKhiIiIiIiIiIiIiIh4PJ/8rnD48GFuvfVWSpQowfTp02nYsCH+/v7s3LmTTz75hAoVKtCnTx9HxGo3PXr0YM6cOaSkpPDf//6Xxx57DF9fXyZNmuTq0OwuPT2dxYsX8+uvv1pN37hxIx9//DGNGjVyUWQiIiIiIiIiIiIiIiLGke87zcaMGYOPjw+bNm3i7rvvpm7dulSrVo2+ffvy66+/cuedd2a7XkpKCo8//jhlypShWLFitGvXjo0bN2ZZLi0tjbFjxxIaGkqpUqWYPHkyZrMZgN9//5127dpRokQJwsPD6d27N4cOHcrvW8Df35+IiAgqV67Mo48+SteuXfnll1+slsnIyOCZZ54hLCyMiIgIpkyZkjnPljh++OEHGjZsSEBAAOHh4XTt2pUrV65kbvu1116jatWqBAQE0LhxY3744Yd8v4+6detm3jV387/3338fgL///htfX19atmyZuV5CQgJDhw7l008/pWTJkvl+XREREREREREREREREXeTr6LZ+fPnWbp0KY899hiBgYHZLmMymbKd/swzz/Djjz/y5ZdfsmXLFmrUqEH37t25cOGC1XJffvklPj4+bNiwgXfffZe33nqL2bNnA3DlyhWeeuopNm3aRFRUFF5eXvTv35+MjIz8vI0sAgICuHr1apY4AgMDWb9+PW+88QYvv/wyy5YtsymOU6dOMWTIEB544AH27t3LypUrGTBgQGbx77XXXuOrr77io48+Yvfu3Tz55JPcd999rFq1KvP1v/jiixz/ltf8+OOPAERFRXHq1CmOHj2Kl5cX33//PaNHjwbgl19+4c4777Ta1mOPPUavXr3o2rVrof5uIiIiIiIiIiIiIiIi7iJfwzP+888/mM1mateubTW9VKlSJCcnA5aCzIwZM6zmX7lyhVmzZvHFF1/Qs2dPAD799FOWLVvGZ599xsSJEzOXjYyM5O2338ZkMlG7dm127tzJ22+/zejRoxk4cKDVdj///HNKly7Nnj17aNCgQX7eCgBms5moqCiWLFnCuHHjrOY1atSIl156CYCaNWvy/vvvExUVRbdu3fKM49SpU6SlpTFgwAAqV64MQMOGDQHLHXfTp09n+fLltG3bFoBq1aqxZs0aPv74Y2677TYAQkNDs/ydb3b69Gl8fHy49dZb8ff3Z/PmzWRkZNC+fXv8/f0B+M9//sPbb7+duc78+fPZsmVLtnf5iYiIiIiIiIiIiIiIeKp8D8+YnQ0bNrBt2zbq169PSkpKlvmHDh0iNTWVW2+9NXOar68vrVq1Yu/evVbLtmnTxuquqLZt23Lw4EHS09M5ePAgQ4YMoVq1aoSEhFClShUAoqOj8xXv4sWLCQoKolixYvTs2ZPBgwdbDb8IZHnWV7ly5Thz5gxAnnE0btyYLl260LBhQwYNGsSnn37KxYsXAUvhMTExkW7duhEUFJT576uvvrIa4rF///7s27cv1/exc+dOatWqlVkg2759O2XKlKFs2bIA7N27l5MnT9KlSxcAjh8/zhNPPME333xDsWLF8vU3ExERERERERERERERcWf5utOsRo0amEwm9u/fbzW9WrVqgGWYQ0e68847qVy5Mp9++inly5cnIyODBg0aZBlaMS+dOnVi1qxZ+Pn5Ub58eXx8sv4ZfH19rX43mUyZwy/mFYe3tzfLli3j77//ZunSpbz33ns8//zzrF+/noSEBAB+/fVXKlSoYPUa14pfttqxY0fmHWxgKZrd+Psvv/xCt27dMgtkmzdv5syZMzRr1ixzmfT0dP7880/ef/99UlJS8Pb2zlcMIiIiIiIiIiIiIiIi7iBfd5qFh4fTrVs33n//fa5cuWLzetWrV8fPz4+//vorc1pqaiobN26kXr16VsuuX7/e6vd169ZRs2ZN4uLi2L9/Py+88AJdunShbt26mXdv5VdgYCA1atSgUqVK2RbMcnP+/Hmb4jCZTNx6661MnTqVrVu34ufnx8KFC6lXrx7+/v5ER0dTo0YNq3+RkZH5imXHjh1Wd8Rt377d6vf//Oc/9O3bN/P3Ll26sHPnTrZt25b5r0WLFgwdOpRt27apYCYiIiIiIiIiIiIiIh4rfxUj4MMPP+TWW2+lRYsWTJkyhUaNGuHl5cXGjRvZt28fzZs3z7JOYGAgjz76KBMnTiQsLIxKlSrxxhtvkJiYyIMPPmi1bHR0NE899RQPP/wwW7Zs4b333uPNN9+kZMmShIeH88knn1CuXDmio6N59tlnC/7OC8iWONavX09UVBS33347ZcqUYf369Zw9e5a6desSHBzM008/zZNPPklGRgbt2rXj0qVL/PXXX4SEhDBixAgAFi5cyKRJk3IcojEjI4Pdu3fz4osvZk47dOgQAwYMAODMmTNs2rSJX375JXN+cHBwlme/BQYGEh4eXqBnwomIiIiIiIiIiIiIiLiLfBfNqlevztatW5k+fTqTJk0iJiYGf39/6tWrx9NPP82YMWOyXe/1118nIyODYcOGER8fT4sWLViyZAklS5a0Wm748OEkJSXRqlUrvL29eeKJJ3jooYcwmUzMnz+fxx9/nAYNGlC7dm1mzpxJx44dC/TGC8rLyyvPOEJCQvjzzz955513uHz5MpUrV+bNN9+kZ8+eALzyyiuULl2a1157jcOHD1OiRAmaNWvGc889l7mNS5cuZRkG80aHDh0iMTHR6s6yhg0b8tJLL9G8eXP27dtHq1atKFWqlP3/CCIiIiIiIiIiIiIiIm7GZDabza4OQuyvT58+tGvXjmeeecbVoYiIiIiIiIiIiIiIiBhevp5pJkVHu3btGDJkiKvDEBERERERERERERERKRJ0p5mIiIiIiIiIiIiIiIh4PN1pJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjH83F1ACKSf9sWQlKcq6OAgBLQpH/htvHpSjifYI9oCi88CEZ3LNw2lBvHUG7cm1H2NXfaz8C92gHlRooSo+xr7tQGgHu1A8pNVu6UG3fTp08fDh065OowqF69Or/88kuhtmGU/Qzcqx1wpzYA1A7czCj7GbjXvuZObQAoN+J+VDQTKYKS4uDKeVdHYR/nEyD2kqujsB/lxrjcKTfuxp32NXfbz5Qbkfxzp33NndoAUG6MzJ1y424OHTrEnj17XB2GXbjbfuZO7YC75caduNN+Bu61ryk3Io6j4RlFRERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8no+rAxARx3lj/kiWbf4SAC+TF2Eh5WhSvTMP3vEapUIruDg6z6bcGJdyI86ifc24lBtxBu1nxqXcGJdyI86ifc24lBtxBu1nxqXciDPoTjMRN9ewanu+m3yKb56PZtK98/jn5FZe+XqQq8MSlBsjU27EWbSvGZdyI86g/cy4lBvjUm7EWbSvGZdyI86g/cy4lBtxNN1pJuLmfLz9CAuJAKBUaAV6tX6ID/7zOFeSLxNYLMTF0RVcetpV3h/pX+D1n5hrtmM0BaPcZE+5EVtpXzMu5UbENu66n6kNMC7lRoqCYsWKkZyc7Oow3HZfUzsgzqD9zLiUG5G8qWgmUggZGRm8++67fPzxxxw9epTSpUtz99138/LLLxMYGOjq8LI4d+kkf+78AS8vb7y8vF0dTqHE7F3JfTN2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RERERERERERExONpeEaRIiighKsjsLBHHOFBhd+GvdgjFuXGMZQb92aUfc2d9jNwr3ZAuZGixCj5dac2ANyrHVBusnKn3Lib6tWrF2i9jIwMzl64BEBYiRAuxF0GoHRYKF5e+b9+u6Bx3MhI+XWndsCd2gAwVixGYJT9DNxrX3OnNgCUG3E/JrPZbHZ1ECIiIuI8cYkwZaHl5yn9oURx18YjIlIYatNERIzn0uUEXps1D4DHhvXjg69/BmDSo/cSGmKgb3pFDEjnNiIirqXhGUVERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj+fj6gBEJP8+XQnnE1wdBYQHweiOhdvGtoWQFGePaAovoAQ06V+4bSg3jmGP3Ig4g1HaAHCvdsCd2mdQbqTo0HHjGGrTsnKn3IiIiHEZpf90p74T3OvcRrkRUNFMpEg6nwCxl1wdhX0kxcGV866Own6UGxHP5k5tALhXO6DciOSfjhvjUm5ERETyz536T3frO5UbMRINzygiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiHgQsxku3DBO+OnLkJ7hunhERArDbIYLV67/fvoSpKW7Lh4RERGRwriaBifjrv9+OclloYiIeCw900xERMTNpaXD9uOw4TBEn4ekq9fnzYoCHy8oXxKaVoZW1SDQ33WxiojkJS0ddsbA+kOWNi3xxjbtD/D2ggoloUklS5sWVMx1sYqIiIjk5UIC/P0P7I6B2MuWi4Kueet3CCkGVctA2xpQKwK8TK6LVUTEE6hoJiJFxhvzR7Js85cAeJm8CAspR5PqnXnwjtcoFVrBxdF5NuXGmMxmS6Fs0TZISM55ubQMyxfP0efhv9uhfW3o2Qh8vZ0WqhRxagOMy51yYzbD5qPwyxa4nEub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no0s/y4lQcx5uHxjm1bScmea2jSxhaccN0WRciMinsDLZLkrvk45SM+AU3GWf1fTwNvL8lmuYpjuKhPbqO80LuWmaFHRTESKlE37l/DnjgWcvniUldvmU718E8b0fQeAGd8O519DvmJv9HrKhVUjNLAUAEO7PM/QLs8D8Mb8kfRu+4g6EQdQboqG0OKWfyKOoHbAuNw1N6EBoCH8xVHc9bhxB8qNiLgjby9LgaximKsjEXekvtO4lBvjMZnNZrOrgxCR/Hl9McRecnUUluEBnu1duG2snQNXztsnnsIKDIe29xduG8qNY9gjN+K+4hJhykLLz1P6W+5CcRWjtAHgXu2AO7XPoNxI7tSmZU/HjTXlxjHUptnPpcsJvDZrHgCPDevHB1//DMCkR+8lNCTIhZGJiDMZ6bwGjNN/ulPfCe51bqPcCICXqwMQERERERERERERERERcTUNzyhSBIUb5MI8e8QRUKLw27AXe8Si3DiGkWIRyY1R2gBwr3bAndpnUG6k6NBx4xhq07Jyp9yIiIhxGaX/dKe+E9zr3Ea5EVDRTKRIGt3R1RHYT5P+ro7AvpQbEc/mTm0AuFc7oNyI5J+OG+NSbkRERPLPnfpPd+s7lRsxEg3PKCIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PB9XByAi+ffpSjif4OooIDwIRncs3Da2LYSkOHtEU3gBJaBJ/8JtQ7lxDHvkRkTyT22aY6i/seZuuRHj0nHjGGrTrLlbbkRExJiM0neCe/Wf7nReA8pNQaloJlIEnU+A2EuujsI+kuLgynlXR2E/yo2IuBO1acal3Ijkn44b41JuRERE8sed+k5wr/5TuSn6NDyjiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIi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IxblxjGMFIuIJ1Gb5hjqb6y5W26qV69eoPUyMjI4e8FySWpYiRAuxF0GoHRYKF4FeAhYQeNwZzpuHENtmjV3y42IiBiTUfpOcK/+053Oa0C5KSgNzygiIiIiIuJiGspMRNyJ2jQREREpqjQ8o4iIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRIqAlJQU7r//fipWrEhoaCidOnVi9+7drg5LRERERAzmzJkz9OjRg+LFi9OgQQPWrVvn6pBERArspZdeol69enh5eTF//nxXhyMiIiIeQEUzkSIgLS2NatWqsW7dOi5cuMCdd95Jv379XB2WiIiIiBjMI488QrVq1Th//jwTJ05k4MCBpKSkuDosEZECqVmzJu+++y6tWrVydSgiIiLiIVQ0EykCAgMDmTx5MhUrVsTb25uxY8dy6NAhzp8/7+rQRERERMQg4uPjWbx4MS+99BIBAQGMGDGC4OBgVq5c6erQREQK5L777qNbt24UK1bM1aGIiIiIh1DRTKQIWrt2LWXKlCE8PNzVoYiIiIiIQRw8eJASJUpQtmzZzGkNGzZkz549LoxKRERERESk6PBxdQAikj9xcXE89NBDTJ8+3dWhiIiIiEgBmc1mlq7exOX4KwBcTU3NnBf11+bMnxf/sRY/X1/LLybocVsrggOLZ7vNK1euEBISYjUtJCSEhIQEO0cvImLNbDaz/K/NxF2ytDc2tWlA9w4tCQkOdF6gIiIiInlQ0UykCElOTqZv37707t2bBx54wNXhiIiIiEgBmUwmqkaW4/MF/80yb9/h45k/79x/JPPnW5rXz7FgBpYhvePj462mXb58maCgIDtELCKSM5PJRLVK5Zn97WLMN83LqU1r1biOCmYiIiJiOBqeUaSISE9P55577iEyMpL/+7//c3U4IiIiIlJItapWpG2z+jYtWzqsBD1ua53rMjVr1uTixYucPn06c9quXbuoV69eoeIUEbFF9UrladeykU3LhpcIoVfntg6OSERERCT/VDQTKSJGjx5NcnIyc+bMwWQyuTocEREREbGDnh1bUzosNNdlvLxMDO7dCT/f3AcKCQ4Opnfv3rzyyiskJyfz9ddfc/nyZTp27GjHiEVEcnZ7hxaULVUy12VMJhN39+6Ev59vrssBpKamkpycTEZGhtXPIiIiIo6iolkOTCYTI0eOdHUYIgAcO3aMOXPmsGrVKkqWLElQUBBBQUGsXr3a1aGJiIiISCH4+fpwd+9OeOVyUVTnW5pRsVxpm7Y3a9YsDh48SFhYGK+//jo//vgj/v7+9gpXRCRXvj4+DO7dCW+vnL9u6timMZUrlLVpe6NHjyYgIIDVq1czfPhwAgIC+PPPP+0VroiIiEgWJrPZfPNw04KlaDZixAi++OILV4ciBnD06FG++OIL+vXrR5MmTVwdThbnLl7Cx9ubEiF6XoWIiIhIUbR8zWaW/7U5y/TIcqV55L6+uX4BLSJiNCvXbeP3VRuyTC9fNpwxw/rh4+3tgqhERERE8qZPXiI2OHr0KFOnTmXbtm2uDiVbi6PW8u+P57N51wFXhyIiIiIiBdCpbdMsd5P5+nhzdx53bIiIGFGHVo2y3E3m4+3N4N6dVTATERERQ9OnL7G7a+OMi3McP3WGfYeiMZvNNg9xISIiIiLG4u3txeBenfD1uf5lcq/ObSkdVsJ1QYmIFJCXlxd39+6E3w3PLetxW6s8n3cmIiIi4mq5P0naII4fP86ECRNYsmQJZrOZ2267jXfeeYcuXbpQpUoVVq5cmbnstWEV77vvPl544QV27NhBSEgIgwcP5tVXXyUoyHr4ut27dzNhwgRWr16Nv78/PXv25O233y5wrNdef/jw4Tz//PNs376dsLAwxo0bx7/+9S8uXrzI008/zaJFi0hISKBz58588sknlC9f3mo7ly5dYvr06fz4448cP36ckJAQunbtyquvvkq1atUyl4uPj2fGjBksW7aMQ4cOER8fT2RkJHfddRcvvvgixYsXz1w2IyODmTNn8vnnn3PkyBFMJhPlypWjXbt2fPTRR/j6+lq9h5uHpvziiy+4//77WbFiRebDxKdMmcLUqVPZtWsXn332GQsWLODUqVNERUXRsWNHUlJSePPNN/nmm284dOgQxYoVo3379rz88ss0bdo0c9srV66kU6dOzJkzh8TERN59912OHTtGzZo1ee211+jduzc7d+5k4sSJ/P333/j6+jJ06FDefPPNzLivOXjwIC+//DLLly/n/PnzlC9fnkGDBjFlyhQCAwMzlxs5ciRffvklcXFxPPvss/z4449cvnyZ5s2b89Zbb9G6dWur9w1w//33Z/582223sXLlSpv/rrlJz8ggISExz+Wyc23Ii/q1quDr7c2lywkF2o6IiIiIuJafrw+d2jZl6epNVI0sR53qkTq3E5Eiy8fLi863NOP3leupXKEs9WtXUZsmIiIiThUUVDzfI3cYvmgWFxdHhw4dOH78OI888gj16tVj1apVdOrUiaSkpGzX2bJlCz/88AOjR49m+PDhrFixgpkzZ7Jr1y6WLVuG1//+SEeOHKF9+/akpKQwduxYIiMjWbRoET169ChUzFu3bmXRokU89NBDDB8+nAULFvDss89SrFgxvvzyS6pUqcKUKVP4559/mDlzJsOHD2f58uWZ61+6dIlbbrmF6OhoHnjgAerXr8+pU6f48MMPad26NZs2baJy5coAnDhxgtmzZzNw4EDuvfdefHx8WLVqFW+88QZbt25lyZIlmdt99dVXefHFF7nzzjt55JFH8Pb25siRI/zyyy+kpKTYVNzJydChQwkICGDChAmZRaPU1FR69OjB33//zbBhwxg7diyXLl3i008/5dZbb+XPP/+kRYsWVtv54IMPuHjxIqNGjaJYsWLMnDmT/v378/333zN69GiGDBlCv379WLp0Ke+99x5lypThhRdeyFx/8+bNdO7cmRIlSvDwww9ToUIFtm/fzsyZM/nrr79YtWpVlvfZvXt3SpcuzYsvvsj58+d566236NWrF0eOHCE4OJgOHTrw3HPPMX36dB566CHat28PQNmyZe32d01ISOS1WfMK/PcH2Ln/CDv3HynUNkRERETEGI4cP8Xrs751dRgiInZx7MRpZqhNExERESeb9Oi9hIYE5b3gDQxfNHvjjTc4evQon3/+eeYdPmPGjGH8+PG8++672a6zc+dOFi5cSL9+/TKXf+KJJ5g5cyYLFizgnnvuAeD555/n4sWL/PHHH3Tq1AmAxx57jAEDBrB169YCx7xz507Wrl2beafSgw8+SOXKlXnyyScZO3YsM2fOtFr+7bffZv/+/dSuXRuAF198kcOHD7Nu3ToaN26cudzIkSNp2LAhL730UuZdYNWqVeP48eNWhZnHHnuMyZMnM23aNDZs2ECrVq0AWLhwIXXr1uWXX36xev3XX3+9wO/1mhIlSrB8+XJ8fK7vUm+//TYrV67k999/p3v37pnTx4wZQ4MGDXj66aet7hIEOHnyJHv27CE0NBSAzp0707hxYwYMGMAPP/zAgAEDAHjkkUdo3rw5H3zwgVXR7IEHHqBcuXJs3LiR4ODgzOldunRhwIABfPPNN4wcOdLqNZs1a8aHH36Y+Xu9evW4++67mTdvHg8//DDVqlWjW7duTJ8+nbZt23LfffdZre/Iv6uIiIiIiIiIiIiIiDiH4YtmP//8M2XLlmX48OFW0//1r3/lWDSrXbt2ZsHsmmeffZaZM2eycOFC7rnnHjIyMli0aBEtWrTILJiBZWjCZ555hp9//rnAMbdt2zazYAbg5+dHq1at+OWXX3j88cetlm3fvj1vv/02Bw8epHbt2pjNZr755hs6dOhAhQoVOHfuXOaygYGBtGnThqVLl1pt+5q0tDTi4+NJT0+na9euTJs2jfXr12cWzUJDQzl06BBr1qyhXbt2BX5/2Rk/frxVwQxg7ty51KlTh+bNm1u9D4Bu3brx5ZdfkpSUREBAQOb0kSNHZhbMABo1akRISAjBwcGZBbNr2rVrx8yZM0lISCAoKIidO3eyY8cOpk6dSkpKCikpKVbLBgYGsnTp0ixFsyeffNLq986dOwOWYR5tYY+/a1BQcSY9em++1jl55jxf/rgEk8nEQ0N6ExYanPdKIiIiIiIiIiIiIiIeICioeN4L3cTwRbPDhw/TsmVLvL29raaXK1eOEiVKZLtO3bp1s0y7tvzhw4cBOHPmDAkJCdSpUyfLsvXq1StUzDc+c+yakiUtD7utWrVqttPPnz8PwNmzZzl//jxLly6ldOnS2W7f66YxOD/88EM++ugjdu/eTUZGhtW8ixcvZv48ffp0+vXrR/v27SlfvjwdO3akV69e3HXXXVbFt4KoVatWlml79+4lKSkpx/cBcO7cOSIjIzN/z+lvd+MyN04Hy98uKCiIvXv3AvDSSy/x0ksvZft6p0+fzjLt5tcMDw/P3K4tHPl3zc2aTTsBaFCrigpmIiIiIiIiIiIiIiKFZPiiWVF0c4HPlnlms9nq/65du/Kvf/0rz9d66623mDBhArfffjuPP/445cuXx8/PjxMnTjBy5EirIlrbtm05dOgQS5YsYcWKFaxYsYJ58+Yxbdo01qxZQ1hYWK6vlZaWluO84sWzVmzNZjMNGzbkrbfeynG9mwtqOf19cvub3vy3mzBhQo7PpbtWaLNl29e2l5fC/l2hcM8007PMRERERERERERERESsueUzzapVq8bBgwdJT0+3Km6cOnWKuLi4bNe5dsfRja4tf+2uotKlSxMUFMS+ffuyLLtnzx77BF8ApUuXpkSJEly+fJmuXbvmufzXX39NlSpV+O2336zuQPv999+zXT4oKIiBAwcycOBAwHKX2mOPPcZnn33GxIkTAQgLC+PChQtZ1r12l56tatasydmzZ+ncuXOWu+McoWbNmoClCGbL3y4/TCZTrvNt+buKiIiIiIiIiIiIiIhxGb5o1rdvX15//XW++uor7r///szpM2bMyHGd/fv38/PPP1s91+za8temeXt707t3b+bPn8+KFSsyn2tmNpt544037P9GbOTl5cXQoUP54IMP+OGHH7jrrruyLHPmzBnKlCkDWN6HyWSyuisqLS2N119/Pct6586do1SpUlbTmjVrBmBVJKtVqxZr164lMTEx8w6yixcvMmfOnHy9l+HDhzNx4kTeeustnn766SzzT58+TdmyZfO1zdw0bdqUBg0a8NFHH/Hwww9nGXYxLS2Ny5cv23Tn182CgizV6OyKibb+XXPfvu3PNNOzzEREREREREREREREcueWzzR75plnmDdvHqNHj2bz5s3Ur1+flStXsnbt2iyFimsaNmzIfffdx+jRo6lZsyYrVqzghx9+4LbbbmPw4MGZy02bNo3ffvuN3r17M27cOCpWrMiiRYs4e/ass95etl599VX++usv7r77bu6++27atGmDn58fx44d47///S/Nmzfniy++AOCuu+5i0qRJ9OzZkwEDBnD58mXmzZuHr69vlu3WrVuXNm3a0Lp1a8qXL8+pU6f45JNP8PPz45577slcbuzYsdx333107tyZYcOGERcXx6effkrlypWJjY21+X088cQTLFu2jIkTJ/LHH3/QuXNnQkJCiI6OJioqimLFirFixYpC/72uMZlMfP3113Tu3JlGjRrxwAMPUL9+fRITE/nnn3/46aefeO211xg5cmS+t12vXj2Cg4P58MMPKV68OCVKlKBMmTJ07tzZ5r9rbry9vGy+TXTh0jUANK1fk6qR5fL9XkRERETk/9u7f5fWzjCA409EkQv+QC6IiEOIS3HRCooUIaCTf4GDQxQcBSXiIIo66aSDiri4mEXcFHRVCBmc3Du02IKLlIvtIA5iN6nc1loq6vX9fMbw5PDkkO3Lew4AAAB87d1Hs6ampiiXy1EsFmN3dzciIvL5fJycnMTg4ODffqe7uzvW1tZibm4utre3o6GhISYmJmJ5efnRYwLb29ujXC7H9PR0bGxsRG1tbQwNDUWpVHrRE1D/VWNjY1QqlVhdXY39/f04ODiI6urqaGtri/7+/hgfH3+YnZmZifv7+9jZ2YnJycloaWmJ4eHhGBsbi46OjkfXnZ6ejuPj41hfX4/r6+tobm6Ovr6+mJ2djc7Ozoe5kZGRuLy8jM3NzSgWi5HL5WJhYSGqqqri7Ozs2b+jpqYmjo6OYmtrK0qlUiwuLkZERGtra/T29kahUPifd+prXV1dcX5+HisrK3F4eBjb29tRX18f2Ww2RkdH//E/828+ffoUe3t7MT8/H1NTU3F7exv5fD4GBgaefV9fwpfrP+LHn3+NqkwmBn74/kWvDQAAAAAAKcvc//W5ft+YbDYb2Ww2Tk9PHz7LZDJRKBQeTmLBR/Pbl9/jp18uo6fzu7deBQAAAAAAPox3f9IMeOxzU0N8bmp46zUAAAAAAOBDEc2e4erqKu7u7p6cqauri7q6572TCgAAAAAAgPdFNHuGnp6euLi4eHJmcXExlpaWXmchAAAAAAAAXtQ3/U6z11KpVOLm5ubJmVwuF7lc7pU2AgAAAAAA4CWJZgAAAAAAACSv6q0XAAAAAAAAgLcmmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeX8C7OsU8pAAnfAAAAAASUVORK5CYII=", + "image/png": "iVBORw0KGgoAAAANSUhEUgAABs0AAAE2CAYAAAAqK9xEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACMWElEQVR4nOzdd3gU5drH8e+mEtIgoYQSeu+9KCBVQBApIgJSVLAgKIp4REVBEcXz2rBgQbEgIhY8gkcpERCU3jtICwFCDySkkLLvH3sILGmbZMtk9/e5Li6SaXtv7pnnmd175hmT2Ww2IyIiIiIiIiIiIiIiIuLBvFwdgIiIiIiIiIiIiIiIiIirqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgOK5p17NiR8ePHO3wdo25DREREREREREREREREio4CFc1iY2N54oknqFGjBsWKFaNs2bLceuutzJo1i8TERHvHaFcjR47EZDJhMpnw8/OjRo0avPzyy6Slpbk6NIe5//77eeGFF7JMf/311zGZTCoQioiIiIiIiIiIiIiIx/PJ7wqHDx/m1ltvpUSJEkyfPp2GDRvi7+/Pzp07+eSTT6hQoQJ9+vRxRKx206NHD+bMmUNKSgr//e9/eeyxx/D19WXSpEmuDs3u0tPTWbx4Mb/++qvV9I0bN/Lxxx/TqFEjF0UmIiIiIiIiIiIiIiJiHPm+02zMmDH4+PiwadMm7rnnHurWrUu1atW46667+PXXX7nzzjuzXS8lJYXHH3+cMmXKUKxYMdq1a8fGjRuzLJeWlsbYsWMJDQ2lVKlSTJ48GbPZDMDvv/9Ou3btKFGiBOHh4fTu3ZtDhw7l9y3g7+9PREQElStX5tFHH6Vr16788ssvVstkZGTwzDPPEBYWRkREBFOmTMmcZ0scP/zwAw0bNiQgIIDw8HC6du3KlStXMrf92muvUbVqVQICAmjcuDE//PBDvt9H3bp1M++au/nf+++/D8Dff/+Nr68vLVu2zFwvISGBoUOH8umnn1KyZMl8v66IiIiIiIiIiIiIiIi7yVfR7Pz58yxdupTHHnuMwMDAbJcxmUzZTn/mmWf48ccf+fLLL9myZQs1atSge/fuXLhwwWq5L7/8Eh8fHzZs2MC7777LW2+9xezZswG4cuUKTz31FJs2bSIqKgovLy/69etHRkZGft5GFgEBAVy9ejVLHIGBgaxfv5433niDl19+mWXLltkUx6lTpxg8eDAPPPAAe/fuZeXKlfTv3z+z+Pfaa6/x1Vdf8dFHH7F7926efPJJ7rvvPlatWpX5+l988UWOf8trfvzxRwCioqI4deoUR48excvLi++//57Ro0cD8Msvv3DnnXdabeuxxx6jV69edO3atVB/NxEREREREREREREREXeRr+EZ//nnH8xmM7Vr17aaXqpUKZKTkwFLQWbGjBlW869cucKsWbP44osv6NmzJwCffvopy5Yt47PPPmPixImZy0ZGRvL2229jMpmoXbs2O3fu5O2332b06NEMGDDAaruff/45pUuXZs+ePTRo0CA/bwUAs9lMVFQUS5YsYdy4cVbzGjVqxEsvvQRAzZo1ef/994mKiqJbt255xnHq1CnS0tLo378/lStXBqBhw4aA5Y676dOns3z5ctq2bQtAtWrVWLNmDR9//DG33XYbAKGhoVn+zjc7ffo0Pj4+3Hrrrfj7+7N582YyMjJo3749/v7+APznP//h7bffzlxn/vz5bNmyJdu7/ERERERERERERERERDxVvodnzM6GDRvYtm0b9evXJyUlJcv8Q4cOkZqayq233po5zdfXl1atWrF3716rZdu0aWN1V1Tbtm05ePAg6enpHDx4kMGDB1OtWjVCQkKoUqUKANHR0fmKd/HixQQFBVGsWDF69uzJoEGDrIZfBLI866tcuXKcOXMGIM84GjduTJcuXWjYsCEDBw7k008/5eLFi4Cl8JiYmEi3bt0ICgrK/PfVV19ZDfHYr18/9u3bl+v72LlzJ7Vq1coskG3fvp0yZcpQtmxZAPbu3cvJkyfp0qULAMePH+eJJ57gm2++oVixYvn6m4mIiIiIiIiIiIiIiLizfN1pVqNGDUwmE/v377eaXq1aNcAyzKEj3XnnnVSuXJlPP/2U8uXLk5GRQYMGDbIMrZiXTp06MWvWLPz8/Chfvjw+Pln/DL6+vla/m0ymzOEX84rD29ubZcuW8ffff7N06VLee+89nn/+edavX09CQgIAv/76KxUqVLB6jWvFL1vt2LEj8w42sBTNbvz9l19+oVu3bpkFss2bN3PmzBmaNWuWuUx6ejp//vkn77//PikpKXh7e+crBhEREREREREREREREXeQrzvNwsPD6datG++//z5Xrlyxeb3q1avj5+fHX3/9lTktNTWVjRs3Uq9ePatl169fb/X7unXrqFmzJnFxcezfv58XXniBLl26ULdu3cy7t/IrMDCQGjVqUKlSpWwLZrk5f/68TXGYTCZuvfVWpk6dytatW/Hz82PhwoXUq1cPf39/oqOjqVGjhtW/yMjIfMWyY8cOqzvitm/fbvX7f/7zH+66667M37t06cLOnTvZtm1b5r8WLVowdOhQtm3bpoKZiIiIiIiIiIiIiIh4rPxVjIAPP/yQW2+9lRYtWjBlyhQaNWqEl5cXGzduZN++fTRv3jzLOoGBgTz66KNMnDiRsLAwKlWqxBtvvEFiYiIPPvig1bLR0dE89dRTPPzww2zZsoX33nuPN998k5IlSxIeHs4nn3xCuXLliI6O5tlnny34Oy8gW+JYv349UVFR3H777ZQpU4b169dz9uxZ6tatS3BwME8//TRPPvkkGRkZtGvXjkuXLvHXX38REhLCiBEjAFi4cCGTJk3KcYjGjIwMdu/ezYsvvpg57dChQ/Tv3x+AM2fOsGnTJn755ZfM+cHBwVme/RYYGEh4eHiBngknIiIiIiIiIiIiIiLiLvJdNKtevTpbt25l+vTpTJo0iZiYGPz9/alXrx5PP/00Y8aMyXa9119/nYyMDIYNG0Z8fDwtWrRgyZIllCxZ0mq54cOHk5SURKtWrfD29uaJJ57goYcewmQyMX/+fB5//HEaNGhA7dq1mTlzJh07dizQGy8oLy+vPOMICQnhzz//5J133uHy5ctUrlyZN998k549ewLwyiuvULp0aV577TUOHz5MiRIlaNasGc8991zmNi5dupRlGMwbHTp0iMTERKs7yxo2bMhLL71E8+bN2bdvH61ataJUqVL2/yOIiIiIiIiIiIiIiIi4GZPZbDa7Ogixvz59+tCuXTueeeYZV4ciIiIiIiIiIiIiIiJiePl6ppkUHe3atWPw4MGuDkNERERERERERERERKRI0J1mIiIiIiIiIiIiIiIi4vF0p5mIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj6eimYiIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHs/H1QGISP5tWwhJca6OAgJKQJN+hdvGpyvhfII9oim88CAY3bFw21BuHEO5cW9G2dfcaT8D92oHlBspSoyyr7lTGwDu1Q4oN1m5U27cTZ8+fTh06JCrw6B69er88ssvhdqGUfYzcK92wJ3aAFA7cDOj7GfgXvuaO7UBoNyI+1HRTKQISoqDK+ddHYV9nE+A2EuujsJ+lBvjcqfcuBt32tfcbT9TbkTyz532NXdqA0C5MTJ3yo27OXToEHv27HF1GHbhbvuZO7UD7pYbd+JO+xm4176m3Ig4joZnFBEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8Xg+rg5ARBznjfkjWbb5SwC8TF6EhZSjSfXOPHjHa5QKreDi6DybcmNcyo04i/Y141JuxBm0nxmXcmNcyo04i/Y141JuxBm0nxmXciPOoDvNRNxcw6rt+W7yKb55PppJQ+bxz8mtvPL1QFeHJSg3RqbciLNoXzMu5UacQfuZcSk3xqXciLNoXzMu5UacQfuZcSk34mi600zEzfl4+xEWEgFAqdAK9Gr9EB/853GuJF8msFiIi6MruPS0q7w/0r/A6z8x12zHaApGucmeciO20r5mXMqNiG3cdT9TG2Bcyo0UBcWKFSM5OdnVYbjtvqZ2QJxB+5lxKTcieVPRTKQQMjIyePfdd/n44485evQopUuX5p577uHll18mMDDQ1eFlce7SSf7c+QNeXt54eXm7OpxCidm7kvtm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iIiIiIiIiIiIiMfT8IwiRVBACVdHYGGPOMKDCr8Ne7FHLMqNYyg37s0o+5o77WfgXu2AciNFiVHy605tALhXO6DcZOVOuXE31atXL9B6GRkZnL1wCYCwEiFciLsMQOmwULy88n/9dkHjuJGR8utO7YA7tQFgrFiMwCj7GbjXvuZObQAoN+J+TGaz2ezqIERERMR54hJhykLLz1P6QYniro1HRKQw1KaJiBjPpcsJvDZrHgCPDevLB1//DMCkR4cQGmKgb3pFDEjnNiIirqXhGUVERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj+fj6gBEJP8+XQnnE1wdBYQHweiOhdvGtoWQFGePaAovoAQ06Ve4bSg3jmGP3Ig4g1HaAHCvdsCd2mdQbqTo0HHjGGrTsnKn3IiIiHEZpf90p74T3OvcRrkRUNFMpEg6nwCxl1wdhX0kxcGV866Own6UGxHP5k5tALhXO6DciOSfjhvjUm5ERETyz536T3frO5UbMRINzygiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiHgQsxku3DBO+OnLkJ7hunhERArDbIYLV67/fvoSpKW7Lh4RERGRwriaBifjrv9+OclloYiIeCw900xERMTNpaXD9uOw4TBEn4ekq9fnzYoCHy8oXxKaVoZW1SDQ33WxiojkJS0ddsbA+kOWNi3xxjbtD/D2ggoloUklS5sWVMx1sYqIiIjk5UIC/P0P7I6B2MuWi4Kueet3CCkGVctA2xpQKwK8TK6LVUTEE6hoJiJFxhvzR7Js85cAeJm8CAspR5PqnXnwjtcoFVrBxdF5NuXGmMxmS6Fs0TZISM55ubQMyxfP0efhv9uhfW3o2Qh8vZ0WqhRxagOMy51yYzbD5qPwyxa4nEubln5Tm9auFtzRGPz0yUds5E7HjbtRbkTEnSQkw8LNsOUomHNZ7nIybI+2/CsdDANbWYpnIrZS/2lcyo0xaXhGESlSGlZtz3eTT/HN89FMGjKPf05u5ZWvB7o6LEG5MZqEZPh0JXy7LveC2c1S0+GPPfDv/0LMBYeFJ25IbYBxuUNurqTAZ3/C3L9zL5jdLC0DVu6ztGnR5x0Xn7gfdzhu3JVyIyLuYHcMvL7YckFQbgWzm52Nhw+j4IcNGpJa8kf9p3EpN8ajopmIFCk+3n6EhURQKrQCjap1oFfrh9hzbC1Xki+7OjSPp9wYR3wSvLcM9pws+DbOXIb3l8ORs/aLS9yb2gDjKuq5SUi2tEe7Ygq+jbPxlm0cOm2/uMS9FfXjxp0pNyJS1G08DLP/hISUgm9jzUGYvUqFM7Gd+k/jUm6MR4OUiHiQ9LSrvD+y4A8remJufq5/crxzl07y584f8PLyxsuraI8jp9yIvaSmw0cr4HQu51ZeJgj+3zN+4pMhI4fdJzkVPl4BE3pA6RD7xyrXqQ0wLuXGtdLS4ZOVcCou52VsbdOuplm29WQPiAi1c6BiRceNcSk3IiKutfckzFtn/dyym9l6brPvFHyzFobfCiY958yh1H8al3IjjqCimUghvPbaa2zZsoXNmzdz5MgRKleuzNGjR10dVo5i9q7kvhm7Ca9Qz9WhFNj2wyu58/kgzOYMUlKTALi7wwQC/AIBWLNzIV8vm2q1TvSZPYzp8y533vKo0+O1lXJj3NwUNb/tgBMXc18muBhM7W/5+aWf4FJSzssmp1o+1I3rCl66P91h1AYYtw1Qblybm6W78h5WMT9tWkoazFsLT9wO3mrTHEbHjdo0R3LX3IiI+0tMgfl5FMwgf+c2W49Bg4rQvIrdwpRsqP80bv+p3Bg3N0WZimYihfDcc88RFhZGs2bNiIuLc3U4ebpwYi+VG97u6jAKpU5ka56590uupiWzavsCth5czv09pmXOb9ewH+0a9sv8/a9dP/P5b8/RrcUIV4RrM+VG7CHmAqzYa//tHjkLf/8D7WrZf9uFZTZD7CXLFZj+PlAxrGh+Ea42wLiUG9eJvQTLd9t/u9HnYfUB6FjH/tsuLLPZcqfw5STw84GKJcGnCF5gquPGuJQbERHXWbwt9wJYQf24EeqWh+J+9t92YaWkWi7qTM+AsCAID3J1RAWj/tO4lBtxBBXNRArh0KFDVKtWDYAGDRqQkJDg4ojcn79vABVK1QCgakQDTp0/xPs/j+OpgZ9mWfZsXAzvLXyM6Q/+RjG/4s4O1eMoN6735/68r1osqJX74JaalqFCjMBstjw0e8UeOBF3fXpIgCXOLvXAtwh+0VyUqQ0wrqKamz/35TwcUWGt2gcdahnrDtrNRy0XPsRcuD4tuBi0rQFd61uKaOI8RfW48QTKjYgURQnJsOGwY7adeNXynLTbDHRBUHyyZcSADYcsd/pfUyvCcl5TK8J1sXkq9Z/GpdwYj4E+Joon2b59O3fddRehoaGEhITQt29fTp06RXBwMPfee6/dXmf8+PH8/vvvuS6zYMECLl7MYyyzHFwrmBUFF07uI6y8gc6g7GRYtyks2TSH/cc3WU3PyMjg9W/v495Oz1KtfCMXRWcb5Ubs4UqKZWgORzkXDwdiHbf9/DCb4ZetMPdv64IZWO7O+H0HzPrD8vyiokBtgHEpN66TnAqbjjpu+xevWJ4pYhS/boOv/7IumMH1L5w+jLJcqV0U6LgxLuVGRMR1NhyGtAzHbX/NAcddQJlfcYnw9u+wer91wQwsnyk/jIJ1h1wTW0Go/zQu5UYcRUUzcbqoqCjatGnD/v37eeGFF5g+fToxMTH07NmThIQEmjRpYrfXevfdd1m3bl2O80+cOMHIkSPp2rVrgQtnRcWJvauoULejq8Owu4qla9K27p3M+f15q+nfRE2jeLEQ+rYb56LIbKfciD0cPgOp6Y59jf2nHLt9W209lvcwlIfPwM9bnBNPYakNMC7lxnWOnHV84XufQdq0HcdhWR7DUB49Bz9uyn0Zo9BxY1zKjYiI6zj6vONsvOWiICP4cg1cyCOW79bn/Sxuo1D/aVzKjTiKimbiVGfPnmXQoEE0a9aMrVu3MnHiRMaOHUtUVBTR0dEAdi2a5aVChQr89NNP7N69m27duhWJ55IVVFpqMj6+/gCYzWZ+nN6F71/pgDnD+lKnRW/dxbeTW5CeVkQuZwYGdpzI5gNL2X5oJQC7jvzF7xs+Y+I9c1wbmI2UG7GH4xfyXqYovIYtVu6zbbkNhywP2zY6tQHGpdy4jie1aatsbNM2H7XceWZ0Om6MS7kREXENs9lzzm2iz1sufsqL2Wy5E60oUP9pXMqNOIpGxhenmjFjBhcvXmTOnDkEBARkTg8NDaVZs2ZERUXZvWi2fPlykpNz/4ahefPm/P3333Tr1o0VK1YQFOTcJ5OmpaURG2v7uGepqWUB39yXSUnE198ytm1K4mX8i5fInGcymbj94S/55rlGbFo8g5Z9JgGwM+pjonctY/C0LXj75L59SxypxMSctjnu7LeR93u55pl7v8h2ev0qt7Ds35ZxCBKS4pgxfxgTB31BSGB4PmNxzvtRblyTG3d3NDYMuD6etZfJ8iyc7IQEZP/zzeKTrZ8ndPJCOjExrr01Iy7Jm+jz5WxaNi0DVu24QMNyiQ6O6jqjtAGWWJzXDhSFNkC5sWak3GTnyKmSQGDm745o007FZRAT49oxGuNTvDl0xrY2LT0DVu24SJPyzruMXMeNNSMdN8qNNSPlRiwSEpMyfz5z9vrf9FTsKeIv59JYi7ihK1e9SLpa3mpaYc9tbj6vAThw/BLhXvGFiLTwVv0TCgTbsKSZTUfM3FrhJCYnPjfbKP2nvrPJbhvKzY2MlJuiLiIiAh+f/JXBVDQTp5o/fz7t27enVq1a2c4vW7YsERGWp4EuWLCAmTNnsm3bNkqVKsXRo0cL9Jrr1q1j06bcx7PJ+N8VCNu3b+fs2bNOL5rFxsYSGRlp8/L3vb6L8Ir1s52XkZ7GX99NwtvXn1sGTgMgetdSKjXsZrVccHhFOt8/iyWzhlG5UQ98/Yrz57ynaDf43zaPB3zgwAEi+zewOe7sfDphF1Uisn8vBbFo7SwuXD7FrF+etJp+e4sRDOjwZA5rWRw4cIDbHi7c+1Fucubq3Li7PhMWUbVp78zfg4vB1P55rzehZ87zXvoJLl3/voOLlxLy1VY5QkT11gyamvOwuzeb/PIMNi9+w4ERWTNKGwDGawdc3QYoNzlzdW6y0+vxH6jRakDm745o064kXnV5m1a6chOGvLrV5uVfee1tNvz8igMjsqbjJmeuPm6Um5y5OjdiERxSgjHPzQCgd687GTHuOQBatWxF/OU4F0Ym4nwhpatw/9tHrKYV9tzm5vMagLfffZ97vn+hgFHaR/dH51Ln1qE2LGkiLcNEtZq1SUtx3kWORuk/jdZ3guv7T+UmZ67OTVF3/PhxKlasmK91VDQTp4mNjeXEiRMMGjQoy7yMjAx27txJ06ZNM6eVLFmSsWPHcvr0ad5+++0Cv+4LL7zAlClTcpyfkJBAz549Wb9+Pd999x1Vq1Yt8GsZgZe3D20GTGXh610zp125eJKgkuWzLFurzSAOb1nEkg+H4uNfnAq1O9C422PODNfuBneexODOk1wdRraUG+Pmxh2kp111i9fIy9Wky/laPjXZtVda3khtgHHbAOXGeLlJT3dCm+aE18iL2rSiy4jHzTXKjXFzIyKeyVmfozKK2Oe1jPQ00q4m5b2gk6j/NG7/qdwYNzfuSkUzcZorVyxDyZiyue/6P//5D2fOnLEamrFbN8vVAj///LPDYrq5YNavXz+HvVZuIiIiOH78uM3Lz9lYlvO5XIjj61+cgJAyXD4XTXB4JCZTzo8v7DTifWY/XgGTyYs+ExbnJ2xq1aqVr7izc/i/Zbmav++LHMYe70e5cQx7vB93t/JQKJtirv8en2y5+jA7IQHXr1h88ze4nMPnlJufnVO9QojL82A2w+cbU7mY5APkPo6HCTPfzppMSLHnnBMcxmkDwL3aAXdqn0G5scWaIyGsi77+uyPatMjSxQzRpn2xKZXziXm3aWDmq5nPUCJggjNCA3TcOIratKzcKTdikZCYxBcLVwCw+NdFfP/7WgA2bNxAUHENzyieJcMMM9dkkJZxvS0u7LlNds85ffn5J6g3c7QdIi64Ixf8+XGnbcvWLnuV49HReS9oR0bpP92p7wT3OrdRbtzPtVHt8kNFM3GayMhIvL29WbVqldX0Y8eOMW7cOAC7P88sL+np6ZhMJpcWzAB8fHzydZuo77a8l6napDdHti6mbNXmlK3WMsfl9v01F8xm0q4mcubIZqo27WV7HL6++b699WbHfcH110JZ2OP9KDeOYY/34+7qpWFVNMswZx2uIzuXk2xbDqB6hL8h8tDxCizcnPdyDSNN1Kth27OC7MUobQC4VzvgTu0zKDe2qGfGqmjmiDatWlk/Q7RpnZPh+w15L1evvIkGNdWmFYY7HTfKjWPonNN+Ll1OyPy5TOmymT+XiyhHaIhzH4cgYgSRYXDk3PXfHXFu07hGGGVDwwoWoJ2UrwCrjsI5G26O79a4OBUjiue9oB0Zpf90p74T3OvcRrkRgJxLsiJ25ufnx/Dhw9m0aRN33XUXn3zyCZMnT6Z169aEh1seYmjvopnZbM51aMbQ0FBWrVpV4ILZ119/zbRp05g2bRpnz57l0qVLmb9//fXXBYzaPqo26cWRbYs5fXgjZau3ynaZCyf2smb+M9w27F0ad3+c5bNHkRR/LttlxX6UG3GEamVw+AOUq5fNexlnaFcLGuRxzhcWCHfnfA7tUmoDjEu5MY6qpcHLwW1aDYO0aW2rQ+NKuS9Tojjc09o58eSXjhvjUm5ERIzD0ecdIcWgdIhjX8MWXiYY2Q7887hNo0s9qJX/mz+cQv2ncSk34iwqmolTzZw5k4ceeoj169czYcIE1q9fz8KFCylfvjzFixenVq1aTo8pu+EibfXZZ58xefJkJk+ezJkzZ4iLi8v8/bPPPrNjlPkXWLIcqUnxpF5NzPY9pqelsmTWfUTW70qDTqO59Z7XCAgOJ+rzh10QrWdRbsQRShSH+hUct/2gYtDQIBcneXvB/e0tH7SK+VrP8zJBk0rwZHfLsCZGpDbAuJQb4wguBo0iHbf94n55F6qcxcsLht8KtzeAgJvaNJMJGkda2rQSzr0Q22Y6boxLuRERMY42NfIeiLkw2tZ0/AVHtqoYBk/cnn1RLDQABrSA3k2cHpbN1H8al3IjzqKimThVUFAQH3/8MbGxscTHx7N06VLatm3Lrl27aNiwIV5eRWuXXLlyJWazOdt/K1eudHV4VGrYjdAy1bKdt+7HF4m/EEPXUbMB8PErRvdH53JkyyL2rv7KmWF6JOVGHKFDbcdt+9aa4OPtuO3nl7cX3NkUpva3vqPsyR4wsj0EG7Rgdo3aAONSbozDkW1a2xrga7A27Y7GljZt4A0XzT7ZHe7vAKEGLZhdo+PGuJQbERFjCA/Ke7SMgvLxspzbGEn5kjCmCzzW9fq0IW3hxb7QvrbjR0kpLPWfxqXciDMUrQqFuKW4uDhiYmKyDM2Ynp5OcnIyqampmM1mkpOTSUlJcU2QRVT9jqOo3KhHlukn9q9h86//puuo2RQPLZM5vXTlJrQZMJWVXz/O5XPOfRirp1FuxBFqRUDzKvbfbulgy11dRuTvY/3hM7iY62LJD7UBxqXcGEe1MtAq+8/DhRIeZLmry4j8fKzvGjbqHbM303FjXMqNiIhx9Gue97CFBXFHY+PekV46+PrPtSIsFwoVBeo/jUu5EWdwQFMtkj87d+4Esj7P7Ouvv+b+++/P/D0gIIDKlStz9OhRJ0ZXtAWVLJ/t9Aq12/H4V2nZzmvZZxIt+0xyZFiFcjR2N+/8+DBeJi+8vXx4auBsyoVf/0ZtX/QGPv31GQCSUuIxY2bW+C0AxJw9wKj/q89bY1ZTr3Ibl8R/jXJj3NwUdf1bwD+nc39YdHwyvPTT9Z9z42WyXBHopzMGu3LHNgDcox1QboyVm77N4WAsXEzMeZn8tGkmE9zbBvx9c19O8kfHjbGOmxspN8bNjYh4nrAgy7nNd+tzXy4/5zZVS0HHOvaJT65zx/7TXfpO5ca4uXEn+gpMXC6notnIkSMZOXKk8wMSQwsNKs2rD/xKYEAoG/f9ztzlrzBx0JzM+XUqteLNR1cC8NPqd0hJvV45mLv8FRpVu83ZIXsM5cYYAv3hkc7w/nK4ksPNuRnm3Itq15hMcN8tULW0fWMU96V2wLiKam6K+1natPeWQ0IOXxrZ3KYBg9tAzbJ2DVHcWFE9bjyBciMiRVXbGnAhAZbtznkZW89tIkLhwdssz0cVyYv6TuNSboxHzaq43JgxYzCbzbRpo2q45K1kUBkCA0IB8Pb2xcsr5weS/LF1Hp2aDAZgb/R6woIjKBXqoEHERbkxkHIlYFw3KBNS8G0E+MED7aFZFXtFJZ5A7YBxFeXclA2FJ7pZvhgqqGK+MKK9Y4Z7FPdVlI8bd6fciEhRdkdjuKuZZVSPgqpR1vKZL6iIDE8vrqe+07iUG+NR0UxEiqSU1CS+WvoS/ds9ke38mLMH8PH2IyKsCgDzol7l3k7POjFCz6XcGENEKDzdEzrVzf9DlutXgGd7QcNIx8Qm7k/tgHEV1dyUDrG0aV3r5/8Lpjrl4F+9oEklx8Qm7q+oHjeeQLkRkaLIZLJ8TpvQEyqWzN+6fj4woAWM6WIZZUQkv9R3GpdyYxwanlFEDCcpJYFnPumaZXrPVqO4o/Uo0tPTeO2bIQy87WmqlmuY7TaitnxD56ZDAFi/91dqVWxBSGC4Q+P2BMpN0eLnY7mCsUNtWPsPbDgMcTk8F8jfB5pUhnY1IVLpkFyoHTAud8+Njzf0bgLtav2vTTuU87PO/H2gcSXLspWMEb4YlLsfN0WZciMi7q5CSXiqJxyIhTUHYN9JSMvIftmIUGhTA1pVheIqlkkO1Hcal3JTtKhoJiKGE+AfxHvj1mU7z2w28+b3o2heuzu3Nuib4zZW7VjA22NWA/DPyW3sOLSSSUf/5kjsTmLO7uelET8RHlLOEeG7NeWmaCoZaBkC5I7GcCkRjl+wPFA6wwwBvlAhDEoHF254EPEcageMy1NyU6I49Gxk+XcpCWLOw+Ub27SSljvT1KaJLTzluCmKlBsR8QReJstd8XXKQXoGnIqz/LuaBt5els9yFcN0V5nYRn2ncSk3RYuKZiJSpGzav4Q/dyzg9MWjrNw2n+rlmzDmrncAmPHtcP41+Cv2Rq+nXFg1QgNLATC0y/MM7fI8AG/MH0nvto+oE3EA5aZoCC1u+SfiCGoHjMtdcxMaABrCXxzFXY8bd6DciIg78vayFMgqhrk6EnFH6juNS7kxHpPZbDa7OggRyZ/XF0PsJVdHYRke4NnehdvG2jlw5bx94imswHBoe3/htqHcOIY9ciPuKy4Rpiy0/Dyln+UuFFcxShsA7tUOuFP7DMqN5E5tWvZ03FhTbhxDbZr9XLqcwGuz5gHw2LC+fPD1zwBMenQIoSFBLoxMRJzJSOc1YJz+0536TnCvcxvlRgC8XB2AiIiIiIiIiIiIiIiIiKtpeEaRIijcIBfm2SOOgBKF34a92CMW5cYxjBSLSG6M0gaAe7UD7tQ+g3IjRYeOG8dQm5aVO+VGRESMyyj9pzv1neBe5zbKjYCKZiJF0uiOro7Afpr0c3UE9qXciHg2d2oDwL3aAeVGJP903BiXciMiIpJ/7tR/ulvfqdyIkWh4RhEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj6eimYiIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE4/m4OgARyb9PV8L5BFdHAeFBMLpj4baxbSEkxdkjmsILKAFN+hVuG8qNY9gjNyKSf2rTHEP9jTV3y40Yl44bx1CbZs3dciMiIsZklL4T3Kv/dKfzGlBuCkpFM5Ei6HwCxF5ydRT2kRQHV867Ogr7UW5ExJ2oTTMu5UYk/3TcGJdyIyIikj/u1HeCe/Wfyk3Rp+EZRURERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8Xh6ppmIiIgUOQnJ8M9piL4AMReuT1+8DWqUheploHSwy8ITEcmXKylw8DQcPw/Hb2rTqpeBamWgbIjLwhMRERGxmdkMMRfh6Fk4dOb69PnroHIpqBQGNSLAX99Ki4hBqXkSERGRIuP4BVi1F7ZGQ3pG1vmbjlj+AdQsC+1rQ8OKYDI5N04REVucuAgr98HWo5CWR5tWvQx0qA2NItWmiYiIiPGkZ8CGw7D6AJy8mHX+vlOWfwDFfKFVNbitDoQHOTdOEZG8qGgmIkXGG/NHsmzzlwB4mbwICylHk+qdefCO1ygVWsHF0Xk25UYcLTUdftsBK/Zarly0xcHTln/1K8A9rSC0uGNjFPehNs243CU3aemwZCdE7YEMG9u0Q2cs/+qUg0GtoWSgY2MU9+Eux407Um5ExF2cvAjz1lmPApKb5FT4cz+sOwR3NoFba4GXLgoSG6jvNC53yo2eaSYiRUrDqu35bvIpvnk+mklD5vHPya288vVAV4clKDfiOPFJ8O4S+GOP7QWzG+0+ATN+haPn7B+buC+1acZV1HOTkAwzl8Gy3bYXzG6075SlTTt8Ju9lRa4p6seNO1NuRKSo23IU3vzd9oLZja6mwY+b4PM/LRdKithCfadxuUtudKeZiAdJT7vK+yP9C7z+E3ML8M2Onfl4+xEWEgFAqdAK9Gr9EB/853GuJF8msFjRfdiHciOSvSsp8EEUxF7KeRkvEwQXs/wcn5z9l9CJV2FWFDzWFSqFOyZWuU5tmnEpN66VeBU+/CP7IYuusaVNS06Fj/6AR7tA1dKOiVWu03FjXMqNiIhrbT0GX/8FObWmtpzXAOyKgTl/woO3gbdu8XAo9Z3GpdwYh4pmIgV04MAB5s6dy9KlSzl06BDJyclUr16dgQMHMn78eAIDjTdmTszeldw3YzfhFeq5OhS7OHfpJH/u/AEvL2+8vLxdHU6hKDciWZnN8O263AtmYPkQNrW/5eeXfoJLSdkvl5JmuYLxX70gwM++sYo1tWnGpdy41oL1uRfMwPY27Wo6zFkNz/aC4gX/bC020HFjXMqNiIjrnL4M36zNuWAGtp/XAOw5aRm++o7Gdg1TbqK+07iUG+NQ0UykgD7//HM++OAD+vTpw9ChQ/H19WXFihW88MILLFiwgHXr1hEQEODqMK1cOLGXyg1vd3UYhbL98ErufD4IszmDlFTL2dbdHSYQ4GcpUq7ZuZCvl021Wif6zB7G9HmXO2951Onx2kq5MW5uxHU2H7VccWhPcYnwny1wbxv7blesqU0zbpum3LguN9uOwbZo+27zchL8tBnuu8W+2xVrOm7UpjmSu+ZGRNxbRgZ8u9bynFZ7Wr4bGlaESI0O4jDqO43bdyo3xsmNimYiBXT33XczadIkQkNDM6c98sgj1KxZk1dffZXPPvuMsWPHujBC91QnsjXP3PslV9OSWbV9AVsPLuf+HtMy57dr2I92Dftl/v7Xrp/5/Lfn6NZihCvC9SjKjdhTegYs2uqYba87BB3rQkRo3ss6U1wi/H3Q8uy1DDOUDoa2NTScpKuoTTOuopibjAz4j4PatE1HoGMdqBjmmO0X1KVEWPsPHD5radNKBV1v00wmV0fneYriceMplBsRKYp2HHfMM6MzzLBoG4zpYv9tF0aGGQ7GwobDls9tvt5Qpxy0qqY7/l1BfadxuUtuNEqsuMT27du56667CA0NJSQkhL59+3Lq1CmCg4O599577fY648eP5/fff891mQULFnDxYh7j5GSjRYsWVgWzawYNGgTArl278r1NR7pwch9h5eu4OoxC8/cNoEKpGlSNaMDI7i8TEVaV938el+2yZ+NieG/hYzw/dD7F/Io7OVLbKTfGzY24zq6Y3IfuKKy/Djpu2/llNsNvO2Dqz7B0FxyIhX9OW75sfut3+HSl5flFRYXaNOO2acqN63Kz9yRcvOK47RutTVu2C6b8DL/vvN6mrTsEby+Bj1dA0lVXR2k7HTdq0xzNHXMjIu5vjQPPPQ7EwpnLjtt+fsUlwpu/waw/LKOhHDoD+07Bz1vgxYWw8bCrI7Sd+k7j9p3KjbFyo6KZOF1UVBRt2rRh//79vPDCC0yfPp2YmBh69uxJQkICTZo0sdtrvfvuu6xbty7H+SdOnGDkyJF07dq1QIWz7MTEWMYSK1u2rF22Zy8n9q6iQt2Org7D7oZ1m8KSTXPYf3yT1fSMjAxe//Y+7u30LNXKN3JRdLZRbkSy2njEsdvfdCTnh1A725JdlrH7zTnEs/sEfLbKcvddUaA2zbiUG9dxdJu2+ahx2oioPfDr9pzbtH2nYPYq+w/n5Cg6boxLuRERcY0LCZYLYhzJKIWoKynw/jI4kcNXhmnplue6bT3m3LgKSn2ncSk3xqKimTjV2bNnGTRoEM2aNWPr1q1MnDiRsWPHEhUVRXS05SEP9iya5aVChQr89NNP7N69m27duhEXF1eo7aWnp/PKK6/g4+PDkCFD7BOknaSlJuPja7ln3Gw28+P0Lnz/SgfMGdbfsCx66y6+ndyC9LSicVtDxdI1aVv3Tub8/rzV9G+iplG8WAh922V/NYORKDci1sxmOOaAoT5ulHQVzsY79jVscTkJlu7Me7mDp+3/fDdHUZtmXMqN6zi6TbuaBqcvOfY1bJGQbLlzNi+HzsB2Oz/fzVF03BiXciMi4hrR593jNWyxej+cS8h7uYWbjXMBU27UdxqXcmMseqaZONWMGTO4ePEic+bMISAgIHN6aGgozZo1Iyoqyu5Fs+XLl5OcnJzrMs2bN+fvv/+mW7durFixgqCgoAK91vjx41m7di3Tp0+ndu3aNq+XlpZGbGyszcunppYFfHNfJiURX3/Lra0piZfxL14ic57JZOL2h7/km+casWnxDFr2mQTAzqiPid61jMHTtuDtk/v2LXGkEhNTuMuLbHkveRnYcSLjP7iV7YdW0rh6R3Yd+YvfN3zGrPFb8hmLc96PcuOa3EjRkZDiRXxyeatpXiYILpb98iEB2f98o/jkrHeW7fjnPHXLOHAMSBusPRZMhtmWh6uZidqZQriXg795v4naNGtGatOUG2tGys3NklK9uJjohDbt0AUyIhILEWnhbTgeRHpGCRuWNBO16yplfc86OiQrOm6sGem4UW6sGSk3BZWQeP0c68zZ6zGcij1F/OUcGjcRKRL2HAsBQqym5XRuY8t5DWQ9tzl2Lp2YmFOFC7SQMsywen85LPec5P5A1stJ8OeOc9Qslfv3j/ZklL7TEovr+08j9Z3KjTVX5yYiIgIfn/yVwUxmc04DZ4jYX8WKFalRowYrV67MMq9r167s2rWL2NhYUlJSMu9AO3v2LOXKlWPcuHGMG5e/6rPJZMLb2zvPAyMjI4PU1FR8fX3Zv38/VatWzdfrAEyePJlp06bx0EMP8fHHH+dr3ZiYGCIjI21e/r7XdxFesX628zLS0/jru0l4+/pzy0DLgxYPbviBcjVvIaik9Rc2B9Z9x5JZwxg0dT2+fsWZN7kZ7e59g8bdHrMpjvMxu5n7bAOb487OpxN2USUi+/dSEAlJcTz6TjMmDPyMJjU65Wvdo7G7Gf1m4d6PcpMzV+dGio5SlRozdPo2q2mhATC1f8G3+dJPWZ+RturrJ9i2ZGbBN2oHvZ/8mWrN+mAy5f4hDOBqcjyzRoXkuZw9qU3LmavbNOUmZ67Ozc1Klq/D8Df2Wk1zRJu25ttn2Pzrvwu+UTvoOe47arW+x6Zl09NSeH9kDpVDB9FxkzNXHzfKTc5cnZuCCg4pwZjnZgDw5XvTGTHuOQA+nP4v4i/HuSQmEbGPrqNmU7/jg1bTHHFuM3OYN2az627fCg6P5IF3bb81fuMv0/l7wfN5L2gnRuk7wXj9p6v7TuUmZ67IzfHjx6lYsWK+1tGdZuI0sbGxnDhxgkGDBmWZl5GRwc6dO2natClgufMqIiKCpUuXUq1aNXbs2EH37t0pW7Ys99xj2wfxa1544QWmTJmS4/yEhAR69uzJ+vXr+e677wpUMJsyZQrTpk3j/vvv56OPPsr3+vbk5e1DmwFTWfh618xpVy6ezNLwAtRqM4jDWxax5MOh+PgXp0LtDvlqeI1o0dpZXLh8ilm/PGk1/fYWIxjQ4ckc1nIO5ca4uRFjsaWAZJ/Xcf0o1V5e3vlY1linbWrTjNumKTfGyo0pjyuT7fY6XgZo00zemM1mm9pxk8n29s8ZdNwY67i5kXJj3NyIiIdy1uc1Ly/MLhzz0JSPz2pgrHMb9Z3G7TuVG+Pm5kbG+vZF3NqVK1eA7L8M/c9//sOZM2cyh2YMDAzklVdeyZzfpEkT+vTpw5o1a/JdNMvNzQWzfv365XsbU6ZMYerUqYwYMYLZs2cX6MveiIgIjh8/bvPyczaW5Xwuo+/4+hcnIKQMl89FExwemesXw51GvM/sxytgMnnRZ8Li/IRNrVq18hV3dg7/tyxXLxdqE1YGd57E4M6TCrSuPd6PcpMzV+dGio64JG9mb7CeFp9sufowOyEBMKGn5ec3f7MMjXGz+GxGyZj+ymQafDqhcMEW0spDoWyKsaXfMFM+zNvpx4HatJy5uk1TbnLm6tzcLCHFi4/WWU9zRJs25YV/0fjDsYULtpDWHAlhXbRtbVrpYLPatEJwt+NGucmZq3NTUAmJSXyxcAUAi39dxPe/rwVgw8YNBBXX8IwiRdmKf0LZfMJ6Wk7nNrac11xb/0a+XhkcO3qk8MEWQloGfPh3BlfTTeQ1PCPA80+PpuH/DXV8YP9jlL4TjNd/urrvVG5y5orcRERE5HsdFc3EaSIjI/H29mbVqlVW048dO5Y57GJOzzNLTU1l9erVPP3003aNKT09HZPJVOCC2csvv8zUqVMZNmwYn3/+OV4FvMLXx8cnX7eJ+m7Le5mqTXpzZOtiylZtTtlqLXNcbt9fc8FsJu1qImeObKZq0162x+Hrm+/bW2923BeuFmoL9mOP96PcOIY93o8UHRXMUGwrJN/wXNsMc9bhOrJzOcm25QAaVAujYlhYwYK0k9tDYFOMLUua6FjPz+nHgdo0x1B/Y83dcnMzsxmCtkJCyvVpjmjT6lcrScVSJQsWpJ10KwHrbBrFyETHes7v23XcOIbaNGvulpuCunQ5IfPnMqXLZv5cLqIcoSEFe4a4iBhD7atkKZrZcm6Tn/OayHAvQ3wH0OYM/Lk/7+WK+UKXJmH4+Tjv86VR+k5wr/7Tnc5rQLkpKNeP4SEew8/Pj+HDh7Np0ybuuusuPvnkEyZPnkzr1q0JDw8Hci6ajR07luDgYIYPH56v1zSbzbkOzRgaGsqqVasKVDD74IMPeOmll6hUqRJdu3Zl3rx5zJ07N/PfsmXL8r1Ne6rapBdHti3m9OGNlK3eKttlLpzYy5r5z3DbsHdp3P1xls8eRVL8OSdH6nmUG5HcmUwQ6eDPGr7eUK6EY1/DFmVCoGU125Zrnv/Rg51CbZpxKTfGYDJBZLhjX8PLBOVLOPY1bBEeBG1r2LacLW2fK+i4MS7lRkTEGCo5+LwGHH/uZKvb6kCAX97LdasPfga8NUV9p3EpN8amopk41cyZM3nooYdYv349EyZMYP369SxcuJDy5ctTvHhxatWqlWWdp556irVr1/Lbb7/h52dDT5VPBX12zsaNGwGIjo5mxIgRDBs2zOrfq6++as8w8y2wZDlSk+JJvZqY7XtMT0tlyaz7iKzflQadRnPrPa8REBxO1OcPuyBaz6LciOStWRXHbr9RJHgb5CxoUCtoHJnz/DIh8Ghn8DfghzBQm2Zkyo1xNK3s2O03jDTOFzUDWuT+fksFWdq0Yr7Oiyk/dNwYl3IjImIMZUMcfwGio8+dbBUeBI90guK5fB3ZpR50rue8mPJDfadxKTfGZpCvi8RTBAUF8fHHHxMbG0t8fDxLly6lbdu27Nq1i4YNG2YZ3nD8+PEsW7aMqKgoSpUq5aKos/fFF19gNptz/Ldy5UpXh0ilht0ILZP9ZbzrfnyR+AsxdB01GwAfv2J0f3QuR7YsYu/qr5wZpkdSbkRy16yKY79QbZf1Gg2X8fGGEe0tXyLXKXd9esUwGNwGnu4JJQNdF58t1KYZl3JjDE0r5/5lS2G1q+m4beeXjzcMvxUe6wJ1b3ieeYWScG9reKYXlAp2XXy20HFjXMqNiIjrmUyOPfeoGAaVDXKnGUDlUvB8H+jbzHJB4zVNK8NTPeDOppa/iVGp7zQu5ca4VDQTl4uLiyMmJibL0IyPP/44y5cv548//qB06dKuCa6Iq99xFJUb9cgy/cT+NWz+9d90HTWb4qFlMqeXrtyENgOmsvLrx7l8zqYHUkgBKTciufP3sVyx5wi1y0EVY12HgZfJEte9ba5PG3UbtK5unLtHcqM2zbiUG2Pw9YZuDRyz7eploEbZvJdzJpMJakbAoNbXp43uCG1qqE2TwlFuRESMoWU1y93jjtCzofGKUIH+0LEujOlyfdpdzZwzVGVhqe80LuXGuIrARxZxdzt37gSsn2d27Ngx3nvvPfz9/ala9fpDXNq3b89vv/3m7BCLrKCS5bOdXqF2Ox7/Ki3beS37TKJln0mODKtQjsbu5p0fH8bL5IW3lw9PDZxNufDrV2Xsi97Ap78+A0BSSjxmzMwavwWAmLMHGPV/9XlrzGrqVW6T7fadRbkxbm7EODrXgx3H4fgF+23T38dyp4PRPoQVdWrTjNumKTfGyc1ttWF7NBy142MI/Hwsd6SqTbMvHTfGOW5uptwYNzci4lmunYO8t9y+221RFepXtO82PZ079p3gHv2ncmPc3KhoJi6XXdGscuXKmM1mF0UkRhYaVJpXH/iVwIBQNu77nbnLX2HioDmZ8+tUasWbj64E4KfV75CSmpQ5b+7yV2hU7TZnh+wxlBuxN28vGHYrzFwKCSk5LxefDC/9dP3nnJhMMKSt8Yc6FGNQm2ZcRTU3Xl5w3y2WNu1yLm2VzW0alosAjD7UoRhDUT1uPIFyIyJFVfWy0LMR/LYj52VsPa8BKBcK/VvYLz5xb+o/jcsdcqPhGcXlxowZg9lspk0bXRkneSsZVIbAgFAAvL198fLyznHZP7bOo1OTwQDsjV5PWHAEpUJ1yZKjKDfiCGVCLENgBBfLeZkMM1xKsvzLyOF6Cy8T3NcWGldyTJziftSmGVdRzk2pYBjTFUIDcl7GljbNZILBbS3PfxSxRVE+btydciMiRdntDSz/cmLLeQ1AuRLwaBfHPgNW3Iv6T+Nyh9yoaCYiRVJKahJfLX2J/u2eyHZ+zNkD+Hj7ERFWBYB5Ua9yb6dnnRih51JuxN7Kl4QJPaFu9iMX5KlMCIzrBs2r5r2syM3UphlXUc1NRCg81RPqVyjY+qWCYWxXaJX9M8NFclVUjxtPoNyISFFkMsEdjWFkewjyL9g2bqkBT9wOIblcVCSSE/WfxlWUc6PhGUXEcJJSEnjmk65ZpvdsNYo7Wo8iPT2N174ZwsDbnqZquYbZbiNqyzd0bjoEgPV7f6VWxRaEBBaBJ7QanHIjrlKiODzUETYfhT/2wsmLea8TEgDtaloe2OynMx7Jhto043L33IQGwKjbYOsxS5sWY8OzG4OLwS01oUs9tWmSPXc/booy5UZE3F2TSlCjDCzZBRsPQ3Jq3uvUioCu9S3/i2RH/adxuXtu9HFLRAwnwD+I98aty3ae2Wzmze9H0bx2d25t0DfHbazasYC3x6wG4J+T29hxaCWTjv7NkdidxJzdz0sjfiI8pJwjwndryo24kslkeTB08ypw9BzsPWn5ojn2ElxNBx8vCAuEyHCoXsZyF4e37qmXXKhNMy5PyI3JZBlesWllOHbe0qYdP3+9TfM2QXgQVAy73qb55DyyiYhHHDdFlXIjIp4gqBgMaAG9G8P243D0LBy/AJf/NzSjvy9UKGE5t2kUCWVDXR2xGJ36T+Ny99yoaCYiRcqm/Uv4c8cCTl88yspt86levglj7noHgBnfDudfg79ib/R6yoVVIzSwFABDuzzP0C7PA/DG/JH0bvuIOkQHUG7EWUwmqFra8k/EUdSmGZe75cZkgiqlLP9EHMXdjht3otyIiLvx97UMI62hpMWR1H8alzvkxmQ2m3N5DKOIGNHriy1XIbtaRCg827tw21g7B66ct088hRUYDm3vL9w2lBvHsEduRIqCuESYstDy85R+lmEpXUltmmOov7HmbrmR69SmZU/HTVbKjWO4sk27dDmB12bNA+CxYX354OufAZj06BBCQ4JcE5SISCEZ6dzGKH0nuFf/6U7nNaDcFJQGLRIRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDw900ykCAo3yGgW9ogjoETht2Ev9ohFuXEMI8Ui4knUpjmG+htr7pYbMS4dN46hNs2au+VGRESMySh9J7hX/+lO5zWg3BSUimYiRdDojq6OwH6a9HN1BPal3IiIO1GbZlzKjUj+6bgxLuVGREQkf9yp7wT36j+Vm6JPwzOKiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj6eimYiIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE46loJiIiIiIiIiIiIiIiIh7Px9UBiEj+fboSzie4OgoID4LRHQu3jW0LISnOHtEUXkAJaNKvcNtQbhzDHrkRkfxTm+YY6m+suVtu+vTpw6FDh+wST2FUr16dX375xdVhGIqOG8dQm2bN3XIjIiLGZJS+E9yr/3Sn8xpQbgpKRTORIuh8AsRecnUU9pEUB1fOuzoK+1FuRMSdqE0zLuXGuA4dOsSePXtcHYZkQ8eNcSk3IiIi+eNOfSe4V/+p3BR9Gp5RREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERMQCzGS5euf77mcuQnuG6eERECsNshrjE67+rTRMREZGiLDXdesi9+GTXxSIijqVnmomIiIi4SFo67IyBDYfh2DlIvHp93odR4OsN5UtC00rQqhoU93ddrCIieUnPgF0xsP4QHDsPV1Kuz/swCny8oEJJaFwJWleHQLVpIiIiYmAXr8Daf2DXCYiNgwzz9Xlv/gahAVC1NLStATUjwMvkslBFxI5UNBORIuON+SNZtvlLALxMXoSFlKNJ9c48eMdrlAqt4OLoPJtyI5I/ZjNsOgKLtsLlXK5QTE23FNOOnYNft0OH2tCjkaWYJo6jNs24lBtjMpthyzH4ZQtcSsp5ubQMSzHt2Hn473ZoXxt6NgI/fSp1KB03xqXciIgY05UUWLgZNh+1nOfk5FISbIu2/CsTAne3hFoRTgvTI6nvNC53yo2GZxSRIqVh1fZ8N/kU3zwfzaQh8/jn5FZe+Xqgq8MSlBsRW11Jgdmr4Ju1uRfMbpaaDlF74P/+CycuOi4+sVCbZlzKjbEkXoU5q+Hrv3IvmN0sLQNW7IV//xeOn3dcfGKh48a4lBsREWPZcwJeX2y5yDG3gtnNzly23Fn/wwbLiCLiOOo7jctdcqOimYgUKT7efoSFRFAqtAKNqnWgV+uH2HNsLVeSL7s6NI+n3IjkLSEZ3l8Gu08UfBunL8N7y+DIWfvFJVmpTTMu5cY4rqTAB8thx/GCb+NsPLy/HA6dtl9ckpWOG+NSbkREjGPzEcsFjoV5Xtmag5ZtqHDmOOo7jctdcqOBMEQ8SHraVd4fWfCHRzwxNx+X2DjBuUsn+XPnD3h5eePlVbTHKlNuRNxfWjp8vAJOXcp5GS8TBBez/ByfbD1m/o2SUy3bmtADSofYP9bCUptmXMqNsfn5+VGjRg0CAwNJTU3l6NGjxMXF5bpOYGAgw4YN46OPPnJOkP+TngGfrMz9zldb27SUNMu2nuwBEaH2jrTwdNwYl3IjIiL2ciDWMhpITucrYPu5zb5Tlm0NvxVMBnvOmfpO41JujENFM5EC2r9/Py+//DJbtmzh5MmTpKamUqlSJe644w4mTpxIuXLlXB1iFjF7V3LfjN2EV6jn6lAKbPvhldz5fBBmcwYpqZYxgO7uMIEAv0AA1uxcyNfLplqtE31mD2P6vMudtzzq9HhtpdwYNzci9rJkJxy/kPsywcVgan/Lzy/9lPtQZ8mpMG8djOsKXgYbO0BtmnHbNOXGeLmpWLEiDz30EL169aJBgwb4+flZzT906BCrV6/mk08+Ye3atVbzAgMD+e2332jfvj1VqlTh2WefdVrcy3ZbnreYm/y0aSlpMG8tPHE7eKtNszt3O26uUW6MmxsRkaIk6arlPCS3ghnk79xm6zFoUBGaV7FbmHahvtO4fadyY5zcqGgmUkAxMTGcOnWKfv36UbFiRXx8fNi5cyeffPIJ8+fPZ9u2bZQpU8bVYVq5cGIvlRve7uowCqVOZGueufdLrqYls2r7ArYeXM79PaZlzm/XsB/tGvbL/P2vXT/z+W/P0a3FCFeEazPlRsS9nYqzPI/M3o6chb//gXa17L/twlCbZlzKjXGUKlWKt956iyFDhuDtnfOVl9WrV6d69eqMHDmSTZs2MWbMGDZu3GhVMEtPT2fHjh1Oi/30JVi60/7bjT4Pq/dDx7r233Zh6LgxLuVGRETs4ddtEJdo/+3+uBHqloPiBb95yO7UdxqXcmMcKpqJFFCXLl3o0qVLlukdOnTgnnvu4YsvvuCZZ55xQWTuzd83gAqlagBQNaIBp84f4v2fx/HUwE+zLHs2Lob3Fj7G9Ad/o5hfcWeH6nGUG5GcrdqX91WLBbVyL9xS0zJUiNiP2jTjcofc9O7dm88++yzzAqvo6Gg+//xz1qxZw7Zt27h06RL+/v7UrVuXli1bMmTIENq1a0eLFi1Yu3Ytb731Fm3atMksmA0fPpx58+Y5Lf7V+x3Ypu2DDrWNdwdtUecOx427Um5ERFzrSgqsP+yYbSdehQ1HoGMdx2zfU6nvNC53yY0+iohLbN++nbvuuovQ0FBCQkLo27cvp06dIjg4mHvvvddurzN+/Hh+//33XJdZsGABFy/m8jCGfKpcuTKAXbdpDxdO7iOsvPv10sO6TWHJpjnsP77JanpGRgavf3sf93Z6lmrlG7koOtsoNyLuLfEqbD7quO2fS4D9pxy3/fxSm2Zcyo0xjBgxgp9//pkyZcpw/vx5hg0bRrVq1Zg6dSpRUVGcP3+etLQ0rly5wqZNm5g1axbt27enefPmbNq0CW9vbyZOnOiygllKKmw84rjtxyXCnpOO235+6bgxLuVGRETsYcNhSE133Pb/OgBmgzxqSn2ncSk3xqKimThdVFQUbdq0Yf/+/bzwwgtMnz6dmJgYevbsSUJCAk2aNLHba7377rusW7cux/knTpxg5MiRdO3atcBFruTkZM6dO0dMTAxLly7l4YcfBuCOO+4o0PYc5cTeVVSo29HVYdhdxdI1aVv3Tub8/rzV9G+iplG8WAh9241zUWS2U25E3NvhM479EAaWB00bhdo041JuXK9Xr1589tlneHt78+eff1KvXj3mzp1LenrejcSWLVvo2rUrx48fz5z2xx9/OLVgBnDknOX5Y460z0BFMx03xqXciIiIPTj6s9TZeDif4NjXsJX6TuNSboxFRTNxqrNnzzJo0CCaNWvG1q1bmThxImPHjiUqKoro6GgAuxbN8lKhQgV++ukndu/eTbdu3YiLi8v3NmbPnk3p0qWJjIyke/fuxMXFMXfuXNq3b2//gAshLTUZH1/LIMpms5kfp3fh+1c6YM7IsFpu0Vt38e3kFqSnpboizAIZ2HEimw8sZfuhlQDsOvIXv2/4jIn3zHFtYDZSbkTc2/ELjn+NGCe8hq3UphmXcuNaYWFhmQWz1atX06NHD86cOWPz+oGBgSxatIjIyEgy/pezbt260aNHD0eFnK3j553wGmrTnKIoHDe5UW5ERKSwzGbnfJYyyuc19Z3GpdwYi55pJk41Y8YMLl68yJw5cwgICMicHhoaSrNmzYiKirJ70Wz58uUkJyfnukzz5s35+++/6datGytWrCAoKMjm7fft25c6deqQkJDA1q1b+eWXXzh37ly+YkxLSyM2Ntbm5VNTywK+uS+Tkoivv2U82JTEy/gXL5E5z2QycfvDX/LNc43YtHgGLftMAmBn1MdE71rG4Glb8PbJffuWOFKJiTltc9zZbyPv93LNM/d+ke30+lVuYdm/Lfe6JyTFMWP+MCYO+oKQwPB8xuKc96PcuCY3Iq5yNDYMuD4+t5cJgotlv2xIQPY/3yw+2fp5QicvphMTY/9LJNWmWTNSm6bcWDNSbtLSsr8N680336Rs2bJcuHCBe+65h6SkJJu3GRgYyG+//WY1JOPw4cPp3r07n376KTVr1sxyvpuWlkZMTEyh3kt2jsSWBAIzf3dEm3YqLoOYGPvfbqbjxpqRjhvlxpqRclNQCYnX27gzZ6/HcCr2FPGXc2kQREScKPGqF1dSyltNK+y5zc3nNQAHjl+ilHd8ISLNyih9pyUW5/WfRaHvVG6suTo3ERER+Pjkrwymopk41fz582nfvj21atXKdn7ZsmWJiIgAYMyYMSxatIhLly4RHBzMwIEDeeONN/Dz88vXa65bt45Nmzblusy1q3W3b9/O2bNn81U0q1ixIhUrVgQsBbQBAwbQsmVLEhMTmTRpkk3biI2NJTIy0ubXvO/1XYRXrJ/tvIz0NP76bhLevv7cMnAaANG7llKpYTer5YLDK9L5/lksmTWMyo164OtXnD/nPUW7wf+2eQzdAwcOENm/gc1xZ+fTCbuoEpH9eymIRWtnceHyKWb98qTV9NtbjGBAhydzWMviwIED3PZw4d6PcpMzV+dGxFV6P/kz1Zvflfl7cDGY2j/v9Sb0zHneSz/BpRu+b790OTFf/Yit1KblzNVtmnKTM1fnJjvlypVj6NChAEyYMCFfF0tlVzCbN28eq1evZv/+/VSsWJFBgwbx5ZdfWq134MABh7QLPcd9R63W92T+7og2LSklTW1aHtztuFFucubq3BRUcEgJxjw3A4Deve5kxLjnAGjVshXxl+NcEpOIyM2CwyN54N1o62mFPLe5+bwG4N33PmTQgucKGGX2jNJ3gvH6T1f3ncpNzlyRm+PHj2d+d28rFc3EaWJjYzlx4gSDBg3KMi8jI4OdO3fStGnTzGljx47l3//+N4GBgZw7d46BAwcyffp0pkyZkq/XfeGFF3JdJyEhgZ49e7J+/Xq+++47qlatmq/t36xRo0Y0bdqUDz/80OaimT15efvQZsBUFr7eNXPalYsnCSpZPsuytdoM4vCWRSz5cCg+/sWpULsDjbs95sxw7W5w50kM7uz8v7stlBvj5kbEkTLSHT9sQnraVYe/xs3Uphm3TVNujJebUaNG4evry8mTJ5k7d67N6+VUMAPLh7958+bx4IMP8thjj2UpmjlKhhOGglGb5nxGPG6uUW6MmxsRkaIu3Qmf1QAynHxuo77TuH2ncmPc3NxIRTNxmitXrgCWW0xv9p///IczZ85YDc1Yr169zJ/NZjNeXl4cPHjQrjHdXDDr16+fXbablJTEhQu2D1gcERFh9VD3vMzZWJbziTnP9/UvTkBIGS6fiyY4PBKTKefHF3Ya8T6zH6+AyeRFnwmLbY4BoFatWvmKOzuH/1uWq5cLtQm7scf7UW4cwx7vR8RVVh0OZeMNu298suXqw+yEBFy/YvHN3+ByDqO3xd806nDV8sEOOUbUpjmG+htr7pabLl26cODAAatp15479uWXX+Y4fOPNciuYXfPZZ5/x4IMP0rJlS8LCwqzOP2vVqkVUVFSh3kt21hwJYd0NF2Q7ok2rEO6nNi0P7nbcKDeO4cpz6ITEJL5YuAKAxb8u4vvf1wKwYeMGgopreEYRMYYMM7y3JoPUjOv9SmHPbW4+rwGYMmkc9d990A4RX2eUvhPcq/90p/MaUG6AzFHt8kNFM3GayMhIvL29WbVqldX0Y8eOMW7cOIAszzN7/fXXmTZtGleuXCE8PJzXX3/drjGlp6djMpkKVDCLjY3N9qBbsWIFu3btomPHjjZvy8fHJ1+3ifpuy3uZqk16c2TrYspWbU7Zai1zXG7fX3PBbCbtaiJnjmymatNetsfh65vv21tvdtwXnH8tcfbs8X6UG8ewx/sRcZV66VgVzTLMWYfryM7lJNuWA6gW4eeQY0RtmmOov7Hmbrm5ebx8b2/vzHPcv/76y6Zt2FIwA9i0aRMpKSn4+/vTvHlzli1bZhWHI9qF+masimaOaNOqllWblhd3O26UG8dw5Tn0pcsJmT+XKV028+dyEeUIDbH9cQgiIo4WGQ6Hz17/3RHnNo1qhFGuRFjBAsyBUfpOcK/+053Oa0C5Kaicy5gidubn58fw4cPZtGkTd911F5988gmTJ0+mdevWhIdbHvx3c9Hs2WefJSEhgT179vDII49Qrly5fL2m2WzOdWjG0NBQVq1aVaA7zB599FHatGnDc889x8cff8y7776b+UD24OBg3nzzzXxv056qNunFkW2LOX14I2Wrt8p2mQsn9rJm/jPcNuxdGnd/nOWzR5EUf87JkXoe5UbEs1QrDdncZG1XNco4dvu5UZtmXMqNMVSqVInixS0P+d6+fXuey9taMAPLw7D37t0LQN26de0XdC6qlgYvR7dpZfNexlF03BiXciMiIo7g6POOoGJQNsSxr5ET9Z3GpdwYm4pm4lQzZ87koYceYv369UyYMIH169ezcOFCypcvT/HixalVq1a269WtW5fGjRszbNgwu8eU3XCRthg8eDClSpXi66+/5oknnuDZZ59lw4YNPPzww+zYsSNLAdDZAkuWIzUpntSridm+x/S0VJbMuo/I+l1p0Gk0t97zGgHB4UR9/rALovUsyo2IZwktDg0qOG77gf7QKNJx28/z9dWmGZZyYwxJSUl88sknfPXVV5w/fz7P5WfPnm1TweyaH374gdmzZ7Nv3z57hZyroGKObXMC/KBJJcdtPy86boxLuREREUdoUx0ceT1Q2+rg5aJv4NV3GpdyY2wqmolTBQUF8fHHHxMbG0t8fDxLly6lbdu27Nq1i4YNG+KVSy+Smpqa5fkQrnTPPfewePFijh8/TnJyMklJSezbt4/33nuPSpVc+En/BpUadiO0TLVs56378UXiL8TQddRsAHz8itH90bkc2bKIvau/cmaYHkm5EfEsHWo7btu31AAfb8dt3xZq04xLuXG92NhYHn74YUaMGEFSUt5j+EyePJno6GibCmYAr776KqNHj2bp0qX2CNcmjmzT2lQHPxc/REDHjXEpNyIiYm9hQdDQQRcEeXvBLTUds21bqe80LuXGuPRMM3G5uLg4YmJi6NXr+pisly5dYuHChfTt25fQ0FB27tzJtGnT6N69uwsjLXrqdxyFX0DWe8BP7F/D5l//Te/xCykeen1Mr9KVm9BmwFRWfv04Fep2JKSUMYp/7ki5EfEsNSOgeRXYfNS+2y0VBF0b2HebBaE2zbjcJTfJVxN55uMuRJ/ZyxMDPqJTk3ut5v+9+xe+/WM6vt5+9GrzMF2aDWVf9AY+/fUZAJJS4jFjZtb4La4IP1/++ecfateuTXJyNk+RN4hqZaBVNdhw2L7bLRkI3Rvad5sF4S7HjTtSbkRExBH6NoP9pyAlzb7b7dHQcn7jSuo7jUu5MS4VzcTldu7cCVg/z8xkMjF37lyeeuoprl69SpkyZejfvz9Tp051UZRFU1DJ8tlOr1C7HY9/lf2ZQMs+k2jZZ5IjwyqUo7G7eefHh/EyeeHt5cNTA2dTLvz6VRm5fUEWc/YAo/6vPm+NWU29ym1cEv817pibvL7QzGl+Uf1SUyS/+reAf07n/rDo+GR46afrP+fGywSD24K/Ac7m3LFNU39jrNz4+vgzZcRCFq/7KMu8jIwMPvvvs7z/+Ab8fIox4aOOtKnbmzqVWvHmoysB+Gn1O6Sk2vikdgMwcsHsmr7N4WAsXEzMeZn8tGkmEwxuA8V87RdjQbnLcXMjtWnKjYiI5CwsCPo1h/nrc18uP+c2lcKhcz37xFcY7th3gnv0n8qNcXNjgK9ZxNNlVzQLCQlh+fLlLopIjCw0qDSvPvArgQGhbNz3O3OXv8LEQXMy5+f2Bdnc5a/QqNptzg7ZY+T2hWZu84vyl5oi+RHoD490hveXw5WU7JfJMOdeVLvGZIIhbaF6mbyXlYJRf2Ms3l7ehIVEZDvvUuI5SgSVIcA/CIDI0rXZG72eFrVvz1zmj63zeOG+BU6J1VMU97O0ae8th4QcvjSyuU0DBrWGWtmnWOxAbZpxKTciIsbQpgacT4Blu3NextZzmzIhMLqjZXhGcQz1n8blDrnRoSsuN2bMGMxmM23a6Mo4yVvJoDIEBoQC4O3ti5dXzg/y+WPrPDo1GQzA3uj1hAVHUCq0olPi9ES5faFpy3ywzpmIOypXAsZ1g9LBBd9GMV8Y2Q5aVLVbWJIN9TdFR4nA0sQlnOH85VMkJsez88hq4pMuZM6POXsAH28/IsKquC5IN1U2FB7vBmWzjipjM38fGHar5Vlm4jhq04xLuRERMY47GkOfppZRPQqqWmnL+VFwMfvFJVmp/zQud8iNimYiUiSlpCbx1dKX6N/uiWzn3/wF2byoV7m307NOjFDyS19qiqeICIWJd0CnupY7xvKjTjn4Vy9orKHLnUb9jfGZTCaeGPARr88byvR5g6kS0YDwkOtDnURt+YbOTYe4MEL3ViYEnr4DutTL/xdMtSIsbVqzKg4JTbKhNs24lBsREdczmSxDKj7VAyqUzN+6vt6WIR7HdoMgFcycRv2ncRXl3Gh4RhExnKSUBJ75pGuW6T1bjeKO1qNIT0/jtW+GMPC2p6laLvunxd/4Bdn6vb9Sq2ILQgLDHRq3J8grN4WhLzXFk/j5wF3NoH0tWPsPrD8Ml3MY5sPPx1Ika1cTKpdybpzuTv2N+2hUrQP/fuQPklISmPrVAOpWuj6CwaodC3h7zGoXRuf+fL3hzqbQvjb8fRDWH8p56CI/b2gUCbfWgiql8n/xgORMbZpxKTciIkVLxTCY0BP2n4I1B2DfKUjPyH7Z0sFwS01oVc0yJL/Yj/pP43L33KhoJiKGE+AfxHvj1mU7z2w28+b3o2heuzu3Nuib4zZu/ILsn5Pb2HFoJZOO/s2R2J3EnN3PSyN+IjyknCPCd2u55aaw9KWmeKKwIOjVxDIMSFwiHL9geTZQhhkC/CxXN5YJBi+NDeAQ6m+KlqlfDuCfk1sp5hfIvuj1tKjVnfikC3RuOoSPFk3gnxNb8Pby5YGer+Lr4wdYhvgoF1aN0EBVnJ2hRHFLe9azkaVoFnPBckFAhhkCfKF8SctQjmrTHENtmnEpNyIiRY+XCeqWt/xLS4dTl+BUHFxNszyrrERxiAzTXWWOpP7TuNw9NyqaiUiRsmn/Ev7csYDTF4+yctt8qpdvwpi73gFgxrfD+dfgr7J8QTa0y/MM7fI8AG/MH0nvto+oQ3SQm7/QfLTP28D13OQ0X19qiqczmaBkoOWfGIP6G+N5acSPOc575M43s51et1JrXn3wV0eFJDkwmSxfJJUo7upI5Bq1acal3IiIGJ+Pt6VAFhnm6kjkGvWfxuUOuTGZzWazy15dRArk9cUQe8nVUViey/Ns78JtY+0cuHLePvEUVmA4tL2/cNtQbhzDHrkRkfxTm+YY6m+suVtu6tevz549e+wTUCHUq1eP3bt3uzoMQ9Fx4xhq06y5W24K6tLlBF6bNQ+Ax4b15YOvfwZg0qNDCA0Jck1QIiJuxCh9J7hX/+lO5zWg3BSUBsYQERERERERERERERERj6fhGUWKoHCDXJhnjzgCShR+G/Zij1iUG8cwUiwinkRtmmOov7HmbrmpXr16gdbLyMjg7AXLJalhJUK4EHcZgNJhoXgV4CFgBY3Dnem4cQy1adbcLTciImJMRuk7wb36T3c6rwHlpqA0PKOIiIiIiIiLaSgzEXEnatNERESkqNLwjCIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj6eimYiIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0EykCUlJSuP/++6lYsSKhoaF06tSJ3bt3uzosERERETGYM2fO0KNHD4oXL06DBg1Yt26dq0MSESmwl156iXr16uHl5cX8+fNdHY6IiIh4ABXNRIqAtLQ0qlWrxrp167hw4QJ33nknffv2dXVYIiIiImIwjzzyCNWqVeP8+fNMnDiRAQMGkJKS4uqwREQKpGbNmrz77ru0atXK1aGIiIiIh1DRTKQICAwMZPLkyVSsWBFvb2/Gjh3LoUOHOH/+vKtDExERERGDiI+PZ/Hixbz00ksEBAQwYsQIgoODWblypatDExEpkPvuu49u3bpRrFgxV4ciIiIiHkJFM5EiaO3atZQpU4bw8HBXhyIiIiIiBnHw4EFKlChB2bJlM6c1bNiQPXv2uDAqERERERGRosPH1QGISP7ExcXx0EMPMX36dFeHIiIiIiIFZDabWbp6E5fjrwBwNTU1c17UX5szf178x1r8fH0tv5igx22tCA4snu02r1y5QkhIiNW0kJAQEhIS7By9iIg1s9nM8r82E3fJ0t7Y1KYB3Tu0JCQ40HmBioiIiORBRTORIiQ5OZm77rqL3r1788ADD7g6HBEREREpIJPJRNXIcny+4L9Z5u07fDzz5537j2T+fEvz+jkWzMAypHd8fLzVtMuXLxMUFGSHiEVEcmYymahWqTyzv12M+aZ5ObVprRrXUcFMREREDEfDM4oUEenp6dx7771ERkbyf//3f64OR0REREQKqVbVirRtVt+mZUuHlaDHba1zXaZmzZpcvHiR06dPZ07btWsX9erVK1ScIiK2qF6pPO1aNrJp2fASIfTq3NbBEYmIiIjkn4pmIkXE6NGjSU5OZs6cOZhMJleHIyIiIiJ20LNja0qHhea6jJeXiUG9O+Hnm/tAIcHBwfTu3ZtXXnmF5ORkvv76ay5fvkzHjh3tGLGISM5u79CCsqVK5rqMyWTint6d8PfzzXU5gNTUVJKTk8nIyLD6WURERMRRVDTLgclkYuTIka4OQwSAY8eOMWfOHFatWkXJkiUJCgoiKCiI1atXuzo0ERERESkEP18f7undCa9cLorqfEszKpYrbdP2Zs2axcGDBwkLC+P111/nxx9/xN/f317hiojkytfHh0G9O+HtlfPXTR3bNKZyhbI2bW/06NEEBASwevVqhg8fTkBAAH/++ae9whURERHJwmQ2m28eblqwFM1GjBjBF1984epQxACOHj3KF198Qd++fWnSpImrw8ni3MVL+Hh7UyJEz6sQERERKYqWr9nM8r82Z5keWa40j9x3V65fQIuIGM3Kddv4fdWGLNPLlw1nzLC++Hh7uyAqERERkbzpk5eIDY4ePcrUqVPZtm2bq0PJ1uKotfz74/ls3nXA1aGIiIiISAF0ats0y91kvj7e3JPHHRsiIkbUoVWjLHeT+Xh7M6h3ZxXMRERExND06Uvs7to44+Icx0+dYd+haMxms81DXIiIiIiIsXh7ezGoVyd8fa5/mdyrc1tKh5VwXVAiIgXk5eXFPb074XfDc8t63NYqz+ediYiIiLha7k+SNojjx48zYcIElixZgtls5rbbbuOdd96hS5cuVKlShZUrV2Yue21Yxfvuu48XXniBHTt2EBISwqBBg3j11VcJCrIevm737t1MmDCB1atX4+/vT8+ePXn77bcLHOu11x8+fDjPP/8827dvJywsjHHjxvGvf/2Lixcv8vTTT7No0SISEhLo3Lkzn3zyCeXLl7fazqVLl5g+fTo//vgjx48fJyQkhK5du/Lqq69SrVq1zOXi4+OZMWMGy5Yt49ChQ8THxxMZGcndd9/Niy++SPHixTOXzcjIYObMmXz++eccOXIEk8lEuXLlaNeuHR999BG+vr5W7+HmoSm/+OIL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s2knAPVrV1XBTERERERERERERESkkAxfNCuKbi7w2TLPbDZb/d+1a1f+9a9/5flab731FhMmTOD222/n8ccfp3z58vj5+XHixAlGjhxpVURr27Ythw4dYsmSJaxYsYIVK1Ywb948pk2bxpo1awgLC8v1tdLS0nKcV7x41oqt2WymYcOGvPXWWzmud3NBLae/T25/05v/dhMmTMjxuXTXCm22bPva9vJS2L8rFO6ZZnqWmYiIiIiIiIiIiIiINbd8plm1atU4ePAg6enpVsWNU6dOERcXl+061+44utG15a/dVVS6dGmCgoLYt29flmX37Nljn+ALoHTp0pQoUYLLly/TtWvXPJf/+uuvqVKlCr/99pvVHWi///57tssHBQUxYMAABgwYAFjuUnvsscf47LPPmDhxIgBhYWFcuHAhy7rX7tKzVc2aNTl79iydO3fOcnecI9SsWROwFMFs+dvlh8lkynW+LX9XERERERERERERERExLsMXze666y5ef/11vvrqK+6///7M6TNmzMhxnf379/Pzzz9bPdfs2vLXpnl7e9O7d2/mz5/PihUrMp9rZjabeeONN+z/Rmzk5eXF0KFD+eCDD/jhhx+4++67syxz5swZypQpA1jeh8lksrorKi0tjddffz3LeufOnaNUqVJW05o1awZgVSSrVasWa9euJTExMfMOsosXLzJnzpx8vZfhw4czceJE3nrrLZ5++uks80+fPk3ZsmXztc3cNG3alAYNGvDRRx/x8MMPZxl2MS0tjcuXL9t059fNgoIs1ejsiom2/l1z377tzzTTs8xERERERERERERERHLnls80e+aZZ5g3bx6jR49m8+bN1K9fn5UrV7J27doshYprGjZsyH333cfo0aOpWbMmK1as4IcffuC2225j0KBBmctNmzaN3377jd69ezNu3DgqVqzIokWLOHv2rLPeXrZeffVV/vrrL+655x7uuece2rRpg5+fH8eOHeO///0vzZs354svvgDg7rvvZtKkSfTs2ZP+/ftz+fJl5s2bh6+vb5bt1q1blzZt2tC6dWvKly/PqVOn+OSTT/Dz8+Pee+/NXG7s2LHcd999dO7cmWHDhhEXF8enn35K5cqViY2Ntfl9PPHEEyxbtoyJEyfyxx9/0LlzZ0JCQoiOjiYqKopixYqxYsWKQv+9rjGZTHz99dd07tyZRo0a8cADD1C/fn0SExP5559/+Omnn3jttdcYOXJkvrddr149goOD+fDDDylevDglSpSgTJkydO7c2ea/a268vbxsvk104dI1ADRtUIuqkeXy/V5EREREROT/27t/l9bOMIDjT0SRC/5ALoiIQ4hLcdEKihQhoJN/gYNDFBwFJeIgijrppIOKuLiYRdwUdFUIGZzcO7TYgouUi+0gDmI3qdzWWirq9f18xvDk8OSQ7ct7DgAAwNfefTRramqKcrkcxWIxdnd3IyIin8/HyclJDA4O/u13uru7Y21tLebm5mJ7ezsaGhpiYmIilpeXHz0msL29PcrlckxPT8fGxkbU1tbG0NBQlEqlFz0B9V81NjZGpVKJ1dXV2N/fj4ODg6iuro62trbo7++P8fHxh9mZmZm4v7+PnZ2dmJycjJaWlhgeHo6xsbHo6Oh4dN3p6ek4Pj6O9fX1uL6+jubm5ujr64vZ2dno7Ox8mBsZGYnLy8vY3NyMYrEYuVwuFhYWoqqqKs7Ozp79O2pqauLo6Ci2traiVCrF4uJiRES0trZGb29vFAqF/3mnvtbV1RXn5+exsrISh4eHsb29HfX19ZHNZmN0dPQf/zP/5tOnT7G3txfz8/MxNTUVt7e3kc/nY2Bg4Nn39SV8uf4jfvz516jKZGLgh+9f9NoAAAAAAJCyzP1fn+v3jclms5HNZuP09PThs0wmE4VC4eEkFnw0v335PX765TJ6Or9761UAAAAAAODDePcnzYDHPjc1xOemhrdeAwAAAAAAPhTR7Bmurq7i7u7uyZm6urqoq3veO6kAAAAAAAB4X0SzZ+jp6YmLi4snZxYXF2Npael1FgIAAAAAAOBFfdPvNHstlUolbm5unpzJ5XKRy+VeaSMAAAAAAABekmgGAAAAAABA8qreegEAAAAAAAB4a6IZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJL3JyL/FPhMXRZCAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -432,10 +379,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Simulated expectation values: [0.54180908, 0.55859375, 0.39801025, -0.27911377, 0.23406982, -0.22296143]\n", + "Reconstructed expectation values: [0.50671387, 0.51519775, 0.3380127, -0.17828369, 0.26855469, -0.17858887]\n", "Exact expectation values: [0.50983039, 0.56127511, 0.36167086, -0.23006544, 0.23416169, -0.20855487]\n", - "Errors in estimation: [0.03197869, -0.00268136, 0.03633939, -0.04904833, -9.187e-05, -0.01440655]\n", - "Relative errors in estimation: [0.06272417, -0.00477727, 0.10047642, 0.21319297, -0.00039233, 0.069078]\n" + "Errors in estimation: [-0.00311653, -0.04607736, -0.02365816, 0.05178174, 0.03439299, 0.02996601]\n", + "Relative errors in estimation: [-0.00611287, -0.08209407, -0.06541352, -0.22507399, 0.14687712, -0.14368403]\n" ] } ], @@ -467,7 +414,7 @@ { "data": { "text/html": [ - "

Version Information

Qiskit SoftwareVersion
qiskit-terra0.24.1
qiskit-aer0.12.1
qiskit-ibmq-provider0.20.2
qiskit0.43.2
qiskit-nature0.6.0
System information
Python version3.8.16
Python compilerClang 14.0.6
Python builddefault, Mar 1 2023 21:19:10
OSDarwin
CPUs8
Memory (Gb)32.0
Mon Aug 14 08:37:05 2023 CDT
" + "

Version Information

SoftwareVersion
qiskit0.44.1
qiskit-terra0.25.1
qiskit_aer0.12.1
qiskit_ibm_provider0.6.3
System information
Python version3.8.16
Python compilerClang 14.0.6
Python builddefault, Mar 1 2023 21:19:10
OSDarwin
CPUs8
Memory (Gb)32.0
Wed Aug 30 08:18:28 2023 CDT
" ], "text/plain": [ "" From f1850c68c02159ec7d02a5f69034dc7aa021e66e Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 08:20:46 -0500 Subject: [PATCH 07/40] diff --- .../cutting/cutting_evaluation.py | 130 +++++++++--------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 002c0ea59..2038c7d6d 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -174,6 +174,71 @@ def execute_experiments( return CuttingExperimentResults(quasi_dists, coefficients) +def _append_measurement_circuit( + qc: QuantumCircuit, + cog: CommutingObservableGroup, + /, + *, + qubit_locations: Sequence[int] | None = None, + inplace: bool = False, +) -> QuantumCircuit: + """Append a new classical register and measurement instructions for the given ``CommutingObservableGroup``. + + The new register will be named ``"observable_measurements"`` and will be + the final register in the returned circuit, i.e. ``retval.cregs[-1]``. + + Args: + qc: The quantum circuit + cog: The commuting observable set for + which to construct measurements + qubit_locations: A ``Sequence`` whose length is the number of qubits + in the observables, where each element holds that qubit's corresponding + index in the circuit. By default, the circuit and observables are assumed + to have the same number of qubits, and the identity map + (i.e., ``range(qc.num_qubits)``) is used. + inplace: Whether to operate on the circuit in place (default: ``False``) + + Returns: + The modified circuit + """ + if qubit_locations is None: + # By default, the identity map. + if qc.num_qubits != cog.general_observable.num_qubits: + raise ValueError( + f"Quantum circuit qubit count ({qc.num_qubits}) does not match qubit " + f"count of observable(s) ({cog.general_observable.num_qubits}). " + f"Try providing `qubit_locations` explicitly." + ) + qubit_locations = range(cog.general_observable.num_qubits) + else: + if len(qubit_locations) != cog.general_observable.num_qubits: + raise ValueError( + f"qubit_locations has {len(qubit_locations)} element(s) but the " + f"observable(s) have {cog.general_observable.num_qubits} qubit(s)." + ) + if not inplace: + qc = qc.copy() + + # Append the appropriate measurements to qc + obs_creg = ClassicalRegister(len(cog.pauli_indices), name="observable_measurements") + qc.add_register(obs_creg) + # Implement the necessary basis rotations and measurements, as + # in BackendEstimator._measurement_circuit(). + genobs_x = cog.general_observable.x + genobs_z = cog.general_observable.z + for clbit, subqubit in enumerate(cog.pauli_indices): + # subqubit is the index of the qubit in the subsystem. + # actual_qubit is its index in the system of interest (if different). + actual_qubit = qubit_locations[subqubit] + if genobs_x[subqubit]: + if genobs_z[subqubit]: + qc.sdg(actual_qubit) + qc.h(actual_qubit) + qc.measure(actual_qubit, obs_creg[clbit]) + + return qc + + def generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], @@ -442,71 +507,6 @@ def _get_bases(circuit: QuantumCircuit) -> tuple[list[QPDBasis], list[list[int]] return bases, qpd_gate_ids -def _append_measurement_circuit( - qc: QuantumCircuit, - cog: CommutingObservableGroup, - /, - *, - qubit_locations: Sequence[int] | None = None, - inplace: bool = False, -) -> QuantumCircuit: - """Append a new classical register and measurement instructions for the given ``CommutingObservableGroup``. - - The new register will be named ``"observable_measurements"`` and will be - the final register in the returned circuit, i.e. ``retval.cregs[-1]``. - - Args: - qc: The quantum circuit - cog: The commuting observable set for - which to construct measurements - qubit_locations: A ``Sequence`` whose length is the number of qubits - in the observables, where each element holds that qubit's corresponding - index in the circuit. By default, the circuit and observables are assumed - to have the same number of qubits, and the identity map - (i.e., ``range(qc.num_qubits)``) is used. - inplace: Whether to operate on the circuit in place (default: ``False``) - - Returns: - The modified circuit - """ - if qubit_locations is None: - # By default, the identity map. - if qc.num_qubits != cog.general_observable.num_qubits: - raise ValueError( - f"Quantum circuit qubit count ({qc.num_qubits}) does not match qubit " - f"count of observable(s) ({cog.general_observable.num_qubits}). " - f"Try providing `qubit_locations` explicitly." - ) - qubit_locations = range(cog.general_observable.num_qubits) - else: - if len(qubit_locations) != cog.general_observable.num_qubits: - raise ValueError( - f"qubit_locations has {len(qubit_locations)} element(s) but the " - f"observable(s) have {cog.general_observable.num_qubits} qubit(s)." - ) - if not inplace: - qc = qc.copy() - - # Append the appropriate measurements to qc - obs_creg = ClassicalRegister(len(cog.pauli_indices), name="observable_measurements") - qc.add_register(obs_creg) - # Implement the necessary basis rotations and measurements, as - # in BackendEstimator._measurement_circuit(). - genobs_x = cog.general_observable.x - genobs_z = cog.general_observable.z - for clbit, subqubit in enumerate(cog.pauli_indices): - # subqubit is the index of the qubit in the subsystem. - # actual_qubit is its index in the system of interest (if different). - actual_qubit = qubit_locations[subqubit] - if genobs_x[subqubit]: - if genobs_z[subqubit]: - qc.sdg(actual_qubit) - qc.h(actual_qubit) - qc.measure(actual_qubit, obs_creg[clbit]) - - return qc - - def _validate_samplers(samplers: BaseSampler | dict[str | int, BaseSampler]) -> None: """Replace unsupported statevector-based Samplers with ExactSampler.""" if isinstance(samplers, BaseSampler): From 42be3769d08b48357f2f6b23b9bb9579e8eb521d Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 08:41:04 -0500 Subject: [PATCH 08/40] cleanup --- circuit_knitting/cutting/cutting_evaluation.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 2038c7d6d..9e1eedbe3 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -331,14 +331,8 @@ def generate_cutting_experiments( sorted_samples = sorted(random_samples.items(), key=lambda x: x[1][0], reverse=True) subexperiments_legacy: list[list[list[QuantumCircuit]]] = [] - weights_legacy: list[tuple[float, WeightType]] = [] for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): subexperiments_legacy.append([]) - actual_coeff = np.prod( - [basis.coeffs[map_id] for basis, map_id in strict_zip(bases, map_ids)] - ) - sampled_coeff = (redundancy / num_samples) * (kappa * np.sign(actual_coeff)) - weights_legacy.append((sampled_coeff, weight_type)) for i, (subcircuit, label) in enumerate( strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) ): From 74e427c8159481dfd39e93d2faa6276ed0d7a215 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 08:42:13 -0500 Subject: [PATCH 09/40] cleanup --- .../cutting/cutting_evaluation.py | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 9e1eedbe3..b62b5b8fe 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -330,24 +330,6 @@ def generate_cutting_experiments( # Sort samples in descending order of frequency sorted_samples = sorted(random_samples.items(), key=lambda x: x[1][0], reverse=True) - subexperiments_legacy: list[list[list[QuantumCircuit]]] = [] - for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): - subexperiments_legacy.append([]) - for i, (subcircuit, label) in enumerate( - strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) - ): - map_ids_tmp = map_ids - if is_separated: - map_ids_tmp = tuple(map_ids[j] for j in subcirc_map_ids[i]) - decomp_qc = decompose_qpd_instructions( - subcircuit, subcirc_qpd_gate_ids[i], map_ids_tmp - ) - subexperiments_legacy[-1].append([]) - so = subsystem_observables[label] - for j, cog in enumerate(so.groups): - meas_qc = _append_measurement_circuit(decomp_qc, cog) - subexperiments_legacy[-1][-1].append(meas_qc) - # Generate the output experiments and weights subexperiments_dict: dict[str | int, list[QuantumCircuit]] = defaultdict(list) weights: list[tuple[float, WeightType]] = [] @@ -372,6 +354,25 @@ def generate_cutting_experiments( meas_qc = _append_measurement_circuit(decomp_qc, cog) subexperiments_dict[label].append(meas_qc) + # Generate legacy subexperiments list + subexperiments_legacy: list[list[list[QuantumCircuit]]] = [] + for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): + subexperiments_legacy.append([]) + for i, (subcircuit, label) in enumerate( + strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) + ): + map_ids_tmp = map_ids + if is_separated: + map_ids_tmp = tuple(map_ids[j] for j in subcirc_map_ids[i]) + decomp_qc = decompose_qpd_instructions( + subcircuit, subcirc_qpd_gate_ids[i], map_ids_tmp + ) + subexperiments_legacy[-1].append([]) + so = subsystem_observables[label] + for j, cog in enumerate(so.groups): + meas_qc = _append_measurement_circuit(decomp_qc, cog) + subexperiments_legacy[-1][-1].append(meas_qc) + # If the circuit wasn't separated, return the subexperiments as a list subexperiments_out: list[QuantumCircuit] | dict[ str | int, list[QuantumCircuit] From f06f79c53833f78a2fcd86222f46353f101c9510 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 14:31:44 -0500 Subject: [PATCH 10/40] Update circuit_knitting/cutting/cutting_evaluation.py Co-authored-by: Jim Garrison --- circuit_knitting/cutting/cutting_evaluation.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index b62b5b8fe..137049952 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -378,8 +378,9 @@ def generate_cutting_experiments( str | int, list[QuantumCircuit] ] = subexperiments_dict assert isinstance(subexperiments_out, dict) - if len(subexperiments_out.keys()) == 1: - subexperiments_out = subexperiments_dict[list(subexperiments_dict.keys())[0]] + if isinstance(circuits, QuantumCircuit): + assert len(subexperiments_out.keys()) == 1 + subexperiments_out = list(subexperiments_dict.values())[0] return subexperiments_out, weights, subexperiments_legacy From dd42cb42d44d82366fdbfa8e5576122b2b23640a Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 14:45:20 -0500 Subject: [PATCH 11/40] Fix tests --- test/cutting/test_cutting_decomposition.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index ca31c4381..56e02c16b 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -337,9 +337,9 @@ def test_generate_cutting_experiments(self): {"A": qc}, {"A": PauliList(["ZY"])}, np.inf ) assert weights == comp_weights - assert len(weights) == len(subexperiments) - for exp in subexperiments: - assert isinstance(exp, QuantumCircuit) + assert len(weights) == len(subexperiments["A"]) + for circ in subexperiments["A"]: + assert isinstance(circ, QuantumCircuit) with self.subTest("test bad num_samples"): qc = QuantumCircuit(4) From 951c86b62b179031d33d996b60ea8c5588595581 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 15:17:23 -0500 Subject: [PATCH 12/40] peer review --- .../cutting/cutting_evaluation.py | 59 +++++++++++++------ test/cutting/test_cutting_decomposition.py | 4 +- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 137049952..85fe1b7d4 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -123,7 +123,7 @@ def execute_experiments( _, coefficients, subexperiments, - ) = generate_cutting_experiments( + ) = _generate_cutting_experiments( circuits, subobservables, num_samples, @@ -246,17 +246,17 @@ def generate_cutting_experiments( ) -> tuple[ list[QuantumCircuit] | dict[str | int, list[QuantumCircuit]], list[tuple[float, WeightType]], - list[list[list[QuantumCircuit]]], ]: """ Generate cutting subexperiments and their associated weights. - If the input circuit and observables are not split into multiple partitions, the output - subexperiments will be contained within a 1D array. + If the input, ``circuits``, is a :class:`QuantumCircuit` instance, the + output subexperiments will be contained within a 1D array, and ``observables`` is + expected to be a :class:`PauliList` instance. - If the input circuit and observables is split into multiple partitions, the output - subexperiments will be returned as a dictionary which maps a partition label to to - a 1D array containing the subexperiments associated with that partition. + If the input circuit and observables are specified by dictionaries with partition labels + as keys, the output subexperiments will be returned as a dictionary which maps a + partition label to to a 1D array containing the subexperiments associated with that partition. In both cases, the subexperiment lists are ordered as follows: :math:`[sample_{0}observable_{0}, sample_{0}observable_{1}, ..., sample_{0}observable_{N}, ..., sample_{M}observable_{N}]` @@ -281,10 +281,34 @@ def generate_cutting_experiments( Raises: ValueError: ``num_samples`` must either be an integer or infinity. + ValueError: ``circuits`` and ``observables`` are incompatible types ValueError: :class:`SingleQubitQPDGate` instances must have the cut number appended to the gate label. ValueError: :class:`SingleQubitQPDGate` instances are not allowed in unseparated circuits. """ + subexperiments, weights, _ = _generate_cutting_experiments( + circuits, observables, num_samples + ) + return subexperiments, weights + + +def _generate_cutting_experiments( + circuits: QuantumCircuit | dict[str | int, QuantumCircuit], + observables: PauliList | dict[str | int, PauliList], + num_samples: int | float, +) -> tuple[ + list[QuantumCircuit] | dict[str | int, list[QuantumCircuit]], + list[tuple[float, WeightType]], + list[list[list[QuantumCircuit]]], +]: + if isinstance(circuits, QuantumCircuit) and not isinstance(observables, PauliList): + raise ValueError( + "If the input circuits is a QuantumCircuit, the observables must be a PauliList." + ) + if isinstance(circuits, dict) and not isinstance(observables, dict): + raise ValueError( + "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." + ) if isinstance(num_samples, float): if num_samples != np.inf: raise ValueError("num_samples must either be an integer or infinity.") @@ -333,17 +357,16 @@ def generate_cutting_experiments( # Generate the output experiments and weights subexperiments_dict: dict[str | int, list[QuantumCircuit]] = defaultdict(list) weights: list[tuple[float, WeightType]] = [] - for i, (subcircuit, label) in enumerate( - strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) - ): - for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): - actual_coeff = np.prod( - [basis.coeffs[map_id] for basis, map_id in strict_zip(bases, map_ids)] - ) - sampled_coeff = (redundancy / num_samples) * (kappa * np.sign(actual_coeff)) - if i == 0: - weights.append((sampled_coeff, weight_type)) - map_ids_tmp = map_ids + for z, (map_ids, (redundancy, weight_type)) in enumerate(sorted_samples): + actual_coeff = np.prod( + [basis.coeffs[map_id] for basis, map_id in strict_zip(bases, map_ids)] + ) + sampled_coeff = (redundancy / num_samples) * (kappa * np.sign(actual_coeff)) + weights.append((sampled_coeff, weight_type)) + map_ids_tmp = map_ids + for i, (subcircuit, label) in enumerate( + strict_zip(subcircuit_list, sorted(subsystem_observables.keys())) + ): if is_separated: map_ids_tmp = tuple(map_ids[j] for j in subcirc_map_ids[i]) decomp_qc = decompose_qpd_instructions( diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 56e02c16b..38d533b90 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -303,7 +303,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights, _ = generate_cutting_experiments( + subexperiments, weights = generate_cutting_experiments( qc, PauliList(["ZZ"]), np.inf ) assert weights == comp_weights @@ -333,7 +333,7 @@ def test_generate_cutting_experiments(self): (0.5, WeightType.EXACT), (-0.5, WeightType.EXACT), ] - subexperiments, weights, _ = generate_cutting_experiments( + subexperiments, weights = generate_cutting_experiments( {"A": qc}, {"A": PauliList(["ZY"])}, np.inf ) assert weights == comp_weights From 2f09338662d66e386c93aa6ad3568e25b36f7726 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:00:18 -0500 Subject: [PATCH 13/40] coverage --- .../cutting/cutting_evaluation.py | 33 +++++++++---------- test/cutting/test_cutting_decomposition.py | 28 +++++++++++++--- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 85fe1b7d4..0348b0508 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -282,8 +282,9 @@ def generate_cutting_experiments( Raises: ValueError: ``num_samples`` must either be an integer or infinity. ValueError: ``circuits`` and ``observables`` are incompatible types - ValueError: :class:`SingleQubitQPDGate` instances must have the cut number - appended to the gate label. + ValueError: :class:`SingleQubitQPDGate` instances must have their cut ID + appended to the gate label so they may be associated with other gates belonging + to the same cut. ValueError: :class:`SingleQubitQPDGate` instances are not allowed in unseparated circuits. """ subexperiments, weights, _ = _generate_cutting_experiments( @@ -473,7 +474,15 @@ def _get_mapping_ids_by_partition( try: decomp_id = int(inst.operation.label.split("_")[-1]) except (AttributeError, ValueError): - _raise_bad_qpd_gate_labels() + raise ValueError( + "BaseQPDGate instances in input circuit(s) must have their " + 'labels suffixed with "_", where is the index of the gate ' + "relative to the other gates belonging to the same cut. For example, " + "a two-qubit gate can be represented by two SingleQubitQPDGates -- one " + 'labeled "_0" and one labeled "_1".' + " This allows SingleQubitQPDGates belonging to the same cut to be " + "sampled together." + ) decomp_ids.add(decomp_id) subcirc_qpd_gate_ids[-1].append([i]) subcirc_map_ids[-1].append(decomp_id) @@ -481,14 +490,6 @@ def _get_mapping_ids_by_partition( return subcirc_qpd_gate_ids, subcirc_map_ids -def _raise_bad_qpd_gate_labels() -> None: - raise ValueError( - "BaseQPDGate instances in input circuit(s) should have their " - 'labels suffixed with "_" so that sibling SingleQubitQPDGate ' - "instances may be grouped and sampled together." - ) - - def _get_bases_by_partition( circuits: Sequence[QuantumCircuit], subcirc_qpd_gate_ids: list[list[list[int]]] ) -> list[QPDBasis]: @@ -497,13 +498,9 @@ def _get_bases_by_partition( bases_dict = {} for i, subcirc in enumerate(subcirc_qpd_gate_ids): for basis_id in subcirc: - try: - decomp_id = int( - circuits[i].data[basis_id[0]].operation.label.split("_")[-1] - ) - except (AttributeError, ValueError): # pragma: no cover - _raise_bad_qpd_gate_labels() # pragma: no cover - + decomp_id = int( + circuits[i].data[basis_id[0]].operation.label.split("_")[-1] + ) bases_dict[decomp_id] = circuits[i].data[basis_id[0]].operation.basis bases = [bases_dict[key] for key in sorted(bases_dict.keys())] diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 38d533b90..b7a92a372 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -349,6 +349,20 @@ def test_generate_cutting_experiments(self): e_info.value.args[0] == "num_samples must either be an integer or infinity." ) + with self.subTest("test incompatible inputs"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, {"A": PauliList(["ZZZZ"])}, 4.5) + assert ( + e_info.value.args[0] + == "If the input circuits is a QuantumCircuit, the observables must be a PauliList." + ) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments({"A": qc}, PauliList(["ZZZZ"]), 4.5) + assert ( + e_info.value.args[0] + == "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." + ) with self.subTest("test bad label"): qc = QuantumCircuit(2) qc.append( @@ -359,16 +373,22 @@ def test_generate_cutting_experiments(self): qc, "AB", observables=PauliList(["ZZ"]) ) partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" + comp_string = ( + "BaseQPDGate instances in input circuit(s) must have their " + 'labels suffixed with "_", where is the index of the gate ' + "relative to the other gates belonging to the same cut. For example, " + "a two-qubit gate can be represented by two SingleQubitQPDGates -- one " + 'labeled "_0" and one labeled "_1".' + " This allows SingleQubitQPDGates belonging to the same cut to be " + "sampled together." + ) with pytest.raises(ValueError) as e_info: generate_cutting_experiments( partitioned_problem.subcircuits, partitioned_problem.subobservables, np.inf, ) - assert e_info.value.args[0] == ( - "BaseQPDGate instances in input circuit(s) should have their labels suffixed with " - '"_" so that sibling SingleQubitQPDGate instances may be grouped and sampled together.' - ) + assert e_info.value.args[0] == comp_string with self.subTest("test bad observable size"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: From 1498cc93bd01f7e67a85ade54751c396381abe84 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:03:20 -0500 Subject: [PATCH 14/40] peer review --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 0348b0508..b0eb1886a 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -311,7 +311,7 @@ def _generate_cutting_experiments( "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." ) if isinstance(num_samples, float): - if num_samples != np.inf: + if not num_samples >= 1: raise ValueError("num_samples must either be an integer or infinity.") # Retrieving the unique bases, QPD gates, and decomposed observables is slightly different From 75bad4452960b558e5085e49b7c756606b1333c9 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:08:53 -0500 Subject: [PATCH 15/40] Update cutting_evaluation.py --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index b0eb1886a..0d9dbb433 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -475,7 +475,7 @@ def _get_mapping_ids_by_partition( decomp_id = int(inst.operation.label.split("_")[-1]) except (AttributeError, ValueError): raise ValueError( - "BaseQPDGate instances in input circuit(s) must have their " + "SingleQubitQPDGate instances in input circuit(s) must have their " 'labels suffixed with "_", where is the index of the gate ' "relative to the other gates belonging to the same cut. For example, " "a two-qubit gate can be represented by two SingleQubitQPDGates -- one " From d5cbd67a2008f637fce67f74e68513fc0a9d4836 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:11:44 -0500 Subject: [PATCH 16/40] Update cutting_evaluation.py --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 0d9dbb433..298e613eb 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -397,7 +397,7 @@ def _generate_cutting_experiments( meas_qc = _append_measurement_circuit(decomp_qc, cog) subexperiments_legacy[-1][-1].append(meas_qc) - # If the circuit wasn't separated, return the subexperiments as a list + # If the input was a single quantum circuit, return the subexperiments as a list subexperiments_out: list[QuantumCircuit] | dict[ str | int, list[QuantumCircuit] ] = subexperiments_dict From b2b48c0b23f6891e3b5e2ffa8d191da85031f096 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:28:50 -0500 Subject: [PATCH 17/40] fix broken tests --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- test/cutting/test_cutting_decomposition.py | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 298e613eb..89c9ef51f 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -312,7 +312,7 @@ def _generate_cutting_experiments( ) if isinstance(num_samples, float): if not num_samples >= 1: - raise ValueError("num_samples must either be an integer or infinity.") + raise ValueError("num_samples must be positive.") # Retrieving the unique bases, QPD gates, and decomposed observables is slightly different # depending on the format of the execute_experiments input args, but the 2nd half of this function diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index b7a92a372..2fe15fbf0 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -344,11 +344,8 @@ def test_generate_cutting_experiments(self): with self.subTest("test bad num_samples"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 4.5) - assert ( - e_info.value.args[0] - == "num_samples must either be an integer or infinity." - ) + generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 0) + assert e_info.value.args[0] == "num_samples must be at least 1." with self.subTest("test incompatible inputs"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: @@ -374,7 +371,7 @@ def test_generate_cutting_experiments(self): ) partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" comp_string = ( - "BaseQPDGate instances in input circuit(s) must have their " + "SingleQubitQPDGate instances in input circuit(s) must have their " 'labels suffixed with "_", where is the index of the gate ' "relative to the other gates belonging to the same cut. For example, " "a two-qubit gate can be represented by two SingleQubitQPDGates -- one " From ab3753c67936da7b642a67256955e9bf99f95ac2 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:35:30 -0500 Subject: [PATCH 18/40] Better error --- circuit_knitting/cutting/cutting_evaluation.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 89c9ef51f..cdf228a92 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -70,7 +70,7 @@ def execute_experiments( sampling frequency Raises: - ValueError: The number of requested samples must be positive. + ValueError: The number of requested samples must be greater than one. ValueError: The types of ``circuits`` and ``subobservables`` arguments are incompatible. ValueError: ``SingleQubitQPDGate``\ s are not supported in unseparable circuits. ValueError: The keys for the input dictionaries are not equivalent. @@ -78,7 +78,7 @@ def execute_experiments( ValueError: If multiple samplers are passed, each one must be unique. """ if num_samples <= 0: - raise ValueError("The number of requested samples must be positive.") + raise ValueError("The number of requested samples must be at least 1.") if isinstance(circuits, dict) and not isinstance(subobservables, dict): raise ValueError( @@ -280,7 +280,7 @@ def generate_cutting_experiments( weight and the :class:`WeightType`. Each weight corresponds to one unique sample. Raises: - ValueError: ``num_samples`` must either be an integer or infinity. + ValueError: ``num_samples`` must either be greater than one. ValueError: ``circuits`` and ``observables`` are incompatible types ValueError: :class:`SingleQubitQPDGate` instances must have their cut ID appended to the gate label so they may be associated with other gates belonging @@ -312,7 +312,7 @@ def _generate_cutting_experiments( ) if isinstance(num_samples, float): if not num_samples >= 1: - raise ValueError("num_samples must be positive.") + raise ValueError("num_samples must be at least 1.") # Retrieving the unique bases, QPD gates, and decomposed observables is slightly different # depending on the format of the execute_experiments input args, but the 2nd half of this function From 76510ba87c150f6b8a5dbffee1c37fca5cc67005 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:36:50 -0500 Subject: [PATCH 19/40] fix miswording --- circuit_knitting/cutting/cutting_evaluation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index cdf228a92..af1997385 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -70,7 +70,7 @@ def execute_experiments( sampling frequency Raises: - ValueError: The number of requested samples must be greater than one. + ValueError: The number of requested samples must be at least one. ValueError: The types of ``circuits`` and ``subobservables`` arguments are incompatible. ValueError: ``SingleQubitQPDGate``\ s are not supported in unseparable circuits. ValueError: The keys for the input dictionaries are not equivalent. @@ -280,7 +280,7 @@ def generate_cutting_experiments( weight and the :class:`WeightType`. Each weight corresponds to one unique sample. Raises: - ValueError: ``num_samples`` must either be greater than one. + ValueError: ``num_samples`` must either be at least one. ValueError: ``circuits`` and ``observables`` are incompatible types ValueError: :class:`SingleQubitQPDGate` instances must have their cut ID appended to the gate label so they may be associated with other gates belonging From b35e4853a3e770a8793f3d4029095f0e77763497 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:42:11 -0500 Subject: [PATCH 20/40] update test --- test/cutting/test_cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cutting/test_cutting_evaluation.py b/test/cutting/test_cutting_evaluation.py index 469c56a9d..ee71bd0b9 100644 --- a/test/cutting/test_cutting_evaluation.py +++ b/test/cutting/test_cutting_evaluation.py @@ -215,7 +215,7 @@ def test_execute_experiments(self): ) assert ( e_info.value.args[0] - == "The number of requested samples must be positive." + == "The number of requested samples must be at least 1." ) with self.subTest("Dict of non-unique samplers"): qc = QuantumCircuit(2) From 7788198c6379e1b0abf2eeeffd9778e62d88fc28 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:45:31 -0500 Subject: [PATCH 21/40] dont change tut2 --- .../02_gate_cutting_to_reduce_circuit_depth.ipynb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb b/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb index 979571417..e18d2bfc9 100644 --- a/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb +++ b/docs/circuit_cutting/tutorials/02_gate_cutting_to_reduce_circuit_depth.ipynb @@ -252,7 +252,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABs0AAAE2CAYAAAAqK9xEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACMWElEQVR4nOzdd3gU5drH8e+mEtIgoYQSeu+9KCBVQBApIgJSVLAgKIp4REVBEcXz2rBgQbEgIhY8gkcpERCU3jtICwFCDySkkLLvH3sILGmbZMtk9/e5Li6SaXtv7pnnmd175hmT2Ww2IyIiIiIiIiIiIiIiIuLBvFwdgIiIiIiIiIiIiIiIiIirqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgOK5p17NiR8ePHO3wdo25DREREREREREREREREio4CFc1iY2N54oknqFGjBsWKFaNs2bLceuutzJo1i8TERHvHaFcjR47EZDJhMpnw8/OjRo0avPzyy6Slpbk6NIe5//77eeGFF7JMf/311zGZTCoQioiIiIiIiIiIiIiIx/PJ7wqHDx/m1ltvpUSJEkyfPp2GDRvi7+/Pzp07+eSTT6hQoQJ9+vRxRKx206NHD+bMmUNKSgr//e9/eeyxx/D19WXSpEmuDs3u0tPTWbx4Mb/++qvV9I0bN/Lxxx/TqFEjF0UmIiIiIiIiIiIiIiJiHPm+02zMmDH4+PiwadMm7rnnHurWrUu1atW46667+PXXX7nzzjuzXS8lJYXHH3+cMmXKUKxYMdq1a8fGjRuzLJeWlsbYsWMJDQ2lVKlSTJ48GbPZDMDvv/9Ou3btKFGiBOHh4fTu3ZtDhw7l9y3g7+9PREQElStX5tFHH6Vr16788ssvVstkZGTwzDPPEBYWRkREBFOmTMmcZ0scP/zwAw0bNiQgIIDw8HC6du3KlStXMrf92muvUbVqVQICAmjcuDE//PBDvt9H3bp1M++au/nf+++/D8Dff/+Nr68vLVu2zFwvISGBoUOH8umnn1KyZMl8v66IiIiIiIiIiIiIiIi7yVfR7Pz58yxdupTHHnuMwMDAbJcxmUzZTn/mmWf48ccf+fLLL9myZQs1atSge/fuXLhwwWq5L7/8Eh8fHzZs2MC7777LW2+9xezZswG4cuUKTz31FJs2bSIqKgovLy/69etHRkZGft5GFgEBAVy9ejVLHIGBgaxfv5433niDl19+mWXLltkUx6lTpxg8eDAPPPAAe/fuZeXKlfTv3z+z+Pfaa6/x1Vdf8dFHH7F7926efPJJ7rvvPlatWpX5+l988UWOf8trfvzxRwCioqI4deoUR48excvLi++//57Ro0cD8Msvv3DnnXdabeuxxx6jV69edO3atVB/NxEREREREREREREREXeRr+EZ//nnH8xmM7Vr17aaXqpUKZKTkwFLQWbGjBlW869cucKsWbP44osv6NmzJwCffvopy5Yt47PPPmPixImZy0ZGRvL2229jMpmoXbs2O3fu5O2332b06NEMGDDAaruff/45pUuXZs+ePTRo0CA/bwUAs9lMVFQUS5YsYdy4cVbzGjVqxEsvvQRAzZo1ef/994mKiqJbt255xnHq1CnS0tLo378/lStXBqBhw4aA5Y676dOns3z5ctq2bQtAtWrVWLNmDR9//DG33XYbAKGhoVn+zjc7ffo0Pj4+3Hrrrfj7+7N582YyMjJo3749/v7+APznP//h7bffzlxn/vz5bNmyJdu7/ERERERERERERERERDxVvodnzM6GDRvYtm0b9evXJyUlJcv8Q4cOkZqayq233po5zdfXl1atWrF3716rZdu0aWN1V1Tbtm05ePAg6enpHDx4kMGDB1OtWjVCQkKoUqUKANHR0fmKd/HixQQFBVGsWDF69uzJoEGDrIZfBLI866tcuXKcOXMGIM84GjduTJcuXWjYsCEDBw7k008/5eLFi4Cl8JiYmEi3bt0ICgrK/PfVV19ZDfHYr18/9u3bl+v72LlzJ7Vq1coskG3fvp0yZcpQtmxZAPbu3cvJkyfp0qULAMePH+eJJ57gm2++oVixYvn6m4mIiIiIiIiIiIiIiLizfN1pVqNGDUwmE/v377eaXq1aNcAyzKEj3XnnnVSuXJlPP/2U8uXLk5GRQYMGDbIMrZiXTp06MWvWLPz8/Chfvjw+Pln/DL6+vla/m0ymzOEX84rD29ubZcuW8ffff7N06VLee+89nn/+edavX09CQgIAv/76KxUqVLB6jWvFL1vt2LEj8w42sBTNbvz9l19+oVu3bpkFss2bN3PmzBmaNWuWuUx6ejp//vkn77//PikpKXh7e+crBhEREREREREREREREXeQrzvNwsPD6datG++//z5Xrlyxeb3q1avj5+fHX3/9lTktNTWVjRs3Uq9ePatl169fb/X7unXrqFmzJnFxcezfv58XXniBLl26ULdu3cy7t/IrMDCQGjVqUKlSpWwLZrk5f/68TXGYTCZuvfVWpk6dytatW/Hz82PhwoXUq1cPf39/oqOjqVGjhtW/yMjIfMWyY8cOqzvitm/fbvX7f/7zH+66667M37t06cLOnTvZtm1b5r8WLVowdOhQtm3bpoKZiIiIiIiIiIiIiIh4rPxVjIAPP/yQW2+9lRYtWjBlyhQaNWqEl5cXGzduZN++fTRv3jzLOoGBgTz66KNMnDiRsLAwKlWqxBtvvEFiYiIPPvig1bLR0dE89dRTPPzww2zZsoX33nuPN998k5IlSxIeHs4nn3xCuXLliI6O5tlnny34Oy8gW+JYv349UVFR3H777ZQpU4b169dz9uxZ6tatS3BwME8//TRPPvkkGRkZtGvXjkuXLvHXX38REhLCiBEjAFi4cCGTJk3KcYjGjIwMdu/ezYsvvpg57dChQ/Tv3x+AM2fOsGnTJn755ZfM+cHBwVme/RYYGEh4eHiBngknIiIiIiIiIiIiIiLiLvJdNKtevTpbt25l+vTpTJo0iZiYGPz9/alXrx5PP/00Y8aMyXa9119/nYyMDIYNG0Z8fDwtWrRgyZIllCxZ0mq54cOHk5SURKtWrfD29uaJJ57goYcewmQyMX/+fB5//HEaNGhA7dq1mTlzJh07dizQGy8oLy+vPOMICQnhzz//5J133uHy5ctUrlyZN998k549ewLwyiuvULp0aV577TUOHz5MiRIlaNasGc8991zmNi5dupRlGMwbHTp0iMTERKs7yxo2bMhLL71E8+bN2bdvH61ataJUqVL2/yOIiIiIiIiIiIiIiIi4GZPZbDa7Ogixvz59+tCuXTueeeYZV4ciIiIiIiIiIiIiIiJiePl6ppkUHe3atWPw4MGuDkNERERERERERERERKRI0J1mIiIiIiIiIiIiIiIi4vF0p5mIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj6eimYiIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHs/H1QGISP5tWwhJca6OAgJKQJN+hdvGpyvhfII9oim88CAY3bFw21BuHEO5cW9G2dfcaT8D92oHlBspSoyyr7lTGwDu1Q4oN1m5U27cTZ8+fTh06JCrw6B69er88ssvhdqGUfYzcK92wJ3aAFA7cDOj7GfgXvuaO7UBoNyI+1HRTKQISoqDK+ddHYV9nE+A2EuujsJ+lBvjcqfcuBt32tfcbT9TbkTyz532NXdqA0C5MTJ3yo27OXToEHv27HF1GHbhbvuZO7UD7pYbd+JO+xm4176m3Ig4joZnFBEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8Xg+rg5ARBznjfkjWbb5SwC8TF6EhZSjSfXOPHjHa5QKreDi6DybcmNcyo04i/Y141JuxBm0nxmXcmNcyo04i/Y141JuxBm0nxmXciPOoDvNRNxcw6rt+W7yKb55PppJQ+bxz8mtvPL1QFeHJSg3RqbciLNoXzMu5UacQfuZcSk3xqXciLNoXzMu5UacQfuZcSk34mi600zEzfl4+xEWEgFAqdAK9Gr9EB/853GuJF8msFiIi6MruPS0q7w/0r/A6z8x12zHaApGucmeciO20r5mXMqNiG3cdT9TG2Bcyo0UBcWKFSM5OdnVYbjtvqZ2QJxB+5lxKTcieVPRTKQQMjIyePfdd/n44485evQopUuX5p577uHll18mMDDQ1eFlce7SSf7c+QNeXt54eXm7OpxCidm7kvtm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iIiIiIiIiIiIiMfT8IwiRVBACVdHYGGPOMKDCr8Ne7FHLMqNYyg37s0o+5o77WfgXu2AciNFiVHy605tALhXO6DcZOVOuXE31atXL9B6GRkZnL1wCYCwEiFciLsMQOmwULy88n/9dkHjuJGR8utO7YA7tQFgrFiMwCj7GbjXvuZObQAoN+J+TGaz2ezqIERERMR54hJhykLLz1P6QYniro1HRKQw1KaJiBjPpcsJvDZrHgCPDevLB1//DMCkR4cQGmKgb3pFDEjnNiIirqXhGUVERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj+fj6gBEJP8+XQnnE1wdBYQHweiOhdvGtoWQFGePaAovoAQ06Ve4bSg3jmGP3Ig4g1HaAHCvdsCd2mdQbqTo0HHjGGrTsnKn3IiIiHEZpf90p74T3OvcRrkRUNFMpEg6nwCxl1wdhX0kxcGV866Own6UGxHP5k5tALhXO6DciOSfjhvjUm5ERETyz536T3frO5UbMRINzygiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiHgQsxku3DBO+OnLkJ7hunhERArDbIYLV67/fvoSpKW7Lh4RERGRwriaBifjrv9+OclloYiIeCw900xERMTNpaXD9uOw4TBEn4ekq9fnzYoCHy8oXxKaVoZW1SDQ33WxiojkJS0ddsbA+kOWNi3xxjbtD/D2ggoloUklS5sWVMx1sYqIiIjk5UIC/P0P7I6B2MuWi4Kueet3CCkGVctA2xpQKwK8TK6LVUTEE6hoJiJFxhvzR7Js85cAeJm8CAspR5PqnXnwjtcoFVrBxdF5NuXGmMxmS6Fs0TZISM55ubQMyxfP0efhv9uhfW3o2Qh8vZ0WqhRxagOMy51yYzbD5qPwyxa4nEub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I9qF+masimaOaNOqllWblhd3O26UG8dw5Tn0pcsJmT+XKV028+dyEeUIDbH9cQgiIo4WGQ6Hz17/3RHnNo1qhFGuRFjBAsyBUfpOcK/+053Oa0C5Kaicy5gidubn58fw4cPZtGkTd911F5988gmTJ0+mdevWhIdbHvx3c9Hs2WefJSEhgT179vDII49Qrly5fL2m2WzOdWjG0NBQVq1aVaA7zB599FHatGnDc889x8cff8y7776b+UD24OBg3nzzzXxv056qNunFkW2LOX14I2Wrt8p2mQsn9rJm/jPcNuxdGnd/nOWzR5EUf87JkXoe5UbEs1QrDdncZG1XNco4dvu5UZtmXMqNMVSqVInixS0P+d6+fXuey9taMAPLw7D37t0LQN26de0XdC6qlgYvR7dpZfNexlF03BiXciMiIo7g6POOoGJQNsSxr5ET9Z3GpdwYm4pm4lQzZ87koYceYv369UyYMIH169ezcOFCypcvT/HixalVq1a269WtW5fGjRszbNgwu8eU3XCRthg8eDClSpXi66+/5oknnuDZZ59lw4YNPPzww+zYsSNLAdDZAkuWIzUpntSridm+x/S0VJbMuo/I+l1p0Gk0t97zGgHB4UR9/rALovUsyo2IZwktDg0qOG77gf7QKNJx28/z9dWmGZZyYwxJSUl88sknfPXVV5w/fz7P5WfPnm1TweyaH374gdmzZ7Nv3z57hZyroGKObXMC/KBJJcdtPy86boxLuREREUdoUx0ceT1Q2+rg5aJv4NV3GpdyY2wqmolTBQUF8fHHHxMbG0t8fDxLly6lbdu27Nq1i4YNG+KVSy+Smpqa5fkQrnTPPfewePFijh8/TnJyMklJSezbt4/33nuPSpVc+En/BpUadiO0TLVs56378UXiL8TQddRsAHz8itH90bkc2bKIvau/cmaYHkm5EfEsHWo7btu31AAfb8dt3xZq04xLuXG92NhYHn74YUaMGEFSUt5j+EyePJno6GibCmYAr776KqNHj2bp0qX2CNcmjmzT2lQHPxc/REDHjXEpNyIiYm9hQdDQQRcEeXvBLTUds21bqe80LuXGuPRMM3G5uLg4YmJi6NXr+pisly5dYuHChfTt25fQ0FB27tzJtGnT6N69uwsjLXrqdxyFX0DWe8BP7F/D5l//Te/xCykeen1Mr9KVm9BmwFRWfv04Fep2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j1iUG8cwUiwinkRtmmOov7HmbrmpXr16gdbLyMjg7AXLJalhJUK4EHcZgNJhoXgV4CFgBY3Dnem4cQy1adbcLTciImJMRuk7wb36T3c6rwHlpqA0PKOIiIiIiIiLaSgzEXEnatNERESkqNLwjCIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj6eimYiIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0EykCUlJSuP/++6lYsSKhoaF06tSJ3bt3uzosERERETGYM2fO0KNHD4oXL06DBg1Yt26dq0MSESmwl156iXr16uHl5cX8+fNdHY6IiIh4ABXNRIqAtLQ0qlWrxrp167hw4QJ33nknffv2dXVYIiIiImIwjzzyCNWqVeP8+fNMnDiRAQMGkJKS4uqwREQKpGbNmrz77ru0atXK1aGIiIiIh1DRTKQICAwMZPLkyVSsWBFvb2/Gjh3LoUOHOH/+vKtDExERERGDiI+PZ/Hixbz00ksEBAQwYsQIgoODWblypatDExEpkPvuu49u3bpRrFgxV4ciIiIiHkJFM5EiaO3atZQpU4bw8HBXhyIiIiIiBnHw4EFKlChB2bJlM6c1bNiQPXv2uDAqERERERGRosPH1QGISP7ExcXx0EMPMX36dFeHIiIiIiIFZDabWbp6E5fjrwBwNTU1c17UX5szf178x1r8fH0tv5igx22tCA4snu02r1y5QkhIiNW0kJAQEhIS7By9iIg1s9nM8r82E3fJ0t7Y1KYB3Tu0JCQ40HmBioiIiORBRTORIiQ5OZm77rqL3r1788ADD7g6HBEREREpIJPJRNXIcny+4L9Z5u07fDzz5537j2T+fEvz+jkWzMAypHd8fLzVtMuXLxMUFGSHiEVEcmYymahWqTyzv12M+aZ5ObVprRrXUcFMREREDEfDM4oUEenp6dx7771ERkbyf//3f64OR0REREQKqVbVirRtVt+mZUuHlaDHba1zXaZmzZpcvHiR06dPZ07btWsX9erVK1ScIiK2qF6pPO1aNrJp2fASIfTq3NbBEYmIiIjkn4pmIkXE6NGjSU5OZs6cOZhMJleHIyIiIiJ20LNja0qHhea6jJeXiUG9O+Hnm/tAIcHBwfTu3ZtXXnmF5ORkvv76ay5fvkzHjh3tGLGISM5u79CCsqVK5rqMyWTint6d8PfzzXU5gNTUVJKTk8nIyLD6WURERMRRVDTLgclkYuTIka4OQwSAY8eOMWfOHFatWkXJkiUJCgoiKCiI1atXuzo0ERERESkEP18f7undCa9cLorqfEszKpYrbdP2Zs2axcGDBwkLC+P111/nxx9/xN/f317hiojkytfHh0G9O+HtlfPXTR3bNKZyhbI2bW/06NEEBASwevVqhg8fTkBAAH/++ae9whURERHJwmQ2m28eblqwFM1GjBjBF1984epQxACOHj3KF198Qd++fWnSpImrw8ni3MVL+Hh7UyJEz6sQERERKYqWr9nM8r82Z5keWa40j9x3V65fQIuIGM3Kddv4fdWGLNPLlw1nzLC++Hh7uyAqERERkbzpk5eIDY4ePcrUqVPZtm2bq0PJ1uKotfz74/ls3nXA1aGIiIiISAF0ats0y91kvj7e3JPHHRsiIkbUoVWjLHeT+Xh7M6h3ZxXMRERExND06Uvs7to44+Icx0+dYd+haMxms81DXIiIiIiIsXh7ezGoVyd8fa5/mdyrc1tKh5VwXVAiIgXk5eXFPb074XfDc8t63NYqz+ediYiIiLha7k+SNojjx48zYcIElixZgtls5rbbbuOdd96hS5cuVKlShZUrV2Yue21Yxfvuu48XXniBHTt2EBISwqBBg3j11VcJCrIevm737t1MmDCB1atX4+/vT8+ePXn77bcLHOu11x8+fDjPP/8827dvJywsjHHjxvGvf/2Lixcv8vTTT7No0SISEhLo3Lkzn3zyCeXLl7fazqVLl5g+fTo//vgjx48fJyQkhK5du/Lqq69SrVq1zOXi4+OZMWMGy5Yt49ChQ8THxxMZGcndd9/Niy++SPHixTOXzcjIYObMmXz++eccOXIEk8lEuXLlaNeuHR999BG+vr5W7+HmoSm/+OIL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s2knAPVrV1XBTERERERERERERESkkAxfNCuKbi7w2TLPbDZb/d+1a1f+9a9/5flab731FhMmTOD222/n8ccfp3z58vj5+XHixAlGjhxpVURr27Ythw4dYsmSJaxYsYIVK1Ywb948pk2bxpo1awgLC8v1tdLS0nKcV7x41oqt2WymYcOGvPXWWzmud3NBLae/T25/05v/dhMmTMjxuXTXCm22bPva9vJS2L8rFO6ZZnqWmYiIiIiIiIiIiIiINbd8plm1atU4ePAg6enpVsWNU6dOERcXl+061+44utG15a/dVVS6dGmCgoLYt29flmX37Nljn+ALoHTp0pQoUYLLly/TtWvXPJf/+uuvqVKlCr/99pvVHWi///57tssHBQUxYMAABgwYAFjuUnvsscf47LPPmDhxIgBhYWFcuHAhy7rX7tKzVc2aNTl79iydO3fOcnecI9SsWROwFMFs+dvlh8lkynW+LX9XERERERERERERERExLsMXze666y5ef/11vvrqK+6///7M6TNmzMhxnf379/Pzzz9bPdfs2vLXpnl7e9O7d2/mz5/PihUrMp9rZjabeeONN+z/Rmzk5eXF0KFD+eCDD/jhhx+4++67syxz5swZypQpA1jeh8lksrorKi0tjddffz3LeufOnaNUqVJW05o1awZgVSSrVasWa9euJTExMfMOsosXLzJnzpx8vZfhw4czceJE3nrrLZ5++uks80+fPk3ZsmXztc3cNG3alAYNGvDRRx/x8MMPZxl2MS0tjcuXL9t059fNgoIs1ejsiom2/l1z377tzzTTs8xERERERERERERERHLnls80e+aZZ5g3bx6jR49m8+bN1K9fn5UrV7J27doshYprGjZsyH333cfo0aOpWbMmK1as4IcffuC2225j0KBBmctNmzaN3377jd69ezNu3DgqVqzIokWLOHv2rLPeXrZeffVV/vrrL+655x7uuece2rRpg5+fH8eOHeO///0vzZs354svvgDg7rvvZtKkSfTs2ZP+/ftz+fJl5s2bh6+vb5bt1q1blzZt2tC6dWvKly/PqVOn+OSTT/Dz8+Pee+/NXG7s2LHcd999dO7cmWHDhhEXF8enn35K5cqViY2Ntfl9PPHEEyxbtoyJEyfyxx9/0LlzZ0JCQoiOjiYqKopixYqxYsWKQv+9rjGZTHz99dd07tyZRo0a8cADD1C/fn0SExP5559/+Omnn3jttdcYOXJkvrddr149goOD+fDDDylevDglSpSgTJkydO7c2ea/a268vbxsvk104dI1ADRtUIuqkeXy/V5EREREROT/27t/l9bOMIDjT0SRC/5ALoiIQ4hLcdEKihQhoJN/gYNDFBwFJeIgijrppIOKuLiYRdwUdFUIGZzcO7TYgouUi+0gDmI3qdzWWirq9f18xvDk8OSQ7ct7DgAAwNfefTRramqKcrkcxWIxdnd3IyIin8/HyclJDA4O/u13uru7Y21tLebm5mJ7ezsaGhpiYmIilpeXHz0msL29PcrlckxPT8fGxkbU1tbG0NBQlEqlFz0B9V81NjZGpVKJ1dXV2N/fj4ODg6iuro62trbo7++P8fHxh9mZmZm4v7+PnZ2dmJycjJaWlhgeHo6xsbHo6Oh4dN3p6ek4Pj6O9fX1uL6+jubm5ujr64vZ2dno7Ox8mBsZGYnLy8vY3NyMYrEYuVwuFhYWoqqqKs7Ozp79O2pqauLo6Ci2traiVCrF4uJiRES0trZGb29vFAqF/3mnvtbV1RXn5+exsrISh4eHsb29HfX19ZHNZmN0dPQf/zP/5tOnT7G3txfz8/MxNTUVt7e3kc/nY2Bg4Nn39SV8uf4jfvz516jKZGLgh+9f9NoAAAAAAJCyzP1fn+v3jclms5HNZuP09PThs0wmE4VC4eEkFnw0v335PX765TJ6Or9761UAAAAAAODDePcnzYDHPjc1xOemhrdeAwAAAAAAPhTR7Bmurq7i7u7uyZm6urqoq3veO6kAAAAAAAB4X0SzZ+jp6YmLi4snZxYXF2Npael1FgIAAAAAAOBFfdPvNHstlUolbm5unpzJ5XKRy+VeaSMAAAAAAABekmgGAAAAAABA8qreegEAAAAAAAB4a6IZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJL3JyL/FPhMXRZCAAAAAElFTkSuQmCC", + "image/png": "iVBORw0KGgoAAAANSUhEUgAABs0AAAE2CAYAAAAqK9xEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACMWklEQVR4nOzdd3gU5drH8e+mEtIgoYQSeu+9KCBVQJAqIiJFBQuCoohHVBQUUTyvDQsWFAsiYsEjeJQSAUHpvYO0ECD0QEIKKfv+sYfAkrZJtkx2f5/r4iKZtvfmnnme2b1nnjGZzWYzIiIiIiIiIiIiIiIiIh7My9UBiIiIiIiIiIiIiIiIiLiaimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj+ewolnHjh0ZP368w9cx6jZERERERERERERERESk6ChQ0Sw2NpYnnniCGjVqUKxYMcqWLcutt97KrFmzSExMtHeMdjVy5EhMJhMmkwk/Pz9q1KjByy+/TFpamqtDc5j777+fF154Icv0119/HZPJpAKhiIiIiIiIiIiIiIh4PJ/8rnD48GFuvfVWSpQowfTp02nYsCH+/v7s3LmTTz75hAoVKtCnTx9HxGo3PXr0YM6cOaSkpPDf//6Xxx57DF9fXyZNmuTq0OwuPT2dxYsX8+uvv1pN37hxIx9//DGNGjVyUWQiIiIiIiIiIiIiIiLGke87zcaMGYOPjw+bNm3i7rvvpm7dulSrVo2+ffvy66+/cuedd2a7XkpKCo8//jhlypShWLFitGvXjo0bN2ZZLi0tjbFjxxIaGkqpUqWYPHkyZrMZgN9//5127dpRokQJwsPD6d27N4cOHcrvW8Df35+IiAgqV67Mo48+SteuXfnll1+slsnIyOCZZ54hLCyMiIgIpkyZkjnPljh++OEHGjZsSEBAAOHh4XTt2pUrV65kbvu1116jatWqBAQE0LhxY3744Yd8v4+6detm3jV387/3338fgL///htfX19atmyZuV5CQgJDhw7l008/pWTJkvl+XREREREREREREREREXeTr6LZ+fPnWbp0KY899hiBgYHZLmMymbKd/swzz/Djjz/y5ZdfsmXLFmrUqEH37t25cOGC1XJffvklPj4+bNiwgXfffZe33nqL2bNnA3DlyhWeeuopNm3aRFRUFF5eXvTv35+MjIz8vI0sAgICuHr1apY4AgMDWb9+PW+88QYvv/wyy5YtsymOU6dOMWTIEB544AH27t3LypUrGTBgQGbx77XXXuOrr77io48+Yvfu3Tz55JPcd999rFq1KvP1v/jiixz/ltf8+OOPAERFRXHq1CmOHj2Kl5cX33//PaNHjwbgl19+4c4777Ta1mOPPUavXr3o2rVrof5uIiIiIiIiIiIiIiIi7iJfwzP+888/mM1mateubTW9VKlSJCcnA5aCzIwZM6zmX7lyhVmzZvHFF1/Qs2dPAD799FOWLVvGZ599xsSJEzOXjYyM5O2338ZkMlG7dm127tzJ22+/zejRoxk4cKDVdj///HNKly7Nnj17aNCgQX7eCgBms5moqCiWLFnCuHHjrOY1atSIl156CYCaNWvy/vvvExUVRbdu3fKM49SpU6SlpTFgwAAqV64MQMOGDQHLHXfTp09n+fLltG3bFoBq1aqxZs0aPv74Y2677TYAQkNDs/ydb3b69Gl8fHy49dZb8ff3Z/PmzWRkZNC+fXv8/f0B+M9//sPbb7+duc78+fPZsmVLtnf5iYiIiIiIiIiIiIiIeKp8D8+YnQ0bNrBt2zbq169PSkpKlvmHDh0iNTWVW2+9NXOar68vrVq1Yu/evVbLtmnTxuquqLZt23Lw4EHS09M5ePAgQ4YMoVq1aoSEhFClShUAoqOj8xXv4sWLCQoKolixYvTs2ZPBgwdbDb8IZHnWV7ly5Thz5gxAnnE0btyYLl260LBhQwYNGsSnn37KxYsXAUvhMTExkW7duhEUFJT576uvvrIa4rF///7s27cv1/exc+dOatWqlVkg2759O2XKlKFs2bIA7N27l5MnT9KlSxcAjh8/zhNPPME333xDsWLF8vU3ExERERERERERERERcWf5utOsRo0amEwm9u/fbzW9WrVqgGWYQ0e68847qVy5Mp9++inly5cnIyODBg0aZBlaMS+dOnVi1qxZ+Pn5Ub58eXx8sv4ZfH19rX43mUyZwy/mFYe3tzfLli3j77//ZunSpbz33ns8//zzrF+/noSEBAB+/fVXKlSoYPUa14pfttqxY0fmHWxgKZrd+Psvv/xCt27dMgtkmzdv5syZMzRr1ixzmfT0dP7880/ef/99UlJS8Pb2zlcMIiIiIiIiIiIiIiIi7iBfd5qFh4fTrVs33n//fa5cuWLzetWrV8fPz4+//vorc1pqaiobN26kXr16VsuuX7/e6vd169ZRs2ZN4uLi2L9/Py+88AJdunShbt26mXdv5VdgYCA1atSgUqVK2RbMcnP+/Hmb4jCZTNx6661MnTqVrVu34ufnx8KFC6lXrx7+/v5ER0dTo0YNq3+RkZH5imXHjh1Wd8Rt377d6vf//Oc/9O3bN/P3Ll26sHPnTrZt25b5r0WLFgwdOpRt27apYCYiIiIiIiIiIiIiIh4rfxUj4MMPP+TWW2+lRYsWTJkyhUaNGuHl5cXGjRvZt28fzZs3z7JOYGAgjz76KBMnTiQsLIxKlSrxxhtvkJiYyIMPPmi1bHR0NE899RQPP/wwW7Zs4b333uPNN9+kZMmShIeH88knn1CuXDmio6N59tlnC/7OC8iWONavX09UVBS33347ZcqUYf369Zw9e5a6desSHBzM008/zZNPPklGRgbt2rXj0qVL/PXXX4SEhDBixAgAFi5cyKRJk3IcojEjI4Pdu3fz4osvZk47dOgQAwYMAODMmTNs2rSJX375JXN+cHBwlme/BQYGEh4eXqBnwomIiIiIiIiIiIiIiLiLfBfNqlevztatW5k+fTqTJk0iJiYGf39/6tWrx9NPP82YMWOyXe/1118nIyODYcOGER8fT4sWLViyZAklS5a0Wm748OEkJSXRqlUrvL29eeKJJ3jooYcwmUzMnz+fxx9/nAYNGlC7dm1mzpxJx44dC/TGC8rLyyvPOEJCQvjzzz955513uHz5MpUrV+bNN9+kZ8+eALzyyiuULl2a1157jcOHD1OiRAmaNWvGc889l7mNS5cuZRkG80aHDh0iMTHR6s6yhg0b8tJLL9G8eXP27dtHq1atKFWqlP3/CCIiIiIiIiIiIiIiIm7GZDabza4OQuyvT58+tGvXjmeeecbVoYiIiIiIiIiIiIiIiBhevp5pJkVHu3btGDJkiKvDEBERERERERERERERKRJ0p5mIiIiIiIiIiIiIiIh4PN1pJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjH83F1ACKSf9sWQlKcq6OAgBLQpH/htvHpSjifYI9oCi88CEZ3LNw2lBvHUG7cm1H2NXfaz8C92gHlRooSo+xr7tQGgHu1A8pNVu6UG3fTp08fDh065OowqF69Or/88kuhtmGU/Qzcqx1wpzYA1A7czCj7GbjXvuZObQAoN+J+VDQTKYKS4uDKeVdHYR/nEyD2kqujsB/lxrjcKTfuxp32NXfbz5Qbkfxzp33NndoAUG6MzJ1y424OHTrEnj17XB2GXbjbfuZO7YC75caduNN+Bu61ryk3Io6j4RlFRERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8no+rAxARx3lj/kiWbf4SAC+TF2Eh5WhSvTMP3vEapUIruDg6z6bcGJdyI86ifc24lBtxBu1nxqXcGJdyI86ifc24lBtxBu1nxqXciDPoTjMRN9ewanu+m3yKb56PZtK98/jn5FZe+XqQq8MSlBsjU27EWbSvGZdyI86g/cy4lBvjUm7EWbSvGZdyI86g/cy4lBtxNN1pJuLmfLz9CAuJAKBUaAV6tX6ID/7zOFeSLxNYLMTF0RVcetpV3h/pX+D1n5hrtmM0BaPcZE+5EVtpXzMu5UbENu66n6kNMC7lRoqCYsWKkZyc7Oow3HZfUzsgzqD9zLiUG5G8qWgmUggZGRm8++67fPzxxxw9epTSpUtz99138/LLLxMYGOjq8LI4d+kkf+78AS8vb7y8vF0dTqHE7F3JfTN2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RERERERERERExONpeEaRIiighKsjsLBHHOFBhd+GvdgjFuXGMZQb92aUfc2d9jNwr3ZAuZGixCj5dac2ANyrHVBusnKn3Lib6tWrF2i9jIwMzl64BEBYiRAuxF0GoHRYKF5e+b9+u6Bx3MhI+XWndsCd2gAwVixGYJT9DNxrX3OnNgCUG3E/JrPZbHZ1ECIiIuI8cYkwZaHl5yn9oURx18YjIlIYatNERIzn0uUEXps1D4DHhvXjg69/BmDSo/cSGmKgb3pFDEjnNiIirqXhGUVERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRERERERERERERERExOOpaCYiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiIiIiIiIiIiIiIjHU9FMREREREREREREREREPJ6KZiIiIiIiIiIiIiIiIuLxVDQTERERERERERERERERj+fj6gBEJP8+XQnnE1wdBYQHweiOhdvGtoWQFGePaAovoAQ06V+4bSg3jmGP3Ig4g1HaAHCvdsCd2mdQbqTo0HHjGGrTsnKn3IiIiHEZpf90p74T3OvcRrkRUNFMpEg6nwCxl1wdhX0kxcGV866Own6UGxHP5k5tALhXO6DciOSfjhvjUm5ERETyz536T3frO5UbMRINzygiIiIiIiIiIiIiIiIeT0UzERERERERERERERER8XgqmomIiHgQsxku3DBO+OnLkJ7hunhERArDbIYLV67/fvoSpKW7Lh4RERGRwriaBifjrv9+OclloYiIeCw900xERMTNpaXD9uOw4TBEn4ekq9fnzYoCHy8oXxKaVoZW1SDQ33WxiojkJS0ddsbA+kOWNi3xxjbtD/D2ggoloUklS5sWVMx1sYqIiIjk5UIC/P0P7I6B2MuWi4Kueet3CCkGVctA2xpQKwK8TK6LVUTEE6hoJiJFxhvzR7Js85cAeJm8CAspR5PqnXnwjtcoFVrBxdF5NuXGmMxmS6Fs0TZISM55ubQMyxfP0efhv9uhfW3o2Qh8vZ0WqhRxagOMy51yYzbD5qPwyxa4nEub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no0s/y4lQcx5uHxjm1bScmea2jSxhaccN0WRciMinsDLZLkrvk45SM+AU3GWf1fTwNvL8lmuYpjuKhPbqO80LuWmaFHRTESKlE37l/DnjgWcvniUldvmU718E8b0fQeAGd8O519DvmJv9HrKhVUjNLAUAEO7PM/QLs8D8Mb8kfRu+4g6EQdQboqG0OKWfyKOoHbAuNw1N6EBoCH8xVHc9bhxB8qNiLgjby9LgaximKsjEXekvtO4lBvjMZnNZrOrgxCR/Hl9McRecnUUluEBnu1duG2snQNXztsnnsIKDIe29xduG8qNY9gjN+K+4hJhykLLz1P6W+5CcRWjtAHgXu2AO7XPoNxI7tSmZU/HjTXlxjHUptnPpcsJvDZrHgCPDevHB1//DMCkR+8lNCTIhZGJiDMZ6bwGjNN/ulPfCe51bqPcCICXqwMQERERERERERERERERcTUNzyhSBIUb5MI8e8QRUKLw27AXe8Si3DiGkWIRyY1R2gBwr3bAndpnUG6k6NBx4xhq07Jyp9yIiIhxGaX/dKe+E9zr3Ea5EVDRTKRIGt3R1RHYT5P+ro7AvpQbEc/mTm0AuFc7oNyI5J+OG+NSbkRERPLPnfpPd+s7lRsxEg3PKCIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PB9XByAi+ffpSjif4OooIDwIRncs3Da2LYSkOHtEU3gBJaBJ/8JtQ7lxDHvkRkTyT22aY6i/seZuuRHj0nHjGGrTrLlbbkRExJiM0neCe/Wf7nReA8pNQaloJlIEnU+A2EuujsI+kuLgynlXR2E/yo2IuBO1acal3Ijkn44b41JuRERE8sed+k5wr/5TuSn6NDyjiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIi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IxblxjGMFIuIJ1Gb5hjqb6y5W26qV69eoPUyMjI4e8FySWpYiRAuxF0GoHRYKF4FeAhYQeNwZzpuHENtmjV3y42IiBiTUfpOcK/+053Oa0C5KSgNzygiIiIiIuJiGspMRNyJ2jQREREpqjQ8o4iIiIiIiIiIiIiIiHg8Fc1ERERERERERERERETE46loJiIiIiIiIiIiIiIiIh5PRTMRERERERERERERERHxeCqaiYiIiIiIiIiIiIiIiMdT0UxEREREREREREREREQ8nopmIiIiIiIiIiIiIiIi4vFUNBMRERERERERERERERGPp6KZiIiIiIiIiIiIiIiIeDwVzURERERERERERERERMTjqWgmIiIiIiIiIiIiIiIiHk9FMxEREREREREREREREfF4KpqJiIiIiIiIiIiIiIiIx1PRTERERERERERERERERDyeimYiIiIiIiIiIiIiIiLi8VQ0ExEREREREREREREREY+nopmIiIiIiIiIiIiIiIh4PBXNRIqAlJQU7r//fipWrEhoaCidOnVi9+7drg5LRERERAzmzJkz9OjRg+LFi9OgQQPWrVvn6pBERArspZdeol69enh5eTF//nxXhyMiIiIeQEUzkSIgLS2NatWqsW7dOi5cuMCdd95Jv379XB2WiIiIiBjMI488QrVq1Th//jwTJ05k4MCBpKSkuDosEZECqVmzJu+++y6tWrVydSgiIiLiIVQ0EykCAgMDmTx5MhUrVsTb25uxY8dy6NAhzp8/7+rQRERERMQg4uPjWbx4MS+99BIBAQGMGDGC4OBgVq5c6erQREQK5L777qNbt24UK1bM1aGIiIiIh1DRTKQIWrt2LWXKlCE8PNzVoYiIiIiIQRw8eJASJUpQtmzZzGkNGzZkz549LoxKRERERESk6PBxdQAikj9xcXE89NBDTJ8+3dWhiIiIiEgBmc1mlq7exOX4KwBcTU3NnBf11+bMnxf/sRY/X1/LLybocVsrggOLZ7vNK1euEBISYjUtJCSEhIQEO0cvImLNbDaz/K/NxF2ytDc2tWlA9w4tCQkOdF6gIiIiInlQ0UykCElOTqZv37707t2bBx54wNXhiIiIiEgBmUwmqkaW4/MF/80yb9/h45k/79x/JPPnW5rXz7FgBpYhvePj462mXb58maCgIDtELCKSM5PJRLVK5Zn97WLMN83LqU1r1biOCmYiIiJiOBqeUaSISE9P55577iEyMpL/+7//c3U4IiIiIlJItapWpG2z+jYtWzqsBD1ua53rMjVr1uTixYucPn06c9quXbuoV69eoeIUEbFF9UrladeykU3LhpcIoVfntg6OSERERCT/VDQTKSJGjx5NcnIyc+bMwWQyuTocEREREbGDnh1bUzosNNdlvLxMDO7dCT/f3AcKCQ4Opnfv3rzyyiskJyfz9ddfc/nyZTp27GjHiEVEcnZ7hxaULVUy12VMJhN39+6Ev59vrssBpKamkpycTEZGhtXPIiIiIo6iolkOTCYTI0eOdHUYIgAcO3aMOXPmsGrVKkqWLElQUBBBQUGsXr3a1aGJiIiISCH4+fpwd+9OeOVyUVTnW5pRsVxpm7Y3a9YsDh48SFhYGK+//jo//vgj/v7+9gpXRCRXvj4+DO7dCW+vnL9u6timMZUrlLVpe6NHjyYgIIDVq1czfPhwAgIC+PPPP+0VroiIiEgWJrPZfPNw04KlaDZixAi++OILV4ciBnD06FG++OIL+vXrR5MmTVwdThbnLl7Cx9ubEiF6XoWIiIhIUbR8zWaW/7U5y/TIcqV55L6+uX4BLSJiNCvXbeP3VRuyTC9fNpwxw/rh4+3tgqhERERE8qZPXiI2OHr0KFOnTmXbtm2uDiVbi6PW8u+P57N51wFXhyIiIiIiBdCpbdMsd5P5+nhzdx53bIiIGFGHVo2y3E3m4+3N4N6dVTATERERQ9OnL7G7a+OMi3McP3WGfYeiMZvNNg9xISIiIiLG4u3txeBenfD1uf5lcq/ObSkdVsJ1QYmIFJCXlxd39+6E3w3PLetxW6s8n3cmIiIi4mq5P0naII4fP86ECRNYsmQJZrOZ2267jXfeeYcuXbpQpUoVVq5cmbnstWEV77vvPl544QV27NhBSEgIgwcP5tVXXyUoyHr4ut27dzNhwgRWr16Nv78/PXv25O233y5wrNdef/jw4Tz//PNs376dsLAwxo0bx7/+9S8uXrzI008/zaJFi0hISKBz58588sknlC9f3mo7ly5dYvr06fz4448cP36ckJAQunbtyquvvkq1atUyl4uPj2fGjBksW7aMQ4cOER8fT2RkJHfddRcvvvgixYsXz1w2IyODmTNn8vnnn3PkyBFMJhPlypWjXbt2fPTRR/j6+lq9h5uHpvziiy+4//77WbFiRebDxKdMmcLUqVPZtWsXn332GQsWLODUqVNERUXRsWNHUlJSePPNN/nmm284dOgQxYoVo3379rz88ss0bdo0c9srV66kU6dOzJkzh8TERN59912OHTtGzZo1ee211+jduzc7d+5k4sSJ/P333/j6+jJ06FDefPPNzLivOXjwIC+//DLLly/n/PnzlC9fnkGDBjFlyhQCAwMzlxs5ciRffvklcXFxPPvss/z4449cvnyZ5s2b89Zbb9G6dWur9w1w//33Z/582223sXLlSpv/rrlJz8ggISExz+Wyc23Ii/q1quDr7c2lywkF2o6IiIiIuJafrw+d2jZl6epNVI0sR53qkTq3E5Eiy8fLi863NOP3leupXKEs9WtXUZsmIiIiThUUVDzfI3cYvmgWFxdHhw4dOH78OI888gj16tVj1apVdOrUiaSkpGzX2bJlCz/88AOjR49m+PDhrFixgpkzZ7Jr1y6WLVuG1//+SEeOHKF9+/akpKQwduxYIiMjWbRoET169ChUzFu3bmXRokU89NBDDB8+nAULFvDss89SrFgxvvzyS6pUqcKUKVP4559/mDlzJsOHD2f58uWZ61+6dIlbbrmF6OhoHnjgAerXr8+pU6f48MMPad26NZs2baJy5coAnDhxgtmzZzNw4EDuvfdefHx8WLVqFW+88QZbt25lyZIlmdt99dVXefHFF7nzzjt55JFH8Pb25siRI/zyyy+kpKTYVNzJydChQwkICGDChAmZRaPU1FR69OjB33//zbBhwxg7diyXLl3i008/5dZbb+XPP/+kRYsWVtv54IMPuHjxIqNGjaJYsWLMnDmT/v378/333zN69GiGDBlCv379WLp0Ke+99x5lypThhRdeyFx/8+bNdO7cmRIlSvDwww9ToUIFtm/fzsyZM/nrr79YtWpVlvfZvXt3SpcuzYsvvsj58+d566236NWrF0eOHCE4OJgOHTrw3HPPMX36dB566CHat28PQNmyZe32d01ISOS1WfMK/PcH2Ln/CDv3HynUNkRERETEGI4cP8Xrs751dRgiInZx7MRpZqhNExERESeb9Oi9hIYE5b3gDQxfNHvjjTc4evQon3/+eeYdPmPGjGH8+PG8++672a6zc+dOFi5cSL9+/TKXf+KJJ5g5cyYLFizgnnvuAeD555/n4sWL/PHHH3Tq1AmAxx57jAEDBrB169YCx7xz507Wrl2beafSgw8+SOXKlXnyyScZO3YsM2fOtFr+7bffZv/+/dSuXRuAF198kcOHD7Nu3ToaN26cudzIkSNp2LAhL730UuZdYNWqVeP48eNWhZnHHnuMyZMnM23aNDZs2ECrVq0AWLhwIXXr1uWXX36xev3XX3+9wO/1mhIlSrB8+XJ8fK7vUm+//TYrV67k999/p3v37pnTx4wZQ4MGDXj66aet7hIEOHnyJHv27CE0NBSAzp0707hxYwYMGMAPP/zAgAEDAHjkkUdo3rw5H3zwgVXR7IEHHqBcuXJs3LiR4ODgzOldunRhwIABfPPNN4wcOdLqNZs1a8aHH36Y+Xu9evW4++67mTdvHg8//DDVqlWjW7duTJ8+nbZt23LfffdZre/Iv6uIiIiIiIiIiIiIiDiH4YtmP//8M2XLlmX48OFW0//1r3/lWDSrXbt2ZsHsmmeffZaZM2eycOFC7rnnHjIyMli0aBEtWrTILJiBZWjCZ555hp9//rnAMbdt2zazYAbg5+dHq1at+OWXX3j88cetlm3fvj1vv/02Bw8epHbt2pjNZr755hs6dOhAhQoVOHfuXOaygYGBtGnThqVLl1pt+5q0tDTi4+NJT0+na9euTJs2jfXr12cWzUJDQzl06BBr1qyhXbt2BX5/2Rk/frxVwQxg7ty51KlTh+bNm1u9D4Bu3brx5ZdfkpSUREBAQOb0kSNHZhbMABo1akRISAjBwcGZBbNr2rVrx8yZM0lISCAoKIidO3eyY8cOpk6dSkpKCikpKVbLBgYGsnTp0ixFsyeffNLq986dOwOWYR5tYY+/a1BQcSY9em++1jl55jxf/rgEk8nEQ0N6ExYanPdKIiIiIiIiIiIiIiIeICioeN4L3cTwRbPDhw/TsmVLvL29raaXK1eOEiVKZLtO3bp1s0y7tvzhw4cBOHPmDAkJCdSpUyfLsvXq1StUzDc+c+yakiUtD7utWrVqttPPnz8PwNmzZzl//jxLly6ldOnS2W7f66YxOD/88EM++ugjdu/eTUZGhtW8ixcvZv48ffp0+vXrR/v27SlfvjwdO3akV69e3HXXXVbFt4KoVatWlml79+4lKSkpx/cBcO7cOSIjIzN/z+lvd+MyN04Hy98uKCiIvXv3AvDSSy/x0ksvZft6p0+fzjLt5tcMDw/P3K4tHPl3zc2aTTsBaFCrigpmIiIiIiIiIiIiIiKFZPiiWVF0c4HPlnlms9nq/65du/Kvf/0rz9d66623mDBhArfffjuPP/445cuXx8/PjxMnTjBy5EirIlrbtm05dOgQS5YsYcWKFaxYsYJ58+Yxbdo01qxZQ1hYWK6vlZaWluO84sWzVmzNZjMNGzbkrbfeynG9mwtqOf19cvub3vy3mzBhQo7PpbtWaLNl29e2l5fC/l2hcM8007PMRERERERERERERESsueUzzapVq8bBgwdJT0+3Km6cOnWKuLi4bNe5dsfRja4tf+2uotKlSxMUFMS+ffuyLLtnzx77BF8ApUuXpkSJEly+fJmuXbvmufzXX39NlSpV+O2336zuQPv999+zXT4oKIiBAwcycOBAwHKX2mOPPcZnn33GxIkTAQgLC+PChQtZ1r12l56tatasydmzZ+ncuXOWu+McoWbNmoClCGbL3y4/TCZTrvNt+buKiIiIiIiIiIiIiIhxGb5o1rdvX15//XW++uor7r///szpM2bMyHGd/fv38/PPP1s91+za8temeXt707t3b+bPn8+KFSsyn2tmNpt544037P9GbOTl5cXQoUP54IMP+OGHH7jrrruyLHPmzBnKlCkDWN6HyWSyuisqLS2N119/Pct6586do1SpUlbTmjVrBmBVJKtVqxZr164lMTEx8w6yixcvMmfOnHy9l+HDhzNx4kTeeustnn766SzzT58+TdmyZfO1zdw0bdqUBg0a8NFHH/Hwww9nGXYxLS2Ny5cv23Tn182CgizV6OyKibb+XXPfvu3PNNOzzEREREREREREREREcueWzzR75plnmDdvHqNHj2bz5s3Ur1+flStXsnbt2iyFimsaNmzIfffdx+jRo6lZsyYrVqzghx9+4LbbbmPw4MGZy02bNo3ffvuN3r17M27cOCpWrMiiRYs4e/ass95etl599VX++usv7r77bu6++27atGmDn58fx44d47///S/Nmzfniy++AOCuu+5i0qRJ9OzZkwEDBnD58mXmzZuHr69vlu3WrVuXNm3a0Lp1a8qXL8+pU6f45JNP8PPz45577slcbuzYsdx333107tyZYcOGERcXx6effkrlypWJjY21+X088cQTLFu2jIkTJ/LHH3/QuXNnQkJCiI6OJioqimLFirFixYpC/72uMZlMfP3113Tu3JlGjRrxwAMPUL9+fRITE/nnn3/46aefeO211xg5cmS+t12vXj2Cg4P58MMPKV68OCVKlKBMmTJ07tzZ5r9rbry9vGy+TXTh0jUANK1fk6qR5fL9XkRERETk/9u7f5fWzjCA409EkQv+QC6IiEOIS3HRCooUIaCTf4GDQxQcBSXiIIo66aSDiri4mEXcFHRVCBmc3Du02IKLlIvtIA5iN6nc1loq6vX9fMbw5PDkkO3Lew4AAAB87d1Hs6ampiiXy1EsFmN3dzciIvL5fJycnMTg4ODffqe7uzvW1tZibm4utre3o6GhISYmJmJ5efnRYwLb29ujXC7H9PR0bGxsRG1tbQwNDUWpVHrRE1D/VWNjY1QqlVhdXY39/f04ODiI6urqaGtri/7+/hgfH3+YnZmZifv7+9jZ2YnJycloaWmJ4eHhGBsbi46OjkfXnZ6ejuPj41hfX4/r6+tobm6Ovr6+mJ2djc7Ozoe5kZGRuLy8jM3NzSgWi5HL5WJhYSGqqqri7Ozs2b+jpqYmjo6OYmtrK0qlUiwuLkZERGtra/T29kahUPifd+prXV1dcX5+HisrK3F4eBjb29tRX18f2Ww2RkdH//E/828+ffoUe3t7MT8/H1NTU3F7exv5fD4GBgaefV9fwpfrP+LHn3+NqkwmBn74/kWvDQAAAAAAKcvc//W5ft+YbDYb2Ww2Tk9PHz7LZDJRKBQeTmLBR/Pbl9/jp18uo6fzu7deBQAAAAAAPox3f9IMeOxzU0N8bmp46zUAAAAAAOBDEc2e4erqKu7u7p6cqauri7q6572TCgAAAAAAgPdFNHuGnp6euLi4eHJmcXExlpaWXmchAAAAAAAAXtQ3/U6z11KpVOLm5ubJmVwuF7lc7pU2AgAAAAAA4CWJZgAAAAAAACSv6q0XAAAAAAAAgLcmmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeaIZAAAAAAAAyRPNAAAAAAAASJ5oBgAAAAAAQPJEMwAAAAAAAJInmgEAAAAAAJA80QwAAAAAAIDkiWYAAAAAAAAkTzQDAAAAAAAgeX8C7OsU8pAAnfAAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -379,10 +379,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Reconstructed expectation values: [0.50671387, 0.51519775, 0.3380127, -0.17828369, 0.26855469, -0.17858887]\n", + "Simulated expectation values: [0.54180908, 0.55859375, 0.39801025, -0.27911377, 0.23406982, -0.22296143]\n", "Exact expectation values: [0.50983039, 0.56127511, 0.36167086, -0.23006544, 0.23416169, -0.20855487]\n", - "Errors in estimation: [-0.00311653, -0.04607736, -0.02365816, 0.05178174, 0.03439299, 0.02996601]\n", - "Relative errors in estimation: [-0.00611287, -0.08209407, -0.06541352, -0.22507399, 0.14687712, -0.14368403]\n" + "Errors in estimation: [0.03197869, -0.00268136, 0.03633939, -0.04904833, -9.187e-05, -0.01440655]\n", + "Relative errors in estimation: [0.06272417, -0.00477727, 0.10047642, 0.21319297, -0.00039233, 0.069078]\n" ] } ], @@ -414,7 +414,7 @@ { "data": { "text/html": [ - "

Version Information

SoftwareVersion
qiskit0.44.1
qiskit-terra0.25.1
qiskit_aer0.12.1
qiskit_ibm_provider0.6.3
System information
Python version3.8.16
Python compilerClang 14.0.6
Python builddefault, Mar 1 2023 21:19:10
OSDarwin
CPUs8
Memory (Gb)32.0
Wed Aug 30 08:18:28 2023 CDT
" + "

Version Information

Qiskit SoftwareVersion
qiskit-terra0.24.1
qiskit-aer0.12.1
qiskit-ibmq-provider0.20.2
qiskit0.43.2
qiskit-nature0.6.0
System information
Python version3.8.16
Python compilerClang 14.0.6
Python builddefault, Mar 1 2023 21:19:10
OSDarwin
CPUs8
Memory (Gb)32.0
Mon Aug 14 08:37:05 2023 CDT
" ], "text/plain": [ "" From f30b435685b07b84a1ccba544ea3abcb6e42c74f Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 16:49:21 -0500 Subject: [PATCH 22/40] Update cutting_evaluation.py --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index af1997385..04b5366a3 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -478,7 +478,7 @@ def _get_mapping_ids_by_partition( "SingleQubitQPDGate instances in input circuit(s) must have their " 'labels suffixed with "_", where is the index of the gate ' "relative to the other gates belonging to the same cut. For example, " - "a two-qubit gate can be represented by two SingleQubitQPDGates -- one " + "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " 'labeled "_0" and one labeled "_1".' " This allows SingleQubitQPDGates belonging to the same cut to be " "sampled together." From e4274d1aa4fb7a32c2269287f4bb4df8d4220463 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Wed, 30 Aug 2023 20:55:10 -0500 Subject: [PATCH 23/40] fix strange error --- test/cutting/test_cutting_decomposition.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 2fe15fbf0..61dfa2f56 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -370,22 +370,22 @@ def test_generate_cutting_experiments(self): qc, "AB", observables=PauliList(["ZZ"]) ) partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" - comp_string = ( + + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments( + partitioned_problem.subcircuits, + partitioned_problem.subobservables, + np.inf, + ) + assert e_info.value.args[0] == ( "SingleQubitQPDGate instances in input circuit(s) must have their " 'labels suffixed with "_", where is the index of the gate ' "relative to the other gates belonging to the same cut. For example, " - "a two-qubit gate can be represented by two SingleQubitQPDGates -- one " + "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " 'labeled "_0" and one labeled "_1".' " This allows SingleQubitQPDGates belonging to the same cut to be " "sampled together." ) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments( - partitioned_problem.subcircuits, - partitioned_problem.subobservables, - np.inf, - ) - assert e_info.value.args[0] == comp_string with self.subTest("test bad observable size"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: From 9b6ac2c329d79cc09999929693799e99d69fdf25 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 08:50:01 -0500 Subject: [PATCH 24/40] Unnecessary conditional --- circuit_knitting/cutting/cutting_evaluation.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 04b5366a3..d5bcc30bb 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -310,9 +310,8 @@ def _generate_cutting_experiments( raise ValueError( "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." ) - if isinstance(num_samples, float): - if not num_samples >= 1: - raise ValueError("num_samples must be at least 1.") + if not num_samples >= 1: + raise ValueError("num_samples must be at least 1.") # Retrieving the unique bases, QPD gates, and decomposed observables is slightly different # depending on the format of the execute_experiments input args, but the 2nd half of this function From 72f891bb93c4fb6da3871800ada7e7bbcae1696d Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 09:05:38 -0500 Subject: [PATCH 25/40] Move generate_exp tests to test_evaluation until we decide on home --- test/cutting/test_cutting_decomposition.py | 119 ------------------- test/cutting/test_cutting_evaluation.py | 127 ++++++++++++++++++++- 2 files changed, 124 insertions(+), 122 deletions(-) diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 61dfa2f56..865fa3ff2 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -287,122 +287,3 @@ def test_unused_qubits(self): ) assert subcircuits.keys() == {"A", "B"} assert subobservables.keys() == {"A", "B"} - - def test_generate_cutting_experiments(self): - with self.subTest("simple circuit and observable"): - qc = QuantumCircuit(2) - qc.append( - TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), - qargs=[0, 1], - ) - comp_weights = [ - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - ] - subexperiments, weights = generate_cutting_experiments( - qc, PauliList(["ZZ"]), np.inf - ) - assert weights == comp_weights - assert len(weights) == len(subexperiments) - for exp in subexperiments: - assert isinstance(exp, QuantumCircuit) - - with self.subTest("simple circuit and observable as dict"): - qc = QuantumCircuit(2) - qc.append( - SingleQubitQPDGate( - QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=0 - ), - qargs=[0], - ) - qc.append( - SingleQubitQPDGate( - QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=1 - ), - qargs=[1], - ) - comp_weights = [ - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - ] - subexperiments, weights = generate_cutting_experiments( - {"A": qc}, {"A": PauliList(["ZY"])}, np.inf - ) - assert weights == comp_weights - assert len(weights) == len(subexperiments["A"]) - for circ in subexperiments["A"]: - assert isinstance(circ, QuantumCircuit) - - with self.subTest("test bad num_samples"): - qc = QuantumCircuit(4) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 0) - assert e_info.value.args[0] == "num_samples must be at least 1." - with self.subTest("test incompatible inputs"): - qc = QuantumCircuit(4) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, {"A": PauliList(["ZZZZ"])}, 4.5) - assert ( - e_info.value.args[0] - == "If the input circuits is a QuantumCircuit, the observables must be a PauliList." - ) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments({"A": qc}, PauliList(["ZZZZ"]), 4.5) - assert ( - e_info.value.args[0] - == "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." - ) - with self.subTest("test bad label"): - qc = QuantumCircuit(2) - qc.append( - TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), - qargs=[0, 1], - ) - partitioned_problem = partition_problem( - qc, "AB", observables=PauliList(["ZZ"]) - ) - partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" - - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments( - partitioned_problem.subcircuits, - partitioned_problem.subobservables, - np.inf, - ) - assert e_info.value.args[0] == ( - "SingleQubitQPDGate instances in input circuit(s) must have their " - 'labels suffixed with "_", where is the index of the gate ' - "relative to the other gates belonging to the same cut. For example, " - "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " - 'labeled "_0" and one labeled "_1".' - " This allows SingleQubitQPDGates belonging to the same cut to be " - "sampled together." - ) - with self.subTest("test bad observable size"): - qc = QuantumCircuit(4) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) - assert e_info.value.args[0] == ( - "Quantum circuit qubit count (4) does not match qubit count of observable(s) (2)." - " Try providing `qubit_locations` explicitly." - ) - with self.subTest("test single qubit qpd gate in unseparated circuit"): - qc = QuantumCircuit(2) - qc.append( - SingleQubitQPDGate(QPDBasis.from_gate(CXGate()), 0, label="cut_cx_0"), - qargs=[0], - ) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) - assert ( - e_info.value.args[0] - == "SingleQubitQPDGates are not supported in unseparable circuits." - ) diff --git a/test/cutting/test_cutting_evaluation.py b/test/cutting/test_cutting_evaluation.py index ee71bd0b9..518a1f788 100644 --- a/test/cutting/test_cutting_evaluation.py +++ b/test/cutting/test_cutting_evaluation.py @@ -9,17 +9,18 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. -import pytest -import unittest +import unittest from copy import deepcopy +import pytest +import numpy as np from qiskit.quantum_info import Pauli, PauliList from qiskit.result import QuasiDistribution from qiskit.primitives import Sampler as TerraSampler from qiskit_aer.primitives import Sampler as AerSampler from qiskit.circuit import QuantumCircuit, ClassicalRegister, CircuitInstruction, Clbit -from qiskit.circuit.library.standard_gates import XGate +from qiskit.circuit.library.standard_gates import XGate, CXGate from circuit_knitting.utils.observable_grouping import CommutingObservableGroup from circuit_knitting.utils.simulation import ExactSampler @@ -31,6 +32,7 @@ from circuit_knitting.cutting.cutting_evaluation import ( _append_measurement_circuit, execute_experiments, + generate_cutting_experiments, ) from circuit_knitting.cutting.qpd import WeightType from circuit_knitting.cutting import partition_problem @@ -358,3 +360,122 @@ def test_workflow_with_unused_qubits(self): num_samples=1, samplers=AerSampler(), ) + + def test_generate_cutting_experiments(self): + with self.subTest("simple circuit and observable"): + qc = QuantumCircuit(2) + qc.append( + TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), + qargs=[0, 1], + ) + comp_weights = [ + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + ] + subexperiments, weights = generate_cutting_experiments( + qc, PauliList(["ZZ"]), np.inf + ) + assert weights == comp_weights + assert len(weights) == len(subexperiments) + for exp in subexperiments: + assert isinstance(exp, QuantumCircuit) + + with self.subTest("simple circuit and observable as dict"): + qc = QuantumCircuit(2) + qc.append( + SingleQubitQPDGate( + QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=0 + ), + qargs=[0], + ) + qc.append( + SingleQubitQPDGate( + QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=1 + ), + qargs=[1], + ) + comp_weights = [ + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + ] + subexperiments, weights = generate_cutting_experiments( + {"A": qc}, {"A": PauliList(["ZY"])}, np.inf + ) + assert weights == comp_weights + assert len(weights) == len(subexperiments["A"]) + for circ in subexperiments["A"]: + assert isinstance(circ, QuantumCircuit) + + with self.subTest("test bad num_samples"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 0) + assert e_info.value.args[0] == "num_samples must be at least 1." + with self.subTest("test incompatible inputs"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, {"A": PauliList(["ZZZZ"])}, 4.5) + assert ( + e_info.value.args[0] + == "If the input circuits is a QuantumCircuit, the observables must be a PauliList." + ) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments({"A": qc}, PauliList(["ZZZZ"]), 4.5) + assert ( + e_info.value.args[0] + == "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." + ) + with self.subTest("test bad label"): + qc = QuantumCircuit(2) + qc.append( + TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), + qargs=[0, 1], + ) + partitioned_problem = partition_problem( + qc, "AB", observables=PauliList(["ZZ"]) + ) + partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" + + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments( + partitioned_problem.subcircuits, + partitioned_problem.subobservables, + np.inf, + ) + assert e_info.value.args[0] == ( + "SingleQubitQPDGate instances in input circuit(s) must have their " + 'labels suffixed with "_", where is the index of the gate ' + "relative to the other gates belonging to the same cut. For example, " + "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " + 'labeled "_0" and one labeled "_1".' + " This allows SingleQubitQPDGates belonging to the same cut to be " + "sampled together." + ) + with self.subTest("test bad observable size"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + assert e_info.value.args[0] == ( + "Quantum circuit qubit count (4) does not match qubit count of observable(s) (2)." + " Try providing `qubit_locations` explicitly." + ) + with self.subTest("test single qubit qpd gate in unseparated circuit"): + qc = QuantumCircuit(2) + qc.append( + SingleQubitQPDGate(QPDBasis.from_gate(CXGate()), 0, label="cut_cx_0"), + qargs=[0], + ) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + assert ( + e_info.value.args[0] + == "SingleQubitQPDGates are not supported in unseparable circuits." + ) From 1d9893ec0873264f6edfec5bd7322900b9f3545b Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 09:06:29 -0500 Subject: [PATCH 26/40] ruff --- test/cutting/test_cutting_decomposition.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/cutting/test_cutting_decomposition.py b/test/cutting/test_cutting_decomposition.py index 865fa3ff2..4118a6537 100644 --- a/test/cutting/test_cutting_decomposition.py +++ b/test/cutting/test_cutting_decomposition.py @@ -23,17 +23,14 @@ from circuit_knitting.cutting import ( partition_circuit_qubits, - generate_cutting_experiments, partition_problem, cut_gates, ) from circuit_knitting.cutting.instructions import Move from circuit_knitting.cutting.qpd import ( QPDBasis, - SingleQubitQPDGate, TwoQubitQPDGate, BaseQPDGate, - WeightType, ) From bcb9209e3fe72b76e90aa89cc69d025f97ee8ebf Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 11:00:11 -0500 Subject: [PATCH 27/40] Create a new module for subexperiment generation --- circuit_knitting/cutting/__init__.py | 2 +- .../cutting/cutting_evaluation.py | 54 ------- .../cutting/cutting_experiments.py | 74 +++++++++ test/cutting/test_cutting_evaluation.py | 123 +-------------- test/cutting/test_cutting_experiments.py | 149 ++++++++++++++++++ 5 files changed, 225 insertions(+), 177 deletions(-) create mode 100644 circuit_knitting/cutting/cutting_experiments.py create mode 100644 test/cutting/test_cutting_experiments.py diff --git a/circuit_knitting/cutting/__init__.py b/circuit_knitting/cutting/__init__.py index f1ab411e4..f0f6851a5 100644 --- a/circuit_knitting/cutting/__init__.py +++ b/circuit_knitting/cutting/__init__.py @@ -90,8 +90,8 @@ from .cutting_evaluation import ( execute_experiments, CuttingExperimentResults, - generate_cutting_experiments, ) +from .cutting_experiments import generate_cutting_experiments from .cutting_reconstruction import reconstruct_expectation_values from .wire_cutting_transforms import cut_wires, expand_observables diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index d5bcc30bb..782d32bd3 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -239,60 +239,6 @@ def _append_measurement_circuit( return qc -def generate_cutting_experiments( - circuits: QuantumCircuit | dict[str | int, QuantumCircuit], - observables: PauliList | dict[str | int, PauliList], - num_samples: int | float, -) -> tuple[ - list[QuantumCircuit] | dict[str | int, list[QuantumCircuit]], - list[tuple[float, WeightType]], -]: - """ - Generate cutting subexperiments and their associated weights. - - If the input, ``circuits``, is a :class:`QuantumCircuit` instance, the - output subexperiments will be contained within a 1D array, and ``observables`` is - expected to be a :class:`PauliList` instance. - - If the input circuit and observables are specified by dictionaries with partition labels - as keys, the output subexperiments will be returned as a dictionary which maps a - partition label to to a 1D array containing the subexperiments associated with that partition. - - In both cases, the subexperiment lists are ordered as follows: - :math:`[sample_{0}observable_{0}, sample_{0}observable_{1}, ..., sample_{0}observable_{N}, ..., sample_{M}observable_{N}]` - - The weights will always be returned as a 1D array -- one weight for each unique sample. - - Args: - circuits: The circuit(s) to partition and separate - observables: The observable(s) to evaluate for each unique sample - num_samples: The number of samples to draw from the quasi-probability distribution. If set - to infinity, the weights will be generated rigorously rather than by sampling from - the distribution. - Returns: - A tuple containing the cutting experiments and their associated weights. - If the input circuits is a :class:`QuantumCircuit` instance, the output subexperiments - will be a sequence of circuits -- one for every unique sample and observable. If the - input circuits are represented as a dictionary keyed by partition labels, the output - subexperiments will also be a dictionary keyed by partition labels and containing - the subexperiments for each partition. - The weights are always a sequence of length-2 tuples, where each tuple contains the - weight and the :class:`WeightType`. Each weight corresponds to one unique sample. - - Raises: - ValueError: ``num_samples`` must either be at least one. - ValueError: ``circuits`` and ``observables`` are incompatible types - ValueError: :class:`SingleQubitQPDGate` instances must have their cut ID - appended to the gate label so they may be associated with other gates belonging - to the same cut. - ValueError: :class:`SingleQubitQPDGate` instances are not allowed in unseparated circuits. - """ - subexperiments, weights, _ = _generate_cutting_experiments( - circuits, observables, num_samples - ) - return subexperiments, weights - - def _generate_cutting_experiments( circuits: QuantumCircuit | dict[str | int, QuantumCircuit], observables: PauliList | dict[str | int, PauliList], diff --git a/circuit_knitting/cutting/cutting_experiments.py b/circuit_knitting/cutting/cutting_experiments.py new file mode 100644 index 000000000..0be8b7f68 --- /dev/null +++ b/circuit_knitting/cutting/cutting_experiments.py @@ -0,0 +1,74 @@ +# This code is a Qiskit project. + +# (C) Copyright IBM 2023. + +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""Functions for evaluating circuit cutting experiments.""" + +from __future__ import annotations + +from qiskit.circuit import QuantumCircuit +from qiskit.quantum_info import PauliList + +from .qpd import WeightType +from .cutting_evaluation import _generate_cutting_experiments + + +def generate_cutting_experiments( + circuits: QuantumCircuit | dict[str | int, QuantumCircuit], + observables: PauliList | dict[str | int, PauliList], + num_samples: int | float, +) -> tuple[ + list[QuantumCircuit] | dict[str | int, list[QuantumCircuit]], + list[tuple[float, WeightType]], +]: + """ + Generate cutting subexperiments and their associated weights. + + If the input, ``circuits``, is a :class:`QuantumCircuit` instance, the + output subexperiments will be contained within a 1D array, and ``observables`` is + expected to be a :class:`PauliList` instance. + + If the input circuit and observables are specified by dictionaries with partition labels + as keys, the output subexperiments will be returned as a dictionary which maps a + partition label to to a 1D array containing the subexperiments associated with that partition. + + In both cases, the subexperiment lists are ordered as follows: + :math:`[sample_{0}observable_{0}, sample_{0}observable_{1}, ..., sample_{0}observable_{N}, ..., sample_{M}observable_{N}]` + + The weights will always be returned as a 1D array -- one weight for each unique sample. + + Args: + circuits: The circuit(s) to partition and separate + observables: The observable(s) to evaluate for each unique sample + num_samples: The number of samples to draw from the quasi-probability distribution. If set + to infinity, the weights will be generated rigorously rather than by sampling from + the distribution. + Returns: + A tuple containing the cutting experiments and their associated weights. + If the input circuits is a :class:`QuantumCircuit` instance, the output subexperiments + will be a sequence of circuits -- one for every unique sample and observable. If the + input circuits are represented as a dictionary keyed by partition labels, the output + subexperiments will also be a dictionary keyed by partition labels and containing + the subexperiments for each partition. + The weights are always a sequence of length-2 tuples, where each tuple contains the + weight and the :class:`WeightType`. Each weight corresponds to one unique sample. + + Raises: + ValueError: ``num_samples`` must either be at least one. + ValueError: ``circuits`` and ``observables`` are incompatible types + ValueError: :class:`SingleQubitQPDGate` instances must have their cut ID + appended to the gate label so they may be associated with other gates belonging + to the same cut. + ValueError: :class:`SingleQubitQPDGate` instances are not allowed in unseparated circuits. + """ + subexperiments, weights, _ = _generate_cutting_experiments( + circuits, observables, num_samples + ) + return subexperiments, weights diff --git a/test/cutting/test_cutting_evaluation.py b/test/cutting/test_cutting_evaluation.py index 518a1f788..9cafb52a2 100644 --- a/test/cutting/test_cutting_evaluation.py +++ b/test/cutting/test_cutting_evaluation.py @@ -14,13 +14,12 @@ from copy import deepcopy import pytest -import numpy as np from qiskit.quantum_info import Pauli, PauliList from qiskit.result import QuasiDistribution from qiskit.primitives import Sampler as TerraSampler from qiskit_aer.primitives import Sampler as AerSampler from qiskit.circuit import QuantumCircuit, ClassicalRegister, CircuitInstruction, Clbit -from qiskit.circuit.library.standard_gates import XGate, CXGate +from qiskit.circuit.library.standard_gates import XGate from circuit_knitting.utils.observable_grouping import CommutingObservableGroup from circuit_knitting.utils.simulation import ExactSampler @@ -32,7 +31,6 @@ from circuit_knitting.cutting.cutting_evaluation import ( _append_measurement_circuit, execute_experiments, - generate_cutting_experiments, ) from circuit_knitting.cutting.qpd import WeightType from circuit_knitting.cutting import partition_problem @@ -360,122 +358,3 @@ def test_workflow_with_unused_qubits(self): num_samples=1, samplers=AerSampler(), ) - - def test_generate_cutting_experiments(self): - with self.subTest("simple circuit and observable"): - qc = QuantumCircuit(2) - qc.append( - TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), - qargs=[0, 1], - ) - comp_weights = [ - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - ] - subexperiments, weights = generate_cutting_experiments( - qc, PauliList(["ZZ"]), np.inf - ) - assert weights == comp_weights - assert len(weights) == len(subexperiments) - for exp in subexperiments: - assert isinstance(exp, QuantumCircuit) - - with self.subTest("simple circuit and observable as dict"): - qc = QuantumCircuit(2) - qc.append( - SingleQubitQPDGate( - QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=0 - ), - qargs=[0], - ) - qc.append( - SingleQubitQPDGate( - QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=1 - ), - qargs=[1], - ) - comp_weights = [ - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - (0.5, WeightType.EXACT), - (-0.5, WeightType.EXACT), - ] - subexperiments, weights = generate_cutting_experiments( - {"A": qc}, {"A": PauliList(["ZY"])}, np.inf - ) - assert weights == comp_weights - assert len(weights) == len(subexperiments["A"]) - for circ in subexperiments["A"]: - assert isinstance(circ, QuantumCircuit) - - with self.subTest("test bad num_samples"): - qc = QuantumCircuit(4) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 0) - assert e_info.value.args[0] == "num_samples must be at least 1." - with self.subTest("test incompatible inputs"): - qc = QuantumCircuit(4) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, {"A": PauliList(["ZZZZ"])}, 4.5) - assert ( - e_info.value.args[0] - == "If the input circuits is a QuantumCircuit, the observables must be a PauliList." - ) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments({"A": qc}, PauliList(["ZZZZ"]), 4.5) - assert ( - e_info.value.args[0] - == "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." - ) - with self.subTest("test bad label"): - qc = QuantumCircuit(2) - qc.append( - TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), - qargs=[0, 1], - ) - partitioned_problem = partition_problem( - qc, "AB", observables=PauliList(["ZZ"]) - ) - partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" - - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments( - partitioned_problem.subcircuits, - partitioned_problem.subobservables, - np.inf, - ) - assert e_info.value.args[0] == ( - "SingleQubitQPDGate instances in input circuit(s) must have their " - 'labels suffixed with "_", where is the index of the gate ' - "relative to the other gates belonging to the same cut. For example, " - "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " - 'labeled "_0" and one labeled "_1".' - " This allows SingleQubitQPDGates belonging to the same cut to be " - "sampled together." - ) - with self.subTest("test bad observable size"): - qc = QuantumCircuit(4) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) - assert e_info.value.args[0] == ( - "Quantum circuit qubit count (4) does not match qubit count of observable(s) (2)." - " Try providing `qubit_locations` explicitly." - ) - with self.subTest("test single qubit qpd gate in unseparated circuit"): - qc = QuantumCircuit(2) - qc.append( - SingleQubitQPDGate(QPDBasis.from_gate(CXGate()), 0, label="cut_cx_0"), - qargs=[0], - ) - with pytest.raises(ValueError) as e_info: - generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) - assert ( - e_info.value.args[0] - == "SingleQubitQPDGates are not supported in unseparable circuits." - ) diff --git a/test/cutting/test_cutting_experiments.py b/test/cutting/test_cutting_experiments.py new file mode 100644 index 000000000..5bf09a25a --- /dev/null +++ b/test/cutting/test_cutting_experiments.py @@ -0,0 +1,149 @@ +# This code is a Qiskit project. + +# (C) Copyright IBM 2023. + +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + + +import unittest + +import pytest +import numpy as np +from qiskit.quantum_info import PauliList +from qiskit.circuit import QuantumCircuit +from qiskit.circuit.library.standard_gates import CXGate + +from circuit_knitting.cutting.qpd import ( + SingleQubitQPDGate, + TwoQubitQPDGate, + QPDBasis, +) +from circuit_knitting.cutting import generate_cutting_experiments +from circuit_knitting.cutting.qpd import WeightType +from circuit_knitting.cutting import partition_problem + + +class TestCuttingExperiments(unittest.TestCase): + def test_generate_cutting_experiments(self): + with self.subTest("simple circuit and observable"): + qc = QuantumCircuit(2) + qc.append( + TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), + qargs=[0, 1], + ) + comp_weights = [ + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + ] + subexperiments, weights = generate_cutting_experiments( + qc, PauliList(["ZZ"]), np.inf + ) + assert weights == comp_weights + assert len(weights) == len(subexperiments) + for exp in subexperiments: + assert isinstance(exp, QuantumCircuit) + + with self.subTest("simple circuit and observable as dict"): + qc = QuantumCircuit(2) + qc.append( + SingleQubitQPDGate( + QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=0 + ), + qargs=[0], + ) + qc.append( + SingleQubitQPDGate( + QPDBasis.from_gate(CXGate()), label="cut_cx_0", qubit_id=1 + ), + qargs=[1], + ) + comp_weights = [ + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + (0.5, WeightType.EXACT), + (-0.5, WeightType.EXACT), + ] + subexperiments, weights = generate_cutting_experiments( + {"A": qc}, {"A": PauliList(["ZY"])}, np.inf + ) + assert weights == comp_weights + assert len(weights) == len(subexperiments["A"]) + for circ in subexperiments["A"]: + assert isinstance(circ, QuantumCircuit) + + with self.subTest("test bad num_samples"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 0) + assert e_info.value.args[0] == "num_samples must be at least 1." + with self.subTest("test incompatible inputs"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, {"A": PauliList(["ZZZZ"])}, 4.5) + assert ( + e_info.value.args[0] + == "If the input circuits is a QuantumCircuit, the observables must be a PauliList." + ) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments({"A": qc}, PauliList(["ZZZZ"]), 4.5) + assert ( + e_info.value.args[0] + == "If the input circuits are contained in a dictionary keyed by partition labels, the input observables must also be represented by such a dictionary." + ) + with self.subTest("test bad label"): + qc = QuantumCircuit(2) + qc.append( + TwoQubitQPDGate(QPDBasis.from_gate(CXGate()), label="cut_cx"), + qargs=[0, 1], + ) + partitioned_problem = partition_problem( + qc, "AB", observables=PauliList(["ZZ"]) + ) + partitioned_problem.subcircuits["A"].data[0].operation.label = "newlabel" + + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments( + partitioned_problem.subcircuits, + partitioned_problem.subobservables, + np.inf, + ) + assert e_info.value.args[0] == ( + "SingleQubitQPDGate instances in input circuit(s) must have their " + 'labels suffixed with "_", where is the index of the gate ' + "relative to the other gates belonging to the same cut. For example, " + "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " + 'labeled "_0" and one labeled "_1".' + " This allows SingleQubitQPDGates belonging to the same cut to be " + "sampled together." + ) + with self.subTest("test bad observable size"): + qc = QuantumCircuit(4) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + assert e_info.value.args[0] == ( + "Quantum circuit qubit count (4) does not match qubit count of observable(s) (2)." + " Try providing `qubit_locations` explicitly." + ) + with self.subTest("test single qubit qpd gate in unseparated circuit"): + qc = QuantumCircuit(2) + qc.append( + SingleQubitQPDGate(QPDBasis.from_gate(CXGate()), 0, label="cut_cx_0"), + qargs=[0], + ) + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZ"]), np.inf) + assert ( + e_info.value.args[0] + == "SingleQubitQPDGates are not supported in unseparable circuits." + ) From 3aa0b896232c85ed0ddbaf79ffd27f754017e715 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 11:02:07 -0500 Subject: [PATCH 28/40] Update circuit_knitting/cutting/cutting_evaluation.py Co-authored-by: Jim Garrison --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 782d32bd3..e8b804a3c 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -426,7 +426,7 @@ def _get_mapping_ids_by_partition( "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " 'labeled "_0" and one labeled "_1".' " This allows SingleQubitQPDGates belonging to the same cut to be " - "sampled together." + "sampled jointly." ) decomp_ids.add(decomp_id) subcirc_qpd_gate_ids[-1].append([i]) From 30b82e99af455af7349c3ec10643fd71aa00b1de Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 11:15:22 -0500 Subject: [PATCH 29/40] peer review --- circuit_knitting/cutting/cutting_experiments.py | 6 +++--- test/cutting/test_cutting_experiments.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/circuit_knitting/cutting/cutting_experiments.py b/circuit_knitting/cutting/cutting_experiments.py index 0be8b7f68..408afcac9 100644 --- a/circuit_knitting/cutting/cutting_experiments.py +++ b/circuit_knitting/cutting/cutting_experiments.py @@ -36,11 +36,11 @@ def generate_cutting_experiments( expected to be a :class:`PauliList` instance. If the input circuit and observables are specified by dictionaries with partition labels - as keys, the output subexperiments will be returned as a dictionary which maps a - partition label to to a 1D array containing the subexperiments associated with that partition. + as keys, the output subexperiments will be returned as a dictionary which maps each + partition label to a 1D array containing the subexperiments associated with that partition. In both cases, the subexperiment lists are ordered as follows: - :math:`[sample_{0}observable_{0}, sample_{0}observable_{1}, ..., sample_{0}observable_{N}, ..., sample_{M}observable_{N}]` + :math:`[sample_{0}observable_{0}, sample_{0}observable_{1}, \ldots, sample_{0}observable_{N}, \ldots, sample_{M}observable_{N}]` The weights will always be returned as a 1D array -- one weight for each unique sample. diff --git a/test/cutting/test_cutting_experiments.py b/test/cutting/test_cutting_experiments.py index 5bf09a25a..15f9d5050 100644 --- a/test/cutting/test_cutting_experiments.py +++ b/test/cutting/test_cutting_experiments.py @@ -125,7 +125,7 @@ def test_generate_cutting_experiments(self): "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " 'labeled "_0" and one labeled "_1".' " This allows SingleQubitQPDGates belonging to the same cut to be " - "sampled together." + "sampled jointly." ) with self.subTest("test bad observable size"): qc = QuantumCircuit(4) From cbfb6f94ef05927c17b1d93ee14edc20f4da3544 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 11:19:07 -0500 Subject: [PATCH 30/40] pydocstyle --- circuit_knitting/cutting/cutting_experiments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_experiments.py b/circuit_knitting/cutting/cutting_experiments.py index 408afcac9..1668d708f 100644 --- a/circuit_knitting/cutting/cutting_experiments.py +++ b/circuit_knitting/cutting/cutting_experiments.py @@ -28,7 +28,7 @@ def generate_cutting_experiments( list[QuantumCircuit] | dict[str | int, list[QuantumCircuit]], list[tuple[float, WeightType]], ]: - """ + r""" Generate cutting subexperiments and their associated weights. If the input, ``circuits``, is a :class:`QuantumCircuit` instance, the From 6a7d913b0c2dd0b7857b790165a059992042e02d Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 11:26:26 -0500 Subject: [PATCH 31/40] Add release note --- .../notes/generate-experiments-2ac773442132c78d.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 releasenotes/notes/generate-experiments-2ac773442132c78d.yaml diff --git a/releasenotes/notes/generate-experiments-2ac773442132c78d.yaml b/releasenotes/notes/generate-experiments-2ac773442132c78d.yaml new file mode 100644 index 000000000..a908d21e4 --- /dev/null +++ b/releasenotes/notes/generate-experiments-2ac773442132c78d.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + Added a module, :mod:`circuit_knitting.cutting.cutting_experiments`, which is intended to hold + functions used for generating the quantum experiments needed for circuit cutting. This module + will initially hold one function, :func:`circuit_knitting.cutting.cutting_experiments.generate_cutting_experiments`, + which can be used to generate quantum experiments, given an input circuit containing + :class:`circuit_knitting.cutting.qpd.BaseQPDGate` instances, some observables, and a number + of times the joint quasi-probability distribution for the cuts should be sampled. From eb149a34e5009f3ef4933d85c9803dc6799b8520 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 11:34:00 -0500 Subject: [PATCH 32/40] cleanup --- circuit_knitting/cutting/cutting_experiments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_experiments.py b/circuit_knitting/cutting/cutting_experiments.py index 1668d708f..bf2ea2114 100644 --- a/circuit_knitting/cutting/cutting_experiments.py +++ b/circuit_knitting/cutting/cutting_experiments.py @@ -40,7 +40,7 @@ def generate_cutting_experiments( partition label to a 1D array containing the subexperiments associated with that partition. In both cases, the subexperiment lists are ordered as follows: - :math:`[sample_{0}observable_{0}, sample_{0}observable_{1}, \ldots, sample_{0}observable_{N}, \ldots, sample_{M}observable_{N}]` + :math:`[sample_{0}observable_{0}, \ldots, sample_{0}observable_{N}, \ldots, sample_{M}observable_{N}]` The weights will always be returned as a 1D array -- one weight for each unique sample. From 2591ecd5c9ec84e0782506194f9f366e32065011 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 11:35:02 -0500 Subject: [PATCH 33/40] weird doc rendering --- circuit_knitting/cutting/cutting_experiments.py | 1 + 1 file changed, 1 insertion(+) diff --git a/circuit_knitting/cutting/cutting_experiments.py b/circuit_knitting/cutting/cutting_experiments.py index bf2ea2114..566512249 100644 --- a/circuit_knitting/cutting/cutting_experiments.py +++ b/circuit_knitting/cutting/cutting_experiments.py @@ -40,6 +40,7 @@ def generate_cutting_experiments( partition label to a 1D array containing the subexperiments associated with that partition. In both cases, the subexperiment lists are ordered as follows: + :math:`[sample_{0}observable_{0}, \ldots, sample_{0}observable_{N}, \ldots, sample_{M}observable_{N}]` The weights will always be returned as a 1D array -- one weight for each unique sample. From 0d9b6637c0cb0845161007e1f81797d6377d757d Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 12:11:49 -0500 Subject: [PATCH 34/40] peer review --- releasenotes/notes/generate-experiments-2ac773442132c78d.yaml | 4 ++-- test/cutting/test_cutting_experiments.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/releasenotes/notes/generate-experiments-2ac773442132c78d.yaml b/releasenotes/notes/generate-experiments-2ac773442132c78d.yaml index a908d21e4..d1190a0c3 100644 --- a/releasenotes/notes/generate-experiments-2ac773442132c78d.yaml +++ b/releasenotes/notes/generate-experiments-2ac773442132c78d.yaml @@ -3,7 +3,7 @@ features: - | Added a module, :mod:`circuit_knitting.cutting.cutting_experiments`, which is intended to hold functions used for generating the quantum experiments needed for circuit cutting. This module - will initially hold one function, :func:`circuit_knitting.cutting.cutting_experiments.generate_cutting_experiments`, + will initially hold one function, :func:`.generate_cutting_experiments`, which can be used to generate quantum experiments, given an input circuit containing - :class:`circuit_knitting.cutting.qpd.BaseQPDGate` instances, some observables, and a number + :class:`.BaseQPDGate` instances, some observables, and a number of times the joint quasi-probability distribution for the cuts should be sampled. diff --git a/test/cutting/test_cutting_experiments.py b/test/cutting/test_cutting_experiments.py index 15f9d5050..3530afbdf 100644 --- a/test/cutting/test_cutting_experiments.py +++ b/test/cutting/test_cutting_experiments.py @@ -87,6 +87,9 @@ def test_generate_cutting_experiments(self): with pytest.raises(ValueError) as e_info: generate_cutting_experiments(qc, PauliList(["ZZZZ"]), 0) assert e_info.value.args[0] == "num_samples must be at least 1." + with pytest.raises(ValueError) as e_info: + generate_cutting_experiments(qc, PauliList(["ZZZZ"]), np.nan) + assert e_info.value.args[0] == "num_samples must be at least 1." with self.subTest("test incompatible inputs"): qc = QuantumCircuit(4) with pytest.raises(ValueError) as e_info: From 1699db4561c61863909a571de7126cafc943bd80 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 12:22:37 -0500 Subject: [PATCH 35/40] Fix incorrect error message --- circuit_knitting/cutting/cutting_evaluation.py | 11 +++++------ test/cutting/test_cutting_experiments.py | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index e8b804a3c..cbe9e3703 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -421,12 +421,11 @@ def _get_mapping_ids_by_partition( except (AttributeError, ValueError): raise ValueError( "SingleQubitQPDGate instances in input circuit(s) must have their " - 'labels suffixed with "_", where is the index of the gate ' - "relative to the other gates belonging to the same cut. For example, " - "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " - 'labeled "_0" and one labeled "_1".' - " This allows SingleQubitQPDGates belonging to the same cut to be " - "sampled jointly." + 'labels suffixed with "_", where is the index of the cut ' + "relative to the other cuts in the circuit. For example, all " + "SingleQubitQPDGates belonging to the same cut, N, should have labels " + ' formatted as "_N". This allows SingleQubitQPDGates ' + "belonging to the same cut to be sampled jointly." ) decomp_ids.add(decomp_id) subcirc_qpd_gate_ids[-1].append([i]) diff --git a/test/cutting/test_cutting_experiments.py b/test/cutting/test_cutting_experiments.py index 3530afbdf..bc1c712d2 100644 --- a/test/cutting/test_cutting_experiments.py +++ b/test/cutting/test_cutting_experiments.py @@ -123,12 +123,11 @@ def test_generate_cutting_experiments(self): ) assert e_info.value.args[0] == ( "SingleQubitQPDGate instances in input circuit(s) must have their " - 'labels suffixed with "_", where is the index of the gate ' - "relative to the other gates belonging to the same cut. For example, " - "a two-qubit gate cut can be represented by two SingleQubitQPDGates -- one " - 'labeled "_0" and one labeled "_1".' - " This allows SingleQubitQPDGates belonging to the same cut to be " - "sampled jointly." + 'labels suffixed with "_", where is the index of the cut ' + "relative to the other cuts in the circuit. For example, all " + "SingleQubitQPDGates belonging to the same cut, N, should have labels " + ' formatted as "_N". This allows SingleQubitQPDGates ' + "belonging to the same cut to be sampled jointly." ) with self.subTest("test bad observable size"): qc = QuantumCircuit(4) From 48588f1eb3520bef454f3b172462843d70d2eb7a Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 12:23:30 -0500 Subject: [PATCH 36/40] Update circuit_knitting/cutting/cutting_experiments.py Co-authored-by: Jim Garrison --- circuit_knitting/cutting/cutting_experiments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_experiments.py b/circuit_knitting/cutting/cutting_experiments.py index 566512249..b78097e6b 100644 --- a/circuit_knitting/cutting/cutting_experiments.py +++ b/circuit_knitting/cutting/cutting_experiments.py @@ -41,7 +41,7 @@ def generate_cutting_experiments( In both cases, the subexperiment lists are ordered as follows: - :math:`[sample_{0}observable_{0}, \ldots, sample_{0}observable_{N}, \ldots, sample_{M}observable_{N}]` + :math:`[sample_{0}observable_{0}, \ldots, sample_{0}observable_{N}, sample_{1}observable_{0}, \ldots, sample_{M}observable_{N}]` The weights will always be returned as a 1D array -- one weight for each unique sample. From fabfaf1bd91add63f586dc36946025b8e686eef2 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 12:55:14 -0500 Subject: [PATCH 37/40] Update error msg --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- test/cutting/test_cutting_experiments.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index cbe9e3703..80316dec3 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -424,7 +424,7 @@ def _get_mapping_ids_by_partition( 'labels suffixed with "_", where is the index of the cut ' "relative to the other cuts in the circuit. For example, all " "SingleQubitQPDGates belonging to the same cut, N, should have labels " - ' formatted as "_N". This allows SingleQubitQPDGates ' + ' formatted as "_N". This allows SingleQubitQPDGates ' "belonging to the same cut to be sampled jointly." ) decomp_ids.add(decomp_id) diff --git a/test/cutting/test_cutting_experiments.py b/test/cutting/test_cutting_experiments.py index bc1c712d2..820964360 100644 --- a/test/cutting/test_cutting_experiments.py +++ b/test/cutting/test_cutting_experiments.py @@ -126,7 +126,7 @@ def test_generate_cutting_experiments(self): 'labels suffixed with "_", where is the index of the cut ' "relative to the other cuts in the circuit. For example, all " "SingleQubitQPDGates belonging to the same cut, N, should have labels " - ' formatted as "_N". This allows SingleQubitQPDGates ' + ' formatted as "_N". This allows SingleQubitQPDGates ' "belonging to the same cut to be sampled jointly." ) with self.subTest("test bad observable size"): From bbdfb4dc067a049d309887ec5a124c1908a6a23a Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 15:14:48 -0500 Subject: [PATCH 38/40] Update circuit_knitting/cutting/cutting_experiments.py Co-authored-by: Jim Garrison --- circuit_knitting/cutting/cutting_experiments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_experiments.py b/circuit_knitting/cutting/cutting_experiments.py index b78097e6b..586a2d220 100644 --- a/circuit_knitting/cutting/cutting_experiments.py +++ b/circuit_knitting/cutting/cutting_experiments.py @@ -62,7 +62,7 @@ def generate_cutting_experiments( weight and the :class:`WeightType`. Each weight corresponds to one unique sample. Raises: - ValueError: ``num_samples`` must either be at least one. + ValueError: ``num_samples`` must be at least one. ValueError: ``circuits`` and ``observables`` are incompatible types ValueError: :class:`SingleQubitQPDGate` instances must have their cut ID appended to the gate label so they may be associated with other gates belonging From 84b6f08639bd339227f9884797e9adbf00e41d63 Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 15:18:26 -0500 Subject: [PATCH 39/40] peer review --- circuit_knitting/cutting/__init__.py | 5 +---- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/circuit_knitting/cutting/__init__.py b/circuit_knitting/cutting/__init__.py index f0f6851a5..268123d27 100644 --- a/circuit_knitting/cutting/__init__.py +++ b/circuit_knitting/cutting/__init__.py @@ -87,10 +87,7 @@ decompose_gates, PartitionedCuttingProblem, ) -from .cutting_evaluation import ( - execute_experiments, - CuttingExperimentResults, -) +from .cutting_evaluation import execute_experiments, CuttingExperimentResults from .cutting_experiments import generate_cutting_experiments from .cutting_reconstruction import reconstruct_expectation_values from .wire_cutting_transforms import cut_wires, expand_observables diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 80316dec3..9c0b2246f 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -77,7 +77,7 @@ def execute_experiments( ValueError: The input circuits may not contain any classical registers or bits. ValueError: If multiple samplers are passed, each one must be unique. """ - if num_samples <= 0: + if not num_samples >= 1: raise ValueError("The number of requested samples must be at least 1.") if isinstance(circuits, dict) and not isinstance(subobservables, dict): From a2ef91630e843248354367dcbfcb3369ba48a60a Mon Sep 17 00:00:00 2001 From: Caleb Johnson Date: Thu, 31 Aug 2023 16:08:43 -0500 Subject: [PATCH 40/40] Update circuit_knitting/cutting/cutting_evaluation.py Co-authored-by: Jim Garrison --- circuit_knitting/cutting/cutting_evaluation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuit_knitting/cutting/cutting_evaluation.py b/circuit_knitting/cutting/cutting_evaluation.py index 9c0b2246f..995aed8d9 100644 --- a/circuit_knitting/cutting/cutting_evaluation.py +++ b/circuit_knitting/cutting/cutting_evaluation.py @@ -345,7 +345,7 @@ def _generate_cutting_experiments( # If the input was a single quantum circuit, return the subexperiments as a list subexperiments_out: list[QuantumCircuit] | dict[ str | int, list[QuantumCircuit] - ] = subexperiments_dict + ] = dict(subexperiments_dict) assert isinstance(subexperiments_out, dict) if isinstance(circuits, QuantumCircuit): assert len(subexperiments_out.keys()) == 1