parityos_addons
- class parityos_addons.interfaces.CirqExporter(parameter_map: Mapping[str, object] = None, qubit_map: Mapping[Qubit, NamedQubit] = None)
Tool to convert ParityOS circuits to Cirq circuits.
Instantiate the CirqExporter with a qubit map and a parameter map. Then use the to_cirq method to convert ParityOS circuits to Cirq circuits.
- EXAMPLE:
qubit_map = {Qubit(i): cirq.NamedQubit(str(i)) for i in range(10)} parameter_map = {‘theta’: sympy.Symbol(‘theta’), ‘gamma’: sympy.Symbol(‘gamma’)} cirq_exporter = CirqExporter(qubit_map, parameter_map) cirq_circuit = cirq_exporter.to_cirq(parityos_circuit)
- __init__(parameter_map: Mapping[str, object] = None, qubit_map: Mapping[Qubit, NamedQubit] = None)
Converts the circuit to a cirq circuit.
- Parameters:
parameter_map – a mapping of the form {parameter_name: parameter_value}, where the parameter_name is a string that is used as a parameter_name in the ParityOS circuit, and parameter_value is a number like object (int, float, numpy float or a Sympy symbol are all valid). Optional. If not given, then an empty dictionary is used instead.
qubit_map – a mapping of the form {ParityOS_qubit: cirq_qubit}, where cirq_qubit is a Cirq NamedQubit instance. Optional. If not given, then ParityOS Qubits are automatically converted into cirq.NamedQubit instances with the same label.
- class parityos_addons.interfaces.QiskitExporter(parameter_map: Mapping[str, object] = None, qubit_map: Mapping[Qubit, int] = None, qubits: Iterable[Qubit] = None)
Tool to convert ParityOS circuits to Qiskit quantum circuits.
Instantiate the QiskitExporter with a qubit map and a parameter map. Then use the to_qiskit method to convert a ParityOS circuit to Qiskit quantum circuit.
- EXAMPLE:
from qisc import Parameter parameter_map = {‘theta’: Parameter(‘$theta$’), ‘gamma’: Parameter(‘$gamma$’)} qiskit_exporter = QiskitExporter(parameter_map) qiskit_circuit = qiskit_exporter.to_qiskit(parityos_circuit)
- __init__(parameter_map: Mapping[str, object] = None, qubit_map: Mapping[Qubit, int] = None, qubits: Iterable[Qubit] = None)
Converts the circuit to a Qiskit circuit.
- Parameters:
parameter_map – a mapping of the form {parameter_name: parameter_value}, where the parameter_name is a string that is used as a parameter_name in the ParityOS circuit, and parameter_value is a number like object (int, float, numpy float or a Qiskit Parameter object are all valid). Optional. If not given, then an empty dictionary is used instead.
qubit_map – a mapping of the form {ParityOS_qubit: qubit_index}, where qubit_index is the integer index of the qubit in the Qiskit qubit register. Optional.
qubits – an iterable of ParityOS qubits. This is used to generate a qubit_map where each qubit is mapped onto its index in the sequence. Optional. Either a qubit_map or a qubits iterable must be given.
- append_qiskit_gate(qiskit_circuit: <module 'qiskit.circuit' from '/usr/local/lib/python3.11/site-packages/qiskit/circuit/__init__.py'>, gate: ~parityos.base.gates.Gate)
Creates a qiskit gate corresponding to the ParityOS Gate instance and appends it to the qiskit circuit. :param qiskit_circuit: the qiskit circuit to which we want to append the gate :param gate: the ParityOS Gate that is appended to the circuit
- parityos_addons.qaoa.generate_qaoa(parityos_output: ParityOSOutput, unitary_pattern: str) tuple[Circuit, dict[str, tuple[float, float]]]
Generates a QAOA quantum circuit and a dictionary with parameter bounds. The QAOA quantum circuit is composed of several unitary propagators, related to the problem Hamiltonian, driver terms and Parity constraints. The parameter bounds dictionary maps the parameter names used in the quantum circuit onto a (lower bound, upper bound) tuple of floats for each classical QAOA parameter in the QAOA circuit.
- Parameters:
parityos_output (ParityOSOutput) –
The compiler output as an object of ParityOSOutput, containing information about the compiled problem and the raw constraint circuit, as defined in the response schema. Assumptions:
the device has only 2-body connections;
the interaction coefficients are explicit numbers, not strings.
unitary_pattern (str) –
the pattern of unitaries to use in each repetition. Should be a string with the following characters:
Z: the problem Hamiltonian
X: the driver Hamiltonian
C: the constraint Hamiltonian
The string is expressed in time order, from left to right.
- Example:
To create a ParityOS QAOA circuit of order p=3, create the circuit from a ParityOSOutput object with a unitary_pattern of order 3: qaoa_circuit, parameter_bounds = generate_qaoa(parityos_output, ‘XCZXCZXCZ’)
- class parityos_addons.spin_hamiltonians.SpinZ(label: str | int | tuple[int, ...] | Qubit)
Represents a classical Ising spin value (+1 or -1) or the Z-eigenvalue of a Pauli Z operator.
- parityos_addons.spin_hamiltonians.spinz_to_hamiltonian(expr: Add | Mul) ProblemRepresentation
Convert an expression containing sums of products of SpinZ objects into a ParityOS problem representation.
- Parameters:
expr – an expression containing sums of products of SpinZ objects
- Returns:
a ProblemRepresentation object
- parityos_addons.spin_hamiltonians.untie_spinz_product(product: Mul) tuple[frozenset[Qubit], object]
Split a product of SpinZ and other factors into a pure product of SpinZ object and the product of all the remaining factors.
- Parameters:
product – A product of SpinZ objects and other Sympy objects or numbers
- Returns:
a tuple where the first item is the product of SpinZ objects and the second item is the product of all the other factors in the term
- parityos_addons.benchmarking.benchmark_compiler_runs(client: CompilerClient, compiler_runs: Collection[CompilerRun], calculate_circuit_statistics: bool = True) DataFrame
Calculates statistics from the CompilerRun instances, by requesting the corresponding ParityOSOutputs.
- Parameters:
client – CompilerClient which should send requests to get the corresponding ParityOSOutputs
compiler_runs – Collection of CompilerRun instances
calculate_circuit_statistics – indicates if circuit statistics should be added
- Returns:
pd.DataFrame containing benchmark results
- parityos_addons.benchmarking.benchmark_parityos_outputs(parityos_outputs: Collection[ParityOSOutput], calculate_circuit_statistics: bool = True) DataFrame
Calculates statistics from the ParityOSOutput instances
- Parameters:
parityos_outputs – Collection of ParityOSOutput instances
calculate_circuit_statistics – indicates if circuit statistics should be added
- Returns:
pd.DataFrame containing benchmark results
- class parityos_addons.analog_computation.Observable(interactions: Sequence[PauliOp], coefficients: Sequence)
Representation of an Observable as a sum of PauliOps multiplied by corresponding coefficients.
- __init__(interactions: Sequence[PauliOp], coefficients: Sequence)
- Parameters:
interactions – the PauliOps that should be multiplied by the corresponding coefficients and summed up together in order to obtain the Observable.
coefficients – The coefficients in the Observable, in a sequence that aligns with the interactions sequence.
Example:
observable = Observable( [PauliOp([X(Qubit(1))]), PauliOp([Y(Qubit(1)), Y(Qubit(2))])], (0.5, -0.8), )
- evaluate(configuration: Mapping[Qubit, int]) float
Evaluates the expectation value of the Observable in specific Z eigenstates with eigenvalues +1 or -1 given by the configuration.
- Parameters:
configuration – a mapping of the qubits onto their Z eigenvalue +1 or -1.
- Returns:
the corresponding expectation value
- classmethod from_json(data)
Constructs an Observable object from JSON data.
- Parameters:
data – a JSON-like dictionary with
'interactions','coefficients'fields- Returns:
an Observable object
- classmethod from_nx_graph(graph: networkx.Graph)
- Parameters:
graph – A graph representing an optimization problem; nodes are interpreted as binary variables, and edges between them are interpreted as Z interaction terms between them (with strength given by the
weightdata on each edge).- Returns:
the Observable associated with the given
graph
- classmethod from_terms(terms: Iterator[tuple[PauliOp, float]] | Sequence[tuple[PauliOp, float]]) Observable
Creates an Observable from given terms. :param terms: sequence or iterator of (PauliOp, coefficient) tuples. :return: Observable.
- tensor(other: Observable) Observable
Return the tensor product observable self ⊗ other. self and other must not share common qubit labels. Note: Alternatively, the syntax observable1 ^ observable2 can be used to compute the tensor product between two observables
- Parameters:
other – Other observable to compute the tensor product with
- Returns:
tensor product observable self ⊗ other. If observables share common qubits a ParityOsAnalogComputationException is raised.
- property terms: Iterator[tuple[PauliOp, float]]
A property that returns an Iterator of all (interaction, coefficient) pairs.
- Returns:
an Iterator for the (interaction, coefficient) pairs
- to_json()
Converts the Observable object to json.
- Returns:
the Observable object in json-serializable format
- class parityos_addons.analog_computation.ParitySchedule(output: ParityOSOutput, interactions_coefficient: Expr = t, constraints_coefficient: Expr = t, driver_coefficient: Expr = 1.0 - t, time_parameter: Symbol = t, duration: float = 1.0)
A standard annealing Schedule for the Parity Architecture. In contrast to the Schedule class ParitySchedule knows the names of its terms: interactions_term, constraints_term, driver_term. The ParitySchedule corresponds to:
ParitySchedule = interactions_term + constraints_term + driver_term
where terms consists of an Observable and a time dependent coefficient.
- __init__(output: ParityOSOutput, interactions_coefficient: Expr = t, constraints_coefficient: Expr = t, driver_coefficient: Expr = 1.0 - t, time_parameter: Symbol = t, duration: float = 1.0)
Creates ParitySchedule from ParityOSOutput and related coefficients. :param output: ParityOSOutput to transform into a Schedule :param interactions_coefficient: sympy.Expr for the interactions term :param constraints_coefficient: sympy.Expr for the constraints term :param driver_coefficient: sympy.Expr for the driver term :param time_parameter: sympy.Symbol for the time parameter :param duration: float :return: ParitySchedule
- property constraints_coefficient: Expr
Coefficient of the constraints term
- property driver_coefficient: Expr
Coefficient of the driver term
- property duration: float
Duration of the schedule
- property interactions_coefficient: Expr
Coefficient of the interactions term
- property time_parameter: Symbol
Time parameter as sympy.Symbol
- class parityos_addons.analog_computation.PauliOp(pauli_gates: Collection[X | Y | Z] = frozenset({}))
Representation of multi-qubit Pauli operators that consist of a tensor product of Pauli gates (X, Y, Z).
- __init__(pauli_gates: Collection[X | Y | Z] = frozenset({}))
The case when pauli_gates is None corresponds to the Identity operator. Each Pauli gate should be applied to a unique qubit.
- commutes_with(other)
- Returns true if self commutes with other, otherwise false. Here, we are applying the rule
“Two Pauli strings commute iff they do not commute on an even number of indices.”
- Parameters:
other – another PauliOp
- Returns:
True or False, indicating whether self and other commute.
- evaluate(configuration: Mapping[Qubit, int]) int
Evaluates the expectation value of the PauliOp operator in specific Z eigenstates with eigenvalues +1 or -1 given by the configuration.
- Parameters:
configuration – a mapping of the qubits onto their Z eigenvalue +1 or -1.
- Returns:
the corresponding expectation value, which is either +1 or -1 or 0
- classmethod from_json(data: list) PauliOp
Initializes the PauliOp class from json
- Parameters:
data – PauliOp in json format
- Returns:
A PauliOp instance
- to_json() str | int | float | bool | None | dict[str, str | int | float | bool | None | dict[str, JSONType] | list[JSONType]] | list[str | int | float | bool | None | dict[str, JSONType] | list[JSONType]]
Converts the PauliOp to json
- Returns:
the PauliOp in json format
- class parityos_addons.analog_computation.Schedule(terms: list[ScheduleTerm], time_parameter: Symbol, duration: float = 1.0)
Representation of a Schedule defined as a sum of ScheduleTerms.
- Parameters:
terms – list of ScheduleTerms.
time_parameter – sympy.Symbol representing the time parameter.
duration – duration of the Schedule.
Example:
>>> observable_1 = Observable( >>> [PauliOp([X(Qubit(1))]), PauliOp([Y(Qubit(1)), Y(Qubit(2))])], [0.5, -0.8], >>> ) >>> observable_2 = Observable([PauliOp([Z(Qubit(1))])], [1]) >>> time = sympy.Symbol("t") >>> coefficient_1 = 3.1 * time >>> coefficient_2 = time + 4 >>> term_1 = ScheduleTerm(observable_1, coefficient_1) >>> term_2 = ScheduleTerm(observable_2, coefficient_2) >>> schedule = Schedule([term_1, term_2], time)
- __init__(terms: list[ScheduleTerm], time_parameter: Symbol, duration: float = 1.0) None
- add_term(term: ScheduleTerm) Self
Creates a new Schedule by adding an (observable, coefficient) pair. :param term: an (observable, coefficient) pair. :return: new Schedule
- property coefficients: list[Expr]
- Returns:
list of coefficients.
- classmethod compose(schedules: Iterable[Self]) Self
Compose a Schedule by combining all ScheduleTerm`s of a sequence of `Schedule`s. For that the `time_parameter and duration must be identical in all `Schedule`s.
- classmethod from_json(data: dict) Self
Constructs a Schedule object from JSON data.
- Parameters:
data – a JSON-like dictionary with
'terms','time_parameter','duration'fields.- Returns:
a Schedule object.
- property observables: list[Observable]
- Returns:
list of Observables.
- property parameters: set
- Returns:
set of the parameters that are in the list of coefficients
- subs_parameters(*args) Self
Substitutes parameters and returns a new Schedule. Passes the args to the Sympy’s subs methods. From Sympy docstrings:
- :param args:args is either:
two arguments, e.g. foo.subs(old, new)
- one iterable argument, e.g. foo.subs(iterable). The iterable may be
- o an iterable container with (old, new) pairs. In this case the
replacements are processed in the order given with successive patterns possibly affecting replacements already made.
- o a dict or set whose key/value items correspond to old/new pairs.
In this case the old/new pairs will be sorted by op count and in case of a tie, by number of args and the default_sort_key. The resulting sorted list is then processed as an iterable container (see previous).
- Returns:
a new Schedule
- to_json() dict
Converts the Schedule to json.
- Returns:
the Schedule in json-serializable format
- class parityos_addons.analog_computation.ScheduleTerm(observable: Observable, coefficient: Expr)
ScheduleTerm = coefficient * observable, where :param observable: Observable instance. :param coefficient: sympy.Expr representing a parameterized (or constant) coefficient.
- __init__(observable: Observable, coefficient: Expr) None
- classmethod from_json(data) ScheduleTerm
Constructs a ScheduleTerm object from JSON data.
- Parameters:
data – a JSON-like dictionary with the corresponding fields.
- Returns:
a ScheduleTerm object.
- property parameters: set
- Returns:
the parameters of the ScheduleTerm.
- subs_parameters(args) ScheduleTerm
Substitutes parameters and returns a new Schedule.
Passes the args to the Sympy’s subs methods. From Sympy’s docstrings: :param args:args is either:
two arguments, e.g. foo.subs(old, new)
- one iterable argument, e.g. foo.subs(iterable). The iterable may be
- o an iterable container with (old, new) pairs. In this case the
replacements are processed in the order given with successive patterns possibly affecting replacements already made.
- o a dict or set whose key/value items correspond to old/new pairs.
In this case the old/new pairs will be sorted by op count and in case of a tie, by number of args and the default_sort_key. The resulting sorted list is then processed as an iterable container (see previous).
- Returns:
a new Schedule.
- to_json() dict
Converts the ScheduleTerm to json.
- Returns:
the ScheduleTerm in json-serializable format.
- parityos_addons.analog_computation.observable_from_problem(problem_representation: ProblemRepresentation, constraint_strength: float = 1.0) Observable
Creates an Observable from ProblemRepresentation that contains both interactions and constraints.
- Parameters:
problem_representation – a ProblemRepresentation instance.
constraint_strength – the absolute value to multiply to constraint.value(s) in order to obtain the coefficients for the observable defined by constraints. ProblemRepresentation is assumed to be a minimization problem.
- Returns:
Observable.
- parityos_addons.analog_computation.observable_from_problem_constraints(problem_representation: ProblemRepresentation, constraint_strength: float = 1.0) Observable
Creates an Observable only from the constraints of the ProblemRepresentation.
- Parameters:
problem_representation – a ProblemRepresentation instance.
constraint_strength – the absolute value to multiply to constraint.value(s) in order to obtain the coefficients for the observable defined by constraints. ProblemRepresentation is assumed to be a minimization problem.
- Returns:
Observable.
- parityos_addons.analog_computation.observable_from_problem_interactions(problem_representation: ProblemRepresentation) Observable
Creates an Observable only from interactions of the ProblemRepresentation.
- Parameters:
problem_representation – a ProblemRepresentation instance.
- Returns:
Observable.
- parityos_addons.analog_computation.standard_driver_observable_for_qubits(qubits: Sequence[Qubit] | set[Qubit]) Observable
Creates a standard driver (-sum(X)) observable for qubits. :param qubits: :return: a driver Observable