parityos.base

class parityos.base.constraints.EqualityConstraint(operator: Iterable[Qubit], value: int)

Represents an equality constraint of the form: \(s_1 \cdot s_2 \dots \cdot s_n = \pm 1\), where \(s_1 \dots s_n\) are spin variables.

__init__(operator: Iterable[Qubit], value: int)
Parameters:
  • operator – The operator that defines the constraint. Given as a collection of qubits, the operator is then the product of Z operators on each of the qubits.

  • value – parity of the constraint; must be +1 or -1.

classmethod from_json(constraint_data: Sequence[str | int | float | bool | None | dict[str, JSONType] | list[JSONType]]) Self

Initializes an EqualityConstraint object from json

Parameters:

constraint_data – The constraint in json format.

Returns:

An EqualityConstraint instance.

is_satisfied(configuration: dict[Qubit, int]) bool

Evaluate whether the equality constraint is satisfied by the given configuration.

Parameters:

configuration – A mapping of qubits onto their Z eigenvalue +1 or -1. All qubits from the constraint must be present in the configuration.

Returns:

True if the equality constraint is satisfied by the given configuration; False otherwise.

to_json() list[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 EqualityConstraint object to json

Returns:

The constraint in json format.

class parityos.base.constraints.ParityConstraint(qubits: Iterable[Qubit], parity: int)

The deprecated version of the EqualityConstraint class

Represents a parity constraint, which means a condition of the form: \(s_1 \cdot s_2 \dots \cdot s_n = \pm 1\) (where s_1 dots s_n are spin variables).

Parameters:
  • qubits – a collection of qubits that make up this constraint

  • parity – parity of the constraint; must be +1 or -1.

__init__(qubits: Iterable[Qubit], parity: int)
Parameters:
  • operator – The operator that defines the constraint. Given as a collection of qubits, the operator is then the product of Z operators on each of the qubits.

  • value – parity of the constraint; must be +1 or -1.

parityos.base.constraints.evaluate_parity(qubits: Iterable[Qubit], configuration: dict[Qubit, int]) int

Evaluates the product of the Pauli Z operators on a collection of qubits for a configuration of Z eigenvalues that are either +1 or -1.

The given configuration must contain Z values for all qubits.

Parameters:
  • qubits – a collection of qubits

  • configuration – a mapping the qubits onto their Z eigenvalue +1 or -1.

Returns:

value of product of the Z operators of all qubits.

class parityos.base.circuit.Circuit(iterable=(), /)

A sequence of Gate and/or Circuit objects.

classmethod from_json(data: Sequence[Sequence[str | int | float | bool | None | dict[str, JSONType] | list[JSONType]]]) Self

Creates a Circuit from a list of elements in json

Parameters:

data – a list of elements in json format

Returns:

a Circuit object

generate_flat_gate_sequence() Iterator[Gate]

Generates a sequence of all gates in the circuit and its subcircuits.

Returns:

A generator that loops over all gates in the circuit and its subcircuits.

get_hermitian_conjugate() Self

Returns the Hermitian conjugate (inverse) of the circuit :return: a new Circuit instance

modify_angle(angle_map: Mapping[frozenset[Qubit], float], gate_type: type[RMixin] = None, parameter_name: str = None) Self

Create a new circuit with the same subcircuits and gates as this one, except for the rotation gates of the given gate type and with the given parameter_name as parameter, for which the angle will be changed to the values given by the angle map, in function of the qubit(s) on which the gate acts. If the qubit(s) are not included in the angle map, then the angle is left unchanged.

If the gate type is not specified, then all rotation gates might be affected. If the parameter name is not specified, then also gates without parameters might be affected.

Parameters:
  • angle_map – A mapping that provides a new angle for each of the qubit sets on which the gates might act.

  • gate_type – Optional. If given, then only gates of this type will be updated. Other gates will be copied into the new circuit without changes. Default is None.

  • parameter_name – Optional. If given, then only gates with this parameter name will be updated. Other gates will be copied into the new circuit without changes. Default is None.

Returns:

A new circuit with all the gates copied over from the current circuit, except for selected rotation gates for which the rotation angle will have been modified. Default is None.

property parameters: set[str]
Returns:

the set of parameters (strings)

property qubits: set[Qubit]
Returns:

All qubits from the elements in the circuit

remap(context: Mapping = None, **kwargs) Circuit

Creates a copy of the circuit where the remap has been applied to all parametrized gates in the circuit (see gates.RMixin.remap for details).

Parameters:

context – a mapping of parameter names (strings) to parameter values (number-like objects) or to new parameter names (strings).

to_json() list[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 Container to json

Returns:

a list with the elements of the circuit in json format

parityos.base.circuit.convert_cnots_to_rzzs(circuit: Circuit) Circuit

ZZ rotations instead of CNOTs.

Replaces the standards CNOTs on the optimized circuit with an equivalent implementation based on ZZ and local rotations. The resulting circuit will contain additional subcircuits to account for the necessary Rx, Ry and Rz rotations.

Parameters:

circuit (Circuit) – a circuit containing moments with CNOT gates.

Returns:

a new circuit where all CNOTs have been replaced by ZZ and local rotations.

Return type:

Circuit

class parityos.base.gates.CCMixin(control1: Qubit, control2: Qubit, target: Qubit, *args, **kwargs)

Adds two control qubits to a gate. This mixin must come before the gate parent class in the new class definition.

Example:

class CCNOT(CCMixin, X): # Creates a class that stores information for a CCNOT gate.

Attributes:
control_qubits: The tuple of control qubits that can block the operation of the underlying

gate.

__init__(control1: Qubit, control2: Qubit, target: Qubit, *args, **kwargs)
Parameters:
  • control1 (Qubit)

  • control2 (Qubit) – The qubits that control whether the gate will act (if Z_control1 == Z_control2 == -1) or not (any other Z_control values).

  • target (Qubit) – The target qubit on which the controlled operation will act. If the controlled operation acts on more qubits, then these can be provided as additional arguments.

class parityos.base.gates.CCNOT(control1: Qubit, control2: Qubit, target: Qubit, *args, **kwargs)

Represents a CCNOT gate

class parityos.base.gates.CCZ(control1: Qubit, control2: Qubit, target: Qubit, *args, **kwargs)

Represents a CCZ gate

class parityos.base.gates.CH(control: Qubit, target: Qubit, *args, **kwargs)

Represents a CH gate

class parityos.base.gates.CMixin(control: Qubit, target: Qubit, *args, **kwargs)

Adds a single control qubit to a gate. This mixin must come before the gate parent class in the new class definition.

Example:

class CNOT(CMixin, X): # Creates a class that stores information for a CNOT gate.

Attributes:
control_qubits: The tuple of control qubits that can block the operation of the underlying

gate.

__init__(control: Qubit, target: Qubit, *args, **kwargs)
Parameters:
  • control (Qubit) – The qubit that controls whether the gate will act (if Z_control == -1) or not (if Z_control == 1).

  • target (Qubit) – The target qubit on which the controlled operation will act. If the controlled operation acts on more qubits, then these can be provided as additional arguments.

class parityos.base.gates.CNOT(control: Qubit, target: Qubit, *args, **kwargs)

Represents a CNOT gate

class parityos.base.gates.CP(control: Qubit, target: Qubit, *args, **kwargs)

Represents a Controled Phase gate

class parityos.base.gates.CRx(control: Qubit, target: Qubit, *args, **kwargs)

Represents a controlled Rx gate

class parityos.base.gates.CRy(control: Qubit, target: Qubit, *args, **kwargs)

Represents a controlled Ry gate

class parityos.base.gates.CRz(control: Qubit, target: Qubit, *args, **kwargs)

Represents a controlled Rz gate

class parityos.base.gates.CY(control: Qubit, target: Qubit, *args, **kwargs)

Represents a CY gate

class parityos.base.gates.CZ(control: Qubit, target: Qubit, *args, **kwargs)

Represents a CZ gate

class parityos.base.gates.ConditionalGateMixin(condition: Iterable[Qubit], target_qubits: Iterable[Qubit], **kwargs)

A mixin that allows the implementation of a gate based on a parity condition.

__init__(condition: Iterable[Qubit], target_qubits: Iterable[Qubit], **kwargs)

The *args should be the arguments that are used to construct the class that should be executed if the condition evaluates to True.

The condition is a collection of qubits, from which the most recent measurement results determine whether this gate should be executed or not. If the measurement results multiply to +1, it will be executed, if the measurement results multiply to -1 it will not be executed.

classmethod from_json(data: Sequence[str | int | float | bool | None | dict[str, JSONType] | list[JSONType]]) Self

Creates a gate from a json compatible object.

Parameters:

data – gate parameters in json compatible format

Returns:

a Gate instance

make_args() tuple
Returns:

the sequence of arguments that would be needed to instantiate a copy of self (does not include keyword only arguments).

to_json() list[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]]]
Returns:

a json compatible object with all the information about the gate.

class parityos.base.gates.ConditionalRx(condition: Iterable[Qubit], target_qubits: Iterable[Qubit], **kwargs)

An Rx gate that is only executed based on a certain parity condition

class parityos.base.gates.ConditionalX(condition: Iterable[Qubit], target_qubits: Iterable[Qubit], **kwargs)

An X gate that is only executed based on a certain parity condition

class parityos.base.gates.ConditionalZ(condition: Iterable[Qubit], target_qubits: Iterable[Qubit], **kwargs)

An X gate that is only executed based on a certain parity condition

class parityos.base.gates.Gate(*qubit_args: Qubit)

Base class from which all gates inherit.

The Gate subclasses are intended to store the information received from the compiler. They do not implement any methods to simulate the gates, nor do they contain any information on the (anti-) commutation relations between them or other mathematical properties. For those uses we recommend more elaborate frameworks like Qutip, Cirq or Qiskit.

__init__(*qubit_args: Qubit)

Set up the list of qubits on which the gate acts.

classmethod from_json(data: Sequence[str | int | float | bool | None | dict[str, JSONType] | list[JSONType]]) Self

Creates a gate from a json compatible object.

Parameters:

data – gate parameters in json compatible format

Returns:

a Gate instance

get_hermitian_conjugate() Self
Returns:

the Hermitian conjugate of the gate

make_args() tuple[Qubit, ...]
Returns:

the sequence of arguments that would be needed to instantiate a copy of self (does not include keyword only arguments).

static make_args_and_kwargs_from_json(data: Sequence[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]]]) tuple[list, dict]
Returns:

the sequence of arguments keyword arguments derived from the given json data that would be needed to create an instance of the class.

modify_angle(*args, **kwargs) Self

The RMixin.modify_angle method is used to create a new version of the gate, with the same arguments except for the angle, which might get a new value. For other gates (the subject of this version), a simple copy of the gate is returned.

property qubits: set[Qubit]
Returns:

the set of qubits on which the gate acts (including possible control qubits).

remap(*args, **kwargs) Self

The RMixin.remap method is used to remap the parameter name of parametrized gates to new values. For other gates (the subject of this version), a simple copy of the gate is returned.

to_json() list[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]]]
Returns:

a json compatible object with all the information about the gate.

class parityos.base.gates.Gate1(qubit: Qubit)

A Gate that acts on a single qubit.

__init__(qubit: Qubit)
Parameters:

qubit (Qubit) – qubit on which the gate acts.

property target_qubit: Qubit

Return the qubit on which this gate acts.

Returns:

The qubit on which the gate acts.

class parityos.base.gates.Gate2(qubit1: Qubit, qubit2: Qubit)

A Gate that acts on two qubits.

__init__(qubit1: Qubit, qubit2: Qubit)
Parameters:

qubit2 (Qubit qubit1,) – qubits on which the gate acts.

class parityos.base.gates.Gate3(qubit1: Qubit, qubit2: Qubit, qubit3: Qubit)

A Gate that acts on three qubits.

__init__(qubit1: Qubit, qubit2: Qubit, qubit3: Qubit)
Parameters:

qubit3 (Qubit qubit1, qubit2,) – qubits on which the gate acts.

class parityos.base.gates.Gate4(qubit1: Qubit, qubit2: Qubit, qubit3: Qubit, qubit4: Qubit)

A Gate that acts on four qubits.

__init__(qubit1: Qubit, qubit2: Qubit, qubit3: Qubit, qubit4: Qubit)
Parameters:

qubit4 (Qubit qubit1, qubit2, qubit3,) – qubits on which the gate acts.

class parityos.base.gates.H(qubit: Qubit)

Represents a Hadamard gate

class parityos.base.gates.HermitianGateMixin(*qubit_args: Qubit)

A mixin that implements hermitian_conjugate method for Hermitian gates.

get_hermitian_conjugate() Self
Returns:

the Hermitian conjugate of the gate, which is the copy of itself for Hermitian gates

class parityos.base.gates.ISwap(qubit1: Qubit, qubit2: Qubit)

Represents an iSwap gate

class parityos.base.gates.MeasureZ(qubit: Qubit)

A measurement of a qubit in the Z basis

class parityos.base.gates.MultiControlMixin(control_qubits: Sequence[Qubit], target: Qubit, *args, **kwargs)

Adds an arbitrary control sequence to a gate. This mixin must come before the gate parent class in the new class definition.

Example:

class MultiControlledH(MultiControlMixin, H): # Creates a class that stores information for a multi-controlled Hadamard gate.

__init__(control_qubits: Sequence[Qubit], target: Qubit, *args, **kwargs)
Parameters:
  • control_qubits – A sequence of control qubits that can block the operation of the underlying gate.

  • target – The qubit on which the underlying gate should act. If more qubits are targeted, then they can be added as additional arguments.

class parityos.base.gates.MultiControlledH(control_qubits: Sequence[Qubit], target: Qubit, *args, **kwargs)

Represents a controlled Hadamard gate with arbitrary control sequence

class parityos.base.gates.MultiControlledRx(control_qubits: Sequence[Qubit], target: Qubit, *args, **kwargs)

Represents a controlled Rx gate with arbitrary control sequence

class parityos.base.gates.MultiControlledRy(control_qubits: Sequence[Qubit], target: Qubit, *args, **kwargs)

Represents a controlled Ry gate with arbitrary control sequence

class parityos.base.gates.MultiControlledRz(control_qubits: Sequence[Qubit], target: Qubit, *args, **kwargs)

Represents a controlled Rz gate with arbitrary control sequence

class parityos.base.gates.RMixin(*args: Qubit | float, parameter_name: str = None, **kwargs)

A mixin that converts a gate into a rotated gate.

Attributes:

angle: the angle for the gate rotation parameter_name: a label that identifies the parameter with which to multiply the angle when implementing it. If no parameter name is given, then the gate is considered to be a ‘Fixed’ gate. If a parameter name is given, then the gate is considered to be a ‘Parametrized’ gate. This is reflected in the name of the gate in the output generated by the to_json method.

__init__(*args: Qubit | float, parameter_name: str = None, **kwargs)
Parameters:
  • args (Qubit) – a list of Qubits on which the gate acts

  • angle (float) – the angle for the gate rotation

  • parameter_name (str) – a label that identifies the parameter with which to multiply the angle when implementing it.

get_hermitian_conjugate() Self
Returns:

the Hermitian conjugate of the gate

make_args() tuple
Returns:

the sequence of arguments that would be needed to instantiate a copy of self.

classmethod make_args_and_kwargs_from_json(data: Sequence[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]]]) tuple[list, dict]
Returns:

the sequence of arguments keyword arguments derived from the given json data that would be needed to create an instance of the class.

modify_angle(angle_map: Mapping[frozenset[Qubit], float], gate_type: type[Gate] = None, parameter_name: str = None) Gate

Create a new gate with the same arguments as this one, except for rotation gates of the given gate type and with the given parameter_name as parameter, for which the angle will be changed to the value given by the angle map, in function of the qubit(s) on which the gate acts. If the qubit(s) are not included in the angle map, then the angle is left unchanged.

If the gate type is not specified, then all rotation gates might be affected. If the parameter name is not specified, then also gates without parameters might be affected.

Parameters:
  • angle_map – A mapping that provides a new angle for each of the qubit sets on which the gates might act.

  • gate_type – Optional. If given, then only gates of this type will be updated. Other gates will be copied into the new circuit without changes. Default is None.

  • parameter_name – Optional. If given, then only gates with this parameter name will be updated. Other gates will be copied into the new circuit without changes. Default is None.

Returns:

A new circuit with all the gates copied over from the current circuit, except for selected rotation gates for which the rotation angle will have been modified. Default is None.

property parameters: set[str]
Returns:

the set of parameters (strings)

remap(context: Mapping = None, **kwargs) Gate

Creates a copy of the gate with an updated parameter or parameter name.

Updates for the parameter should be provided either as a context mapping or as a keyword argument. If a keyword argument is given, its key must match the parameter_name defined on the gate, otherwise an error will be raised. If no keyword argument is given, then the parameter_name is looked up in the context. If it is found, then the parameter is remapped to the corresponding value. Otherwise, a copy of the gate is returned.

If the provided value is a string, then it is interpreted as a new parameter name and the resulting gate is again a parametrized gate. Otherwise, the value should be a number-like object (an int, a float, a numpy float or even a Sympy symbol or a Qiskit Parameter can be used). Then the returned gate is a fixed gate where the angle has been multiplied with the number-like object.

A keyword argument takes precedence over the context argument.

Parameters:

context – a mapping of parameter names (strings) to parameter values (number-like objects) or to new parameter names (strings).

Examples:

rz_gate = RZ(Qubit(1), angle=math.pi, parameter_name=’parameter’) # Create a copy of rz_gate where the parameter_name is changed to ‘theta’. rz_theta = rz_gate.remap(parameter=’theta’) rz_theta = rz_gate.remap({‘parameter’: ‘theta’, ‘other_parameter’: ‘gamma’})

# Convert rz_theta into a fixed gate with the angle divided by two: rz_fixed = rz_theta.remap(theta=0.5) rz_fixed = rz_theta.remap({‘theta’: 0.5, ‘gamma’: 2.5})

to_json() list[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]]]
Returns:

a json compatible object with all the information about the gate.

class parityos.base.gates.Rx(*args: Qubit | float, parameter_name: str = None, **kwargs)

Represents an RX gate

class parityos.base.gates.Rxx(*args: Qubit | float, parameter_name: str = None, **kwargs)

Represents an RXX gate

class parityos.base.gates.Ry(*args: Qubit | float, parameter_name: str = None, **kwargs)

Represents an RY gate

class parityos.base.gates.Ryy(*args: Qubit | float, parameter_name: str = None, **kwargs)

Represents an RYY gate

class parityos.base.gates.Rz(*args: Qubit | float, parameter_name: str = None, **kwargs)

Represents an RZ gate

class parityos.base.gates.Rzz(*args: Qubit | float, parameter_name: str = None, **kwargs)

Represents an RZZ gate

class parityos.base.gates.Rzzzz(*args: Qubit | float, parameter_name: str = None, **kwargs)

Represents an RZZZZ gate

class parityos.base.gates.SX(qubit: Qubit)

Represents a square root X gate

class parityos.base.gates.Swap(qubit1: Qubit, qubit2: Qubit)

Represents a Swap gate

class parityos.base.gates.X(qubit: Qubit)

Represents an X gate

class parityos.base.gates.Y(qubit: Qubit)

Represents a Y gate

class parityos.base.gates.Z(qubit: Qubit)

Represents a Z gate

class parityos.base.utils.JSONLoadSaveMixin

Mixin class that adds load and save methods.

load instantiates an object by loading the JSON representation from a file. save writes a JSON representation to file.

abstract classmethod from_json(data: str | int | float | bool | None | dict[str, JSONType] | list[JSONType]) Self

Constructs an instance from JSON data.

Parameters:

data – a JSON-like list or dict

Returns:

an instance of the class

classmethod load(filename) Self

Instantiate an object using data read from a file in JSON compatible format.

Parameters:

filename (str) – Name of the file that contains the JSON data.

Returns:

an instance of the class

save(filename: str)

Save the object to file in JSON compatible format.

Parameters:

filename – Name of the file where the JSON data will be stored.

abstract 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 instance to a json-compatible builtin Python object (float, str, list or dict).

Returns:

the instance in json-serializable format

parityos.base.utils.dict_filter(mapping: Mapping, keys: Collection[Hashable]) dict

Filter a mapping on a collection of keys.

Parameters:
  • mapping – a dictionary or mapping of key:value pairs

  • keys – a collection of keys

Returns:

a filtered dictionary containing only the keys that are both in the original mapping and in the collection of keys.

parityos.base.utils.json_wrap(item) 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 an item to the corresponding json representation. :param item: The item to convert to json

Unordered sequences (e.g. sets) are converted to sorted list, such that the JSON output will always be the same if the same set is provided.

Note that this is not a fully json compliant converter. E.g. None values are not translated to null, and boolean types are converted to 0 or 1 instead of ‘false’ or ‘true’.