Register Operations¶
A library of vectorial operations that can be applied to quantum registers.
Operations can be applied directly between registers, for example a bitwise
XOR or an addition. This is similar to how registers work on classical computers. Rotations, and
permutations in general, can be made without using any quantum gate because they just return a new
view on the qubits, i.e. a new QuantumRegister that has the same logical qubits but in a
different order.
The aim of this library is to be able to implement classical algorithms on quantum computers, to benefit from the speedup given by methods such as Grover’s algorithm.
- pyqrypto.register_operations.FEYNMAN_QC: Final[int] = 1¶
The quantum cost of the Feynman gate (CNOT).
- class pyqrypto.register_operations.RegisterCircuit(*inputs: QuantumRegister, **kwargs: Any)[source]¶
Bases:
QuantumCircuitA wrapper around
QuantumCircuit.It implements the logic needed to chain operations on quantum registers.
It supports new operations that operate on whole quantum registers and handles rotations without using any gate by rewiring the circuit when needed. This being also a fully valid
QuantumCircuit, it is also possible to apply operations on single qubits as it is normally done in Qiskit.- Parameters:
inputs – The quantum registers to use as the circuit inputs.
kwargs – Other parameters to pass to the underlying
QuantumCircuitobject.
- add(X: QuantumRegister, Y: QuantumRegister | int, ancillas: AncillaRegister | None = None, mode: str = 'ripple') QuantumRegister[source]¶
Add modulo \(2^n\) two registers of size n or a register of size n and a constant.
The adder can be implemented using different techniques:
ripple: requires 0 ancilla qubits, uses the ripple-carry method from [TTK2009].lookahead: requires \(2n-w(n-1)-\lfloor \log(n-1) \rfloor-2\) ancilla qubits, uses the carry-lookahead method from [DKRS2004].
- Parameters:
X – First register to add (the result will be stored in this register, overwriting its previous value).
Y – Second register to add or a constant.
ancillas – The anquilla register needed in
lookaheadmode.
- Mode:
The type of adder to use.
- Returns:
The output register \(X\).
- Operation:
\(X \leftarrow X+Y \bmod 2^n\)
Note
If Y is a
QuantumRegister, this operation is an addition between two registers, but if Y is an integer it becomes an addition between a register and a constant. In the latter case, the mode is alwayslookahead.
- neg(X: QuantumRegister) QuantumRegister[source]¶
Apply a bitwise NOT on a register.
- Parameters:
X – The register to apply the NOT to.
- Returns:
The output register \(X\).
- Operation:
\(X \leftarrow \neg X\)
- rol(X: QuantumRegister, r: int) QuantumRegister[source]¶
Rotate left a register by a specified amount of qubits.
- Parameters:
X – The register to rotate.
r – The number of qubits by which X should be rotated.
- Returns:
The rotated register \(X'\).
- Operation:
\(X' \leftarrow \mathrm{rol}(X, r)\)
- ror(X: QuantumRegister, r: int) QuantumRegister[source]¶
Rotate right a register by a specified amount of qubits.
- Parameters:
X – The register to rotate.
r – The number of qubits by which X should be rotated.
- Returns:
The rotated register \(X'\).
- Operation:
\(X' \leftarrow \mathrm{ror}(X, r)\)
- property stats: dict¶
Some statistics about the circuit.
quantum_cost: The quantum cost of the circuit as defined by [FoM2009].depth: The circuit depth when register operations are decomposed into NOT, CNOT and CCNOT gates.gate_counts: The number of basic gates in the circuit.
Warning
Quantum cost computation only works if the circuit contains only register operations or NOT, CNOT, and CCNOT gates.
[FoM2009]Mohammadi, M., & Eshghi, M. (2009). On figures of merit in reversible and quantum logic designs. Quantum Information Processing, 8, 297-318.
- xor(X: QuantumRegister, Y: QuantumRegister | int) QuantumRegister[source]¶
Apply a bitwise XOR between two registers or between one register and a constant.
- Parameters:
X – The first register to XOR (the result will be stored in this register, overwriting its previous value).
Y – The second register to XOR or a constant.
- Returns:
The output register \(X\).
- Operation:
\(X \leftarrow X \oplus Y\)
Note
If Y is a
QuantumRegister, this operation is a XOR between two registers, but if Y is an integer it becomes a XOR between a register and a constant.
- class pyqrypto.register_operations.RegisterConstantDKRSCarryLookaheadAdder(A: QuantumRegister, c: int, ancillas: AncillaRegister, label: str | None = None)[source]¶
Bases:
Gate,RegisterOperationAddition modulo \(2^n\) between a quantum register and a constant.
- Parameters:
X – The register of size n to add c to.
c – The constant to add to X.
label – An optional label for the gate.
- Operation:
\(X \leftarrow X + c\)
- class pyqrypto.register_operations.RegisterConstantXOR(X: QuantumRegister, c: int, label: str | None = None)[source]¶
Bases:
Gate,RegisterOperationBitwise XOR between a quantum register and a constant.
- Parameters:
X – The register to XOR with c.
c – The constant to XOR with X.
label – An optional label for the gate.
- Operation:
\(X \leftarrow X \oplus c\)
- class pyqrypto.register_operations.RegisterDKRSCarryLookaheadAdder(A: QuantumRegister, B: QuantumRegister, ancillas: AncillaRegister, label: str | None = None)[source]¶
Bases:
Gate,RegisterOperationA n qubits carry-lookahead adder modulo \(2^n\).
It implements the adder described in [DKRS2004] but skips the output carry compution.
- Parameters:
A – First register of size n to add.
B – Second register of size n to add.
ancillas – The ancilla qubits used for the computation. They must be set to 0 before the circuit and will be reset to 0.
label – An optional label for the gate.
- Raises:
CircuitError – If A and B have a different size or if there is not the correct number of ancilla qubits.
- Operation:
\(X \leftarrow X+Y \bmod 2^n\)
- class pyqrypto.register_operations.RegisterDKRSComputeCarry(P0: Sequence[QuantumRegister], G: Sequence[QuantumRegister], ancillas: AncillaRegister, label: str | None = None)[source]¶
Bases:
Gate,RegisterOperationCarry computation as described in [DKRS2004].
The last carry is not computed.
- Parameters:
P0 – Represents \(P_0[i] = p[i, i+1]\), which is 1 if and only if carry propagages from bit \(i\) to bit \(i+1\).
G – Represents \(G[i] = g[i-1, i]\), which is 1 if and only if a carry is generated between bit \(i-1\) and bit \(i\).
ancillas – The ancilla qubits used for the computation. They must be set to 0 before the circuit and will be reset to 0.
- class pyqrypto.register_operations.RegisterNOT(X: QuantumRegister, label: str | None = None)[source]¶
Bases:
Gate,RegisterOperationBitwise NOT on a quantum register.
- Parameters:
X – The register to apply NOT on.
label – An optional label for the gate.
- Oopoeration:
\(X \leftarrow \neg X\)
- class pyqrypto.register_operations.RegisterOperation[source]¶
Bases:
objectAn operation on registers of qubits.
- Variables:
inputs – The inputs registers of the operation.
outputs – The outputs registers of the operation.
- property inputs: Sequence[QuantumRegister]¶
Get the inputs of the operation.
- Returns:
A list containing the input quantum registers of the operation.
- property outputs: Sequence[QuantumRegister]¶
Get the outputs of the operation.
- Returns:
A list containing the output quantum registers of the operation.
- class pyqrypto.register_operations.RegisterPrepare(X: QuantumRegister, value: int)[source]¶
Bases:
QuantumCircuit,RegisterOperationA circuit preparing a QuantumRegister to an initial classical integer value.
- Parameters:
X – The register to prepare.
value – The value to prepare the register to.
- Operation:
\(X \leftarrow \mathrm{value}\)
- class pyqrypto.register_operations.RegisterROL(X: QuantumRegister, r: int)[source]¶
Bases:
RegisterOperationDefines the left rotation operation on a quantum register.
- Parameters:
X – The register to rotate.
r – The number of qubits by which X should be rotated.
- Raises:
CircuitError – If r is negative.
- Operation:
\(X' \leftarrow \mathrm{rol}(X, r)\)
Warning
The result will be stored in register
self.outputs[0].
- class pyqrypto.register_operations.RegisterROR(X: QuantumRegister, r: int)[source]¶
Bases:
RegisterOperationDefines the right rotation operation on a quantum register.
- Parameters:
X – The register to rotate.
r – The number of qubits by which X should be rotated.
- Raises:
CircuitError – If r is negative.
- Operation:
\(X' \leftarrow \mathrm{ror}(X, r)\)
Warning
The result will be stored in register
self.outputs[0].
- class pyqrypto.register_operations.RegisterTTKRippleCarryAdder(X: QuantumRegister, Y: QuantumRegister, label: str | None = None)[source]¶
Bases:
Gate,RegisterOperationA gate implementing the n qubits ripple-carry adder modulo \(2^n\).
It implements the adder described in [TTK2009] but skips the output carry compution.
- Parameters:
X – First register of size n to add.
Y – Second register of size n to add.
label – An optional label for the gate.
- Raises:
CircuitError – If X and Y have a different size.
- Operation:
\(X \leftarrow X+Y \bmod 2^n\)
- class pyqrypto.register_operations.RegisterXOR(X: QuantumRegister, Y: QuantumRegister, label: str | None = None)[source]¶
Bases:
Gate,RegisterOperationBitwise XOR operation between two quantum registers.
- Parameters:
X – The first register to XOR.
Y – The second register to XOR.
label – An optional label for the gate.
- Raises:
CircuitError – If X and Y have a different size.
- Operation:
\(X \leftarrow X \oplus Y\)
- pyqrypto.register_operations.SINGLE_QC: Final[int] = 1¶
The quantum cost of a single qubit gate.
- pyqrypto.register_operations.TOFFOLI_QC: Final[int] = 5¶
The quantum cost of the Toffoli gate (CCNOT).
- pyqrypto.register_operations.make_circuit(circuit: QuantumCircuit, inputs: Sequence[int], input_registers: Sequence[QuantumRegister], output_registers: Sequence[QuantumRegister]) QuantumCircuit[source]¶
Make a circuit with registers as input and measurement operations for the output registers.
Also prepare the initial values of the input registers.
- Parameters:
circuit – The base circuit that will be expanded with measurement operations and preparation operations.
inputs – A list of the initial values to assign to the input registers.
inputs_registers – A list of the input registers.
output_registers – A list of the output registers.
- Returns:
The final circuit containing the preparation step, the base circuit and the measurement step.
- pyqrypto.register_operations.run_circuit(circuit: QuantumCircuit, method: str = 'automatic', device: str = 'CPU', shots: int = 1024) Sequence[int][source]¶
Simulate a circuit and retrieve the integer values of the classical registers.
- Parameters:
circuit – The circuit to run.
method – The method to use for the simulator.
device – The device to run the simulation on (CPU or GPU).
shots – The number of times to run the simulation.
- Returns:
A list of the integers stored in the classical registers of the circuit after the circuit has been simulated. It takes into account only the most frequent result.
Note
This function needs the qiskit_aer extra dependency.
- pyqrypto.register_operations.simulate(circuit: QuantumCircuit, method: str = 'automatic', device: str = 'CPU', shots: int = 1024) Counts[source]¶
Simulate the given circuit and returns the results.
- Parameters:
circuit – The circuit to simulate.
method – The method to use for the simulator.
device – The device to run the simulation on (CPU or GPU).
shots – The number of times to run the simulation.
- Returns:
The result counts of the simulation.
Note
This function needs the qiskit_aer extra dependency.