Prescriptions#

In Qhronology, quantum circuit models of closed timelike curves (CTCs) are created as instances of the QuantumCTC class:

from qhronology.quantum.prescriptions import QuantumCTC

This provides almost identical functionality as the QuantumCircuit class (from which it is derived), differing only in the addition of the systems_respecting and systems_violating properties.

Built upon the QuantumCTC class are the various theoretical models (prescriptions) of quantum time travel. Qhronology currently implements two such prescriptions: Deutsch’s model (D-CTCs) and postselected teleportation (P-CTCs):

from qhronology.quantum.prescriptions import DCTC, PCTC

Due to their close relationship, instances of the QuantumCTC class can be created directly from instances of the QuantumCircuit class. This is achieved by way of the circuit argument in the QuantumCTC constructor, whereby all attributes of the given QuantumCircuit instance are copied (deeply) to the QuantumCTC instance during initialization. Importantly, this enables the various subclasses, such as DCTC and PCTC, to be instantiated entirely using a single QuantumCTC instance, thereby reducing duplication (of arguments) in cases where one wishes to study multiple prescriptions of the same CTC circuit.

Main class#

Please note that the documentation of this class includes only properties and methods that are either new or modified from its base class QuantumCircuit.

class QuantumCTC(
*args,
circuit: QuantumCircuit | None = None,
systems_respecting: list[int] | None = None,
systems_violating: list[int] | None = None,
**kwargs,
)[source]#

Bases: QuantumCircuit

A class for creating quantum circuit models of quantum interactions near closed timelike curves and storing their metadata.

This is built upon the QuantumCircuit class, and so inherits all of its attributes, properties, and methods.

Instances provide complete descriptions of quantum circuits involving antichronological time travel. The class however does not possess any ability to compute the output state (e.g., resolve temporal paradoxes) of the circuit; that functionality is associated with the specific prescriptions of quantum time travel, which are implemented as subclasses.

Parameters:
  • *args – Variable length argument list, passed directly to the constructor __init__ of the superclass QuantumCircuit.

  • circuit (QuantumCircuit) – An instance of the QuantumCircuit class. The values of its attributes override any other values specified in *args and **kwargs. Defaults to None.

  • systems_respecting (int | list[int]) – The numerical indices of the chronology-respecting (CR) subsystems. Defaults to [].

  • systems_violating (int | list[int]) – The numerical indices of the chronology-violating (CV) subsystems. Defaults to [].

  • **kwargs – Arbitrary keyword arguments, passed directly to the constructor __init__ of the superclass QuantumCircuit.

Note

The lists of indices specified in systems_respecting and systems_violating must both be contiguous. Additionally, the circuit’s inputs (inputs) are treated as one contiguous total state, with the indices of its subsystems exactly matching those specified in systems_respecting.

Note

It is best practice to specify only one of either systems_violating or systems_violating, never both. The properties associated with both of these constructor arguments automatically ensure that they are always complementary (with respect to the entire system space), and so only one needs to be specified.

Note

The circuit argument can be used to merge the value of every attribute from a pre-existing QuantumCircuit instance into the QuantumCTC instance. Any such mergers override the values of the attributes associated with the other arguments specified in the constructor. It is best practice to specify either of:

  • only circuit and one of either systems_respecting or systems_violating

  • *args and **kwargs (like a typical initialization of a QuantumCircuit instance) without specifying circuit

Note

The total interaction between the CR and CV systems is expected to be unitary, and so the sequence of gates in gates cannot contain any non-unitary gates (e.g., measurement operations).

Note

Post-processing (e.g., traces and postselections) cannot be performed on any chronology-violating (CV) systems (i.e., those corresponding to indices specified in systems_violating).

Examples

Code Block 7 SWAP interaction with a CTC#
from qhronology.quantum.states import MixedState
from qhronology.quantum.gates import Swap, Pauli
from qhronology.quantum.prescriptions import QuantumCTC, DCTC, PCTC

import sympy as sp

# Input
rho = sp.MatrixSymbol("ρ", 2, 2).as_mutable()
input_state = MixedState(
    spec=rho,
    conditions=[(rho[1, 1], 1 - rho[0, 0])],
    label="ρ",
)

# Gate
S = Swap(targets=[0, 1], num_systems=2)
I = Pauli(index=0, targets=[0, 1], num_systems=2)

# CTC
SWAP = QuantumCTC(inputs=[input_state], gates=[S], systems_respecting=[0])
SWAP.diagram()

# Output
# D-CTCs
SWAP_DCTC = DCTC(circuit=SWAP)
SWAP_DCTC_respecting = SWAP_DCTC.state_respecting(norm=False, label="ρ_D")
SWAP_DCTC_violating = SWAP_DCTC.state_violating(norm=False, label="τ_D")
SWAP_DCTC_respecting.conditions = [(1 - rho[0, 0], rho[1, 1])]
SWAP_DCTC_respecting.simplify()
SWAP_DCTC_violating.conditions = [(1 - rho[0, 0], rho[1, 1])]

# P-CTCs
SWAP_PCTC = PCTC(circuit=SWAP)
SWAP_PCTC_respecting = SWAP_PCTC.state_respecting(norm=False, label="ρ_P")
SWAP_PCTC_violating = SWAP_PCTC.state_violating(norm=False, label="τ_P")
SWAP_PCTC_respecting.conditions = [(1 - rho[0, 0], rho[1, 1])]
SWAP_PCTC_violating.conditions = [(1 - rho[0, 0], rho[1, 1])]
SWAP_PCTC_respecting.simplify()
SWAP_PCTC_violating.simplify()

# Results
SWAP_DCTC_respecting.print()
SWAP_DCTC_violating.print()
SWAP_PCTC_respecting.print()
SWAP_PCTC_violating.print()
>>> SWAP.diagram()
>>> SWAP_DCTC_respecting.print()
ρ_D = ρ[0, 0]|0⟩⟨0| + ρ[0, 1]|0⟩⟨1| + ρ[1, 0]|1⟩⟨0| + ρ[1, 1]|1⟩⟨1|
>>> SWAP_DCTC_violating.print()
τ_D = ρ[0, 0]|0⟩⟨0| + ρ[0, 1]|0⟩⟨1| + ρ[1, 0]|1⟩⟨0| + ρ[1, 1]|1⟩⟨1|
>>> SWAP_PCTC_respecting.print()
ρ_P = ρ[0, 0]|0⟩⟨0| + ρ[0, 1]|0⟩⟨1| + ρ[1, 0]|1⟩⟨0| + ρ[1, 1]|1⟩⟨1|
>>> SWAP_PCTC_violating.print()
τ_P = ρ[0, 0]|0⟩⟨0| + ρ[0, 1]|0⟩⟨1| + ρ[1, 0]|1⟩⟨0| + ρ[1, 1]|1⟩⟨1|
Code Block 8 CNOT interaction with a CTC#
from qhronology.quantum.states import MixedState
from qhronology.quantum.gates import Not
from qhronology.quantum.circuits import QuantumCircuit
from qhronology.quantum.prescriptions import QuantumCTC, DCTC, PCTC

import sympy as sp

# Input
rho = sp.MatrixSymbol("ρ", 2, 2).as_mutable()
input_state = MixedState(
    spec=rho,
    conditions=[(rho[1, 1], 1 - rho[0, 0])],
    label="ρ",
)

# Gate
CN = Not(targets=[0], controls=[1], num_systems=2)

# CTC
CNOT = QuantumCircuit(inputs=[input_state], gates=[CN])
CNOT = QuantumCTC(circuit=CNOT, systems_respecting=[1])
CNOT.diagram()

# Output
# D-CTCs
CNOT_DCTC = DCTC(circuit=CNOT)
CNOT_DCTC_respecting = CNOT_DCTC.state_respecting(norm=False, label="ρ_D")
CNOT_DCTC_violating = CNOT_DCTC.state_violating(norm=False, label="τ_D")
CNOT_DCTC_respecting.conditions = [(1 - rho[0, 0], rho[1, 1])]

# P-CTCs
CNOT_PCTC = PCTC(circuit=CNOT)
CNOT_PCTC_respecting = CNOT_PCTC.state_respecting(norm=True, label="ρ_P")
CNOT_PCTC_violating = CNOT_PCTC.state_violating(norm=False, label="τ_P")

# Results
CNOT_DCTC_respecting.print()
CNOT_DCTC_violating.print()
CNOT_PCTC_respecting.print()
CNOT_PCTC_violating.print()
>>> CNOT.diagram()
>>> CNOT_DCTC_respecting.print()
ρ_D = ρ[0, 0]|0⟩⟨0| + 2*g*ρ[0, 1]|0⟩⟨1| + 2*g*ρ[1, 0]|1⟩⟨0| + ρ[1, 1]|1⟩⟨1|
>>> CNOT_DCTC_violating.print()
τ_D = 1/2|0⟩⟨0| + g|0⟩⟨1| + g|1⟩⟨0| + 1/2|1⟩⟨1|
>>> CNOT_PCTC_respecting.print()
ρ_P = |0⟩⟨0|
>>> CNOT_PCTC_violating.print()
τ_P = 1/2|0⟩⟨0| + 1/2|1⟩⟨1|

Constructor argument properties#

property QuantumCTC.systems_respecting: list[int]#

The numerical indices of the chronology-respecting (CR) subsystems.

property QuantumCTC.systems_violating: list[int]#

The numerical indices of the chronology-violating (CV) subsystems.

Read-only properties#

property QuantumCTC.matrix: MutableDenseMatrix#

The matrix representation of the total CTC-circuit output state (both CR and CV systems) prior to any post-processing.

Methods#

QuantumCTC.input(
merge: bool | None = None,
conditions: list[tuple[num | expr | str, num | expr | str]] | None = None,
simplify: bool | None = None,
conjugate: bool | None = None,
norm: bool | num | expr | str | None = None,
label: str | None = None,
notation: str | None = None,
debug: bool | None = None,
) QuantumState[source]#

Construct the composite chronology-respecting (CR) input state of the closed timelike curve as a QuantumState instance and return it.

This is computed as the tensor product of the individual gates in the order in which they appear in the inputs property.

Is a vector state only when all of the component states are vectors.

Parameters:
  • merge (bool) – Whether to merge the labels of the individual quantum states into a single product, separated by "⊗" operators, prior to any notational processing. Only relevant when all states are vectors. Defaults to True.

  • conditions (list[tuple[num | expr | str, num | expr | str]]) – Algebraic conditions to be applied to the state. If False, does not substitute the conditions. Defaults to the value of self.conditions.

  • simplify (bool) – Whether to perform algebraic simplification on the state. Defaults to False.

  • conjugate (bool) – Whether to perform Hermitian conjugation on the state. Defaults to False.

  • norm (bool | num | expr | str) – The value to which the state is normalized. If True, normalizes to a value of \(1\). If False, does not normalize. Defaults to False.

  • label (str) – The unformatted string used to represent the state in mathematical expressions. Must have a non-zero length. Defaults to "⊗".join([state.label for state in self.inputs]).

  • notation (str) – The formatted string used to represent the state in mathematical expressions. When not None, overrides the value passed to label. Must have a non-zero length. Not intended to be set by the user in most cases. Defaults to "⊗".join([state.notation for state in self.inputs]) if label is None and either merge is False or the input states are all vectors, else None.

  • debug (bool) – Whether to print the internal state (held in matrix) on change. Defaults to False.

Returns:

mat – The total input state as a QuantumState instance.

Note

Passing a value of False to the merge argument results in a state whose notation is fixed and incompatible with any subsequent changes (including densification). This behaviour may be improved in the future.

QuantumCTC.diagram(
pad: tuple[int, int] | None = None,
sep: tuple[int, int] | None = None,
uniform_spacing: bool | None = None,
force_separation: bool | None = None,
style: str | None = None,
return_string: bool | None = None,
) None | str#

Print or return a diagram of the quantum circuit as a multiline string.

Parameters:
  • pad (tuple[int, int]) – A two-tuple of non-negative integers specifying intra-gate padding (i.e., the horizontal and vertical interior paddings between the content at the centre of each gate (e.g., label) and its outer edge (e.g., block border). Defaults to (0, 0).

  • sep (tuple[int, int]) – A two-tuple of non-negative integers specifying inter-gate separation (i.e., the horizontal and vertical exterior separation distances between the edges of neighbouring gates. Defaults to (1, 1).

  • uniform_spacing (bool) – Whether to uniformly space the gates horizontally such that the midpoint of each is equidistant from those of its neighbours. Defaults to False.

  • force_separation (bool) – Whether to force the horizontal gate separation to be exactly the value given in sep for all gates in the circuit. When not False, the value of uniform_spacing is ignored. Defaults to False.

  • style (str) – A string specifying the style for the circuit visualization to take. Can be any of "ascii", "unicode", or "unicode_alt". Defaults to "unicode".

  • return_string (bool) – Whether to return the assembled diagram as a multiline string. Defaults to False.

Returns:

  • None – Returned if return_string is False.

  • str – The rendered circuit diagram. Returned if return_string is True.

Note

The quality of the visualization depends greatly on the output’s configuration. For best results, the terminal should have a monospace font with good Unicode coverage.

Examples

Please see the examples of the QuantumCTC class itself. For advanced usage examples, see the corresponding diagram() method of the QuantumCircuit class.

Subclasses#

Please note that the documentation of these subclasses includes only properties and methods that are either new or modified from the base class QuantumCTC.

D-CTCs#

P-CTCs#