diff --git a/docs/explanation/analog_interface.md b/docs/explanation/analog_interface.md deleted file mode 100644 index dfac8e30..00000000 --- a/docs/explanation/analog_interface.md +++ /dev/null @@ -1,150 +0,0 @@ -The analog interface represents a quantum experiment in terms of time evolving Hamiltonians. - -## Quantum Degrees of Freedom - -In this analog interface, we allow for 2 different quantum degrees of freedom: - -/// tab | Qubits -Qubits consist of a pair of states (spin $\uparrow$ and spin $\downarrow$). -/// -/// tab | Bosonic -Bosonic degrees of freedom form a fock space. -/// - -## Operators - -/// tab | Pauli - -The basis of operators for the qubits are the Pauli operators: - -- $\sigma^I$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.PauliI]
-- $\sigma^x$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.PauliX]
-- $\sigma^y$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.PauliY]
-- $\sigma^z$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.PauliZ]
- -/// - -/// tab | Ladder - -The basis of operators for the bosonic degree of freedom are the ladder operators: - -- $a$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.Annihilation]
-- $a^{\dagger}$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.Creation]
-- $I$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.Identity]
- -/// - -### Operator Operations - -The basis operators can be combined with the operations: - -- Addition
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.OperatorAdd]
- -- Multiplication
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.OperatorMul]
- -- Tensor Product
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.OperatorKron]
- -- Scalar Multiplication
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operator.OperatorScalarMul]
- -## Hamiltonian - -The Hamiltonian is an operator that governs interactions between quantum degrees of freedom. - -The state of the system evolves under the unitary: - -$$ -U = e^{i H t} -$$ - - -/// admonition | Example - type: example -Spin-dependent force Hamiltonian: - -$$ -H = \sigma^+ \otimes a + \sigma^- \otimes a^{\dagger} -$$ - -```py -H = PauliPlus() @ Annihilation() + PauliMinus() @ Creation() -``` - -/// - -## Analog Gate
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operation.AnalogGate]
- -The [AnalogGate][oqd_core.interface.analog.operation.AnalogGate] wraps the Hamiltonian. - -```py -gate = AnalogGate(hamiltonian=H) -``` - - -/// admonition | Note - type: note -The purpose of the [AnalogGate][oqd_core.interface.analog.operation.AnalogGate] is to accomodate dissipation during the time evolution in the future. -/// - -## Analog Circuit
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operation.AnalogCircuit]
- -The [AnalogCircuit][oqd_core.interface.analog.operation.AnalogCircuit] is the top level structure that describes a quantum experiment at the analog layer. - -An [AnalogCircuit][oqd_core.interface.analog.operation.AnalogCircuit] consist of different kinds of statements: - -/// tab | Initialize - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operation.Initialize] -//// - -Initializes all quantum degrees of freedom in the experiment: - -- Qubits $\rightarrow$ $| \downarrow \rangle$ -- Bosons $\rightarrow$ $| 0 \rangle$ - - -//// admonition | Not Implemented - type: warning -Initialize describes a global initialization. There is no support for individual initialization currently. -//// -/// - -/// tab | Evolve - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operation.Evolve] -//// - -Evolve desribes the evolution of the system with an AnalogGate for a set duration. -/// - -/// tab | Measure - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.operation.Measure] -//// - -Performs a projective measurement of all quantum degrees of freedom. - - -//// admonition | Not Implemented - type: warning -Measure describes a global measurement. There is no support for individual measurement currently. -//// -/// - -## Usage - - -/// admonition | Example - type: example - -```py -circuit = AnalogCircuit() - -circuit.initialize() -circuit.evolve(gate, duration=1) -circuit.measure() -``` - -/// diff --git a/docs/explanation/atomic_interface.md b/docs/explanation/atomic_interface.md deleted file mode 100644 index ca6e7d61..00000000 --- a/docs/explanation/atomic_interface.md +++ /dev/null @@ -1,328 +0,0 @@ -The atomic interface expresses quantum information experiments in terms of light-matter interactions. - -## System
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.system.System]
- -The system describes the properties of the trapped-ion quantum device. - -### Ion
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.system.Ion]
- -An ion is described by its set of electronic energy levels. Each energy level has its associated quantum numbers: - -- Principal quantum number -- Spin angular momentum, $S$ -- Orbital angular momentum, $L$ -- Spin-orbital angular momentum, $J = S + L$ -- Nuclear angular momentum, $I$ -- Spin-orbital-nuclear angular momentum, $F = J + I$ -- Magnetization, $m_F$ -- Energy, $E$ - -with the set of electronic energy levels, we assign two states to be the qubit states. - -Manipulating the qubit states involves driving transitions between the qubit states of the ions, either directly or indirectly. - - -/// admonition | Example - type: example - -Definiition of an [`Ion`][oqd_core.interface.atomic.system.Ion] for $^{171}\mathrm{Yb}^+$: - -```python - -downstate = Level( - label="q0", - principal=6, - spin=1/2, - orbital=0, - nuclear=1/2, - spin_orbital=1/2, - spin_orbital_nuclear=0, - spin_orbital_nuclear_magnetization=0, - energy=0, -) -upstate = Level( - label="q1", - principal=6, - spin=1/2, - orbital=0, - nuclear=1/2, - spin_orbital=1/2, - spin_orbital_nuclear=1, - spin_orbital_nuclear_magnetization=0, - energy=2*pi*12.643e9, -) -estate = Level( - label="e0", - principal=5, - spin=1/2, - orbital=1, - nuclear=1/2, - spin_orbital=1/2, - spin_orbital_nuclear=0, - spin_orbital_nuclear_magnetization=0, - energy=2*pi*811.52e12, -) - -Yb171 = Ion( - mass=171, - charge=1, - position=[0,0,0], - levels=[ - downstate, - upstate, - estate, - ], - transitions=[ - Transition( - label="q0->q1", - level1=downstate, - level2=upstate, - einsteinA=..., - ), - Transition( - label="q0->e0", - level1=downstate, - level2=estate, - einsteinA=..., - ), - Transition( - label="q1->e0", - level1=upstate, - level2=estate, - einsteinA=..., - ), - ], -) -``` - -/// - -### Phonon
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.system.Phonon]
- -In the trapped-ion system the system exhibits collective phonon modes, which are bosonic degrees of freedom. - -These phonon modes are characterized by: - -- Energy (eigenfrequency) -- Profile of the collective phonon mode in terms of the ions' motion (eigenvector) - - -/// admonition | Example - type: example - -Definition of the set of phonon modes for a trapped-ion system with a single ion: - -```python -COM_x = Phonon( - energy=2*pi*5e6, - eigenvector=[1,0,0] -) -COM_y = Phonon( - energy=2*pi*5e6, - eigenvector=[0,1,0] -) -COM_z = Phonon( - energy=2*pi*1e6, - eigenvector=[0,0,1] -) -``` - -/// - -### Other - - -/// admonition | Not Implemented - type: warning -The system is further described by a list of experimental parameters that require calibration to determine, e.g.: - -- Maximum laser power -- Laser lock frequency -- etc. - -These parameters will in the future be included in the [`System`][oqd_core.interface.atomic.system.System]. - -The [`System`][oqd_core.interface.atomic.system.System] will be retrieved from a calibration database to determine the current state of the system and the status of all calibrations required to run quantum experiments. - -/// - -## Pulse Program
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.protocol.Protocol]
- -The pulse program for a quantum experiment is described by a [`Protocol`][oqd_core.interface.atomic.protocol.Protocol]. The protocol defines the list of optical channels in the experiment and the real-time scheduling of pulses of the optical channels in order to perform the quantum experiment. - -### Optical Channel
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.protocol.Beam]
- -An optical channel is described by a [`Beam`][oqd_core.interface.atomic.protocol.Beam] with the following parameters: - -- Transition of the ion for which to reference the Beam to. -- Rabi frequency to drive the referenced transition with. -- Detuning from the resonance of the referenced transition. -- Phase of the beam relative to the clock of the ion. -- Polarization of the beam. -- Wavevector of the beam. -- Target ion addressed by the beam. - - -/// admonition | Example - type: example - -Beam used to drive a microwave Rabi oscillation in the X-axis: - -```python -microwave_beam = Beam( - transition=Transition(level1=downstate,level2=upstate,...), - rabi= 2*pi*1e6, - detuning=0, - phase=0, - polarization=... - wavevector=... - target=0 -) -``` - -/// - - -/// admonition | Note - type: note - -The following parameters may be specified with the [math interface](#explanation/math_interface): - -- Rabi frequency -- Detuning -- Phase - /// - -### Pulse
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.protocol.Pulse]
- -A pulse turns on an optical channel for a duration of time. - - -/// admonition | Example - type: example - -Pulse that drives a microwave Rabi oscillation in the X-axis for a duration $T$: - -```python -microwave_pulse = Pulse( - beam=microwave_beam, - duration=T, -) -``` - -/// - -#### Measurement - -To perform a measurement, we not only have to turn on an optical channel, we also have to turn on a detector, this is handled by the [`MeasurePulse`][oqd_core.interface.atomic.protocol.MeasurePulse]. - - -/// admonition | Example - type: example - -Pulse that drives a fluorescent transition and turns on the detector for a duration $T$: - -```python -detection_pulse = MeasurePulse( - beam=detection_beam, - duration=T, -) -``` - -/// - -### Composition of Protocols - -The pulse program for a quantum experiment is usually more complex than a pulse of a single beam. This is handled with [`SequentialProtocol`][oqd_core.interface.atomic.protocol.SequentialProtocol] and [`ParallelProtocol`][oqd_core.interface.atomic.protocol.ParallelProtocol]. - -/// tab | `SequentialProtocol` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.protocol.SequentialProtocol] -//// - -Sequential protocol applies a set of pulses or subprotocols sequentially in time. - - -//// admonition | Example - type: example - -The following protocol is for a Rabi flop and a measurement: - -```python -microwave_beam = Beam( - transition=Transition(level1=downstate,level2=upstate,...), - rabi= 2*pi*1e6, - detuning=0, - phase=0, - polarization=... - wavevector=... - target=0 -) - -detection_beam = Beam( - transition=Transition(level1=upstate,level2=estate,...), - rabi= 2*pi*1e6, - detuning=0, - phase=0, - polarization=... - wavevector=... - target=0 -) - -protocol = SequentialProtocol( - sequence=[ - Pulse(beam=raman1_beam,duration=T), - Pulse(beam=raman2_beam,duration=100e-6) - ] - ) -``` - -//// -/// - -/// tab | `ParallelProtocol` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.protocol.ParallelProtocol] -//// - -Sequential protocol applies a set of pulses or subprotocols parallel in time. - - -//// admonition | Example - type: example - -The following protocol is for a two-photon Raman transition: - -```python -raman1_beam = Beam( - transition=Transition(level1=downstate,level2=estate,...), - rabi= 2*pi*1e6, - detuning=2*pi*1e9, - phase=0, - polarization=... - wavevector=... - target=0 -) -raman2_beam = Beam( - transition=Transition(level1=upstate,level2=estate,...), - rabi= 2*pi*1e6, - detuning=2*pi*1e9, - phase=0, - polarization=... - wavevector=... - target=0 -) - -protocol = ParallelProtocol( - sequence=[ - Pulse(beam=raman1_beam,duration=T), - Pulse(beam=raman2_beam,duration=T) - ] - ) -``` - -//// - -/// diff --git a/docs/explanation/canonicalization.md b/docs/explanation/canonicalization.md deleted file mode 100644 index 6d29c498..00000000 --- a/docs/explanation/canonicalization.md +++ /dev/null @@ -1,504 +0,0 @@ -Canonicalization is used to remove redundancy in the representation. - -Consider the following two Hamiltonians: - -$$ -H_{1} = X \otimes I + I \otimes X -$$ - -$$ -H_{2} = I \otimes X + X \otimes I -$$ - -$H_{1}$ is equivalent to $H_{2}$. Hence we convert the operators to a canonical form and the canonical form of the above operator is: - -$$ -H_{c} = 1\cdot(I \otimes X) + 1\cdot(X \otimes I) -$$ - -These canonicalization steps (e.g. distribution) are done by implementing a `RewriteRule` with the corresponding logic. - -## Canonicalization Rules - -### Distribution
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.OperatorDistribute]
- -[`Distribution`][oqd_core.compiler.analog.rewrite.canonicalize.OperatorDistribute] distributes the multiplication, scalar multiplication and tensor product of operators over the addition of operators. - - -/// admonition | Example - type: example - -$$X \otimes (Y + Z) \longrightarrow X \otimes Y + X \otimes Z$$ - -//// tab | Original Graph - -```mermaid - graph TD - element0("PauliX"):::Pauli - element1("PauliY"):::Pauli - element2("PauliZ"):::Pauli - element3("OperatorAdd"):::OperatorAdd - element3 --> element1 & element2 - element4("OperatorKron"):::OperatorKron - element4 --> element0 & element3 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid - graph TD - element0("PauliX"):::Pauli - element1("PauliY"):::Pauli - element2("OperatorKron"):::OperatorKron - element2 --> element0 & element1 - element3("PauliX"):::Pauli - element4("PauliZ"):::Pauli - element5("OperatorKron"):::OperatorKron - element5 --> element3 & element4 - element6("OperatorAdd"):::OperatorAdd - element6 --> element2 & element5 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// -/// - -### Gather Math Expression
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.GatherMathExpr]
- -[`GatherMath`][oqd_core.compiler.analog.rewrite.canonicalize.GatherMathExpr] centralizes the coefficients of the operators by gathering them. - - -/// admonition | Example - type: example - -$$ X \times 3 \times I \longrightarrow 3 \times (X \times I)$$ -//// tab | Original Graph - -```mermaid - graph TD - element0("MathExpr
--------
expr = #quot;3#quot;"):::MathExpr - element1("PauliX"):::Pauli - element2("OperatorScalarMul"):::OperatorScalarMul - element2 --> element0 & element1 - element3("PauliI"):::Pauli - element4("OperatorMul"):::OperatorMul - element4 --> element2 & element3 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid - graph TD - element0("MathExpr
--------
expr = #quot;3#quot;"):::MathExpr - element1("PauliX"):::Pauli - element2("PauliI"):::Pauli - element3("OperatorMul"):::OperatorMul - element3 --> element1 & element2 - element4("OperatorScalarMul"):::OperatorScalarMul - element4 --> element0 & element3 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// -/// - -### Proper Order
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.ProperOrder]
- -[`ProperOrder`][oqd_core.compiler.analog.rewrite.canonicalize.ProperOrder] uses the associative property to convert a chain of [`OperatorAdd`][oqd_core.interface.analog.operator.OperatorAdd] or a chain of [`OperatorMul`][oqd_core.interface.analog.operator.OperatorMul] and reorder the operation order from left to right. - - -/// admonition | Example - type: example - -$$ X \otimes (Y + Z) \longrightarrow (X + Y) + Z $$ - -//// tab | Original Graph - -```mermaid - graph TD - element0("PauliX"):::Pauli - element1("PauliY"):::Pauli - element2("PauliZ"):::Pauli - element3("OperatorAdd"):::OperatorAdd - element3 --> element1 & element2 - element4("OperatorAdd"):::OperatorAdd - element4 --> element0 & element3 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid - graph TD - element0("PauliX"):::Pauli - element1("PauliY"):::Pauli - element2("OperatorAdd"):::OperatorAdd - element2 --> element0 & element1 - element3("PauliZ"):::Pauli - element4("OperatorAdd"):::OperatorAdd - element4 --> element2 & element3 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// -/// - -### Pauli Algebra
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.PauliAlgebra]
- -[`PauliAlgebra`][oqd_core.compiler.analog.rewrite.canonicalize.PauliAlgebra] applies the Pauli algebra to simplify the operator. - - -/// admonition | Example - type: example - -$$ X \times Y + I \times I \longrightarrow iZ + I $$ -//// tab | Original Graph - -```mermaid - graph TD - element0("PauliX"):::Pauli - element1("PauliY"):::Pauli - element2("OperatorMul"):::OperatorMul - element2 --> element0 & element1 - element3("PauliI"):::Pauli - element4("PauliI"):::Pauli - element5("OperatorMul"):::OperatorMul - element5 --> element3 & element4 - element6("OperatorAdd"):::OperatorAdd - element6 --> element2 & element5 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid - graph TD - element0("MathExpr
--------
expr = #quot;1j#quot;"):::MathExpr - element1("PauliZ"):::Pauli - element2("OperatorScalarMul"):::OperatorScalarMul - element2 --> element0 & element1 - element3("PauliI"):::Pauli - element4("OperatorAdd"):::OperatorAdd - element4 --> element2 & element3 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// -/// - -### Normal Order
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.NormalOrder]
- -[`NormalOrder`][oqd_core.compiler.analog.rewrite.canonicalize.NormalOrder] puts the ladder operators into normal order. - - -/// admonition | Example - type: example - -$$ C \times A + A \times C \longrightarrow C \times A + C \times A + J$$ -//// tab | Original Graph - -```mermaid - graph TD - element0("Creation"):::Ladder - element1("Annihilation"):::Ladder - element2("OperatorMul"):::OperatorMul - element2 --> element0 & element1 - element3("Annihilation"):::Ladder - element4("Creation"):::Ladder - element5("OperatorMul"):::OperatorMul - element5 --> element3 & element4 - element6("OperatorAdd"):::OperatorAdd - element6 --> element2 & element5 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid - graph TD - element0("Creation"):::Ladder - element1("Annihilation"):::Ladder - element2("OperatorMul"):::OperatorMul - element2 --> element0 & element1 - element3("Creation"):::Ladder - element4("Annihilation"):::Ladder - element5("OperatorMul"):::OperatorMul - element5 --> element3 & element4 - element6("Identity"):::Ladder - element7("OperatorAdd"):::OperatorAdd - element7 --> element5 & element6 - element8("OperatorAdd"):::OperatorAdd - element8 --> element2 & element7 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// -/// - -### Prune Identity
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.PruneIdentity]
- -[`PruneIdentity`][oqd_core.compiler.analog.rewrite.canonicalize.PruneIdentity] prunes the unnecessary ladder identities from the graph. - - -/// admonition | Example - type: example - -$$ C\times A \times J\longrightarrow C \times A$$ -//// tab | Original Graph - -```mermaid - graph TD - element0("Creation"):::Ladder - element1("Annihilation"):::Ladder - element2("OperatorMul"):::OperatorMul - element2 --> element0 & element1 - element3("Identity"):::Ladder - element4("OperatorMul"):::OperatorMul - element4 --> element2 & element3 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid - graph TD - element0("Creation"):::Ladder - element1("Annihilation"):::Ladder - element2("OperatorMul"):::OperatorMul - element2 --> element0 & element1 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// -/// - -### Sorted Order
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.SortedOrder]
- -[`SortedOrder`][oqd_core.compiler.analog.rewrite.canonicalize.SortedOrder] sorts the addition terms in operators into a predefined order. - - -/// admonition | Example - type: example - -$$ X \otimes I + I \otimes X \longrightarrow I \otimes X + X \otimes I$$ -//// tab | Original Graph - -```mermaid - graph TD - element0("PauliX"):::Pauli - element1("PauliI"):::Pauli - element2("OperatorKron"):::OperatorKron - element2 --> element0 & element1 - element3("PauliI"):::Pauli - element4("PauliX"):::Pauli - element5("OperatorKron"):::OperatorKron - element5 --> element3 & element4 - element6("OperatorAdd"):::OperatorAdd - element6 --> element2 & element5 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid - graph TD - element0("PauliI"):::Pauli - element1("PauliX"):::Pauli - element2("OperatorKron"):::OperatorKron - element2 --> element0 & element1 - element3("PauliX"):::Pauli - element4("PauliI"):::Pauli - element5("OperatorKron"):::OperatorKron - element5 --> element3 & element4 - element6("OperatorAdd"):::OperatorAdd - element6 --> element2 & element5 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// -/// - -### Scale Terms
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.rewrite.ScaleTerms]
- -[`ScaleTerms`][oqd_core.compiler.analog.rewrite.canonicalize.ScaleTerms] introduces scalar multiplication to terms without a coefficient for a more consistent reprensentation. - - -/// admonition | Example - type: example - -$$ I \otimes X + X \otimes I \longrightarrow 1*(I \otimes X) + 1*(X \otimes I)$$ -//// tab | Original Graph - -```mermaid - graph TD - element0("PauliI"):::Pauli - element1("PauliX"):::Pauli - element2("OperatorKron"):::OperatorKron - element2 --> element0 & element1 - element3("PauliX"):::Pauli - element4("PauliI"):::Pauli - element5("OperatorKron"):::OperatorKron - element5 --> element3 & element4 - element6("OperatorAdd"):::OperatorAdd - element6 --> element2 & element5 - classDef Pauli stroke:#800000,stroke-width:3px - classDef Ladder stroke:#800000,stroke-width:3px - classDef OperatorAdd stroke:#800000,stroke-width:3px - classDef OperatorScalarMul stroke:#800000,stroke-width:3px - classDef OperatorKron stroke:#800000,stroke-width:3px - classDef OperatorMul stroke:#800000,stroke-width:3px - classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -//// tab | Transformed Graph - -```mermaid -graph TD -element0("MathExpr
--------
expr = #quot;1#quot;"):::MathExpr -element1("PauliI"):::Pauli -element2("PauliX"):::Pauli -element3("OperatorKron"):::OperatorKron -element3 --> element1 & element2 -element4("OperatorScalarMul"):::OperatorScalarMul -element4 --> element0 & element3 -element5("MathExpr
--------
expr = #quot;1#quot;"):::MathExpr -element6("PauliX"):::Pauli -element7("PauliI"):::Pauli -element8("OperatorKron"):::OperatorKron -element8 --> element6 & element7 -element9("OperatorScalarMul"):::OperatorScalarMul -element9 --> element5 & element8 -element10("OperatorAdd"):::OperatorAdd -element10 --> element4 & element9 -classDef Pauli stroke:#800000,stroke-width:3px -classDef Ladder stroke:#800000,stroke-width:3px -classDef OperatorAdd stroke:#800000,stroke-width:3px -classDef OperatorScalarMul stroke:#800000,stroke-width:3px -classDef OperatorKron stroke:#800000,stroke-width:3px -classDef OperatorMul stroke:#800000,stroke-width:3px -classDef MathExpr stroke:#800000,stroke-width:3px -``` - -//// - -/// - -## Canonicalization Pass
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.compiler.analog.passes.canonicalize.analog_operator_canonicalization]
- -```mermaid -stateDiagram-v2 - -[*] --> distribution_pass: done -distribution_pass --> ProperOrder: done -ProperOrder --> pauli_algebra_pass: done -pauli_algebra_pass --> GatherPauli: done -GatherPauli --> VerifyHilbertSpaceDim: done -VerifyHilbertSpaceDim --> normal_order_pass: done -normal_order_pass --> PruneIdentity: pass -PruneIdentity --> scale_terms_pass: done -scale_terms_pass --> SortedOrder: done -SortedOrder --> math_canonicalization_pass: done -math_canonicalization_pass --> end: done -``` diff --git a/docs/explanation/math_interface.md b/docs/explanation/math_interface.md deleted file mode 100644 index fd304efa..00000000 --- a/docs/explanation/math_interface.md +++ /dev/null @@ -1,134 +0,0 @@ -The math interface is utilized to specify arbitrary profiles for operands in other interfaces. - -## Math Expression
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathExpr]
- -[MathExpr][oqd_core.interface.math.MathExpr] represents a mathematical expression. - -## Primitives - -The primitives of the math interface consist of: - -/// tab | `MathNum` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathNum] -//// - -[`MathNum`][oqd_core.interface.math.MathNum] represents a number. - - -/// admonition | Note - type: note -Numbers are considered to belong to the real numbers, i.e. they can be positive or negative floats. -/// -/// - -/// tab | `MathImag` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathImag] -//// - -[`MathImag`][oqd_core.interface.math.MathImag] represents the imaginary unit. -/// - -/// tab | `MathVar` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathVar] -//// - -[`MathVar`][oqd_core.interface.math.MathVar] represents a protected named variable to be substituted during compile time or runtime. -/// - -## Operators - -The compatible operators for the math interface consist of: - -/// tab | `MathAdd` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathAdd] -//// - -[`MathAdd`][oqd_core.interface.math.MathAdd] represents an addition of two expressions. -/// - -/// tab | `MathMul` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathMul] -//// - -[`MathMul`][oqd_core.interface.math.MathMul] represents an multiplication of two expressions. -/// - -/// tab | `MathPow` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathPow] -//// - -[`MathPow`][oqd_core.interface.math.MathPow] represents an exponentiation of an expression with the other expression. -/// - -/// tab | `MathSub` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathSub] -//// - -[`MathSub`][oqd_core.interface.math.MathSub] represents an subtraction of two expressions. -/// - -/// tab | `MathDiv` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathDiv] -//// - -[`MathDiv`][oqd_core.interface.math.MathDiv] represents an division of two expressions. -/// - -/// tab | `MathFunc` - -//// html | div[style='float: right'] -[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.math.MathFunc] -//// - -[`MathFunc`][oqd_core.interface.math.MathFunc] represents the application of a named function on an expression. - -The compatible named functions include: - -- trigonometric (`sin`, `cos`, `tan`) -- inverse trigonometric functions (`asin`, `acos`, `atan`, `atan2`) -- hyperbolic trigonometric (`sinh`, `cosh`, `tanh`) -- inverse hyperbolic trigonometric functions (`asinh`, `acosh`, `atanh`) -- exponential (`exp`) -- logarithm (`log`) -- complex number functions (`real`, `imag`, `conj`, `abs`) -- step function (`heaviside`) - -/// - -## Usage - - -/// admonition | Example - type: example - -$$ -10 \sin^2(\omega t + \phi) -$$ - -```py -expr = ( - 10 - * MathFunc( - func="sin", expr=MathVar(name="omega") * MathVar(name="t") + MathVar(name="phi") - ) - ** 2 -) -``` - -/// diff --git a/docs/frontend/analog_frontend.md b/docs/frontend/analog_frontend.md new file mode 100644 index 00000000..885aef13 --- /dev/null +++ b/docs/frontend/analog_frontend.md @@ -0,0 +1,67 @@ +The analog frontend provides tools to convert analog source text into a parsed tree and to convert a parsed tree back into source text. + +## Frontend Components + +The analog frontend is implemented in `src/oqd_core/frontend/analog`. + +### ANTLR4 Generated Files + +These files are generated from the grammar `src/grammar/analog` using ANTLR4: + +- [`AnalogLexer.py`](../../src/oqd_core/frontend/analog/AnalogLexer.py) +- [`AnalogParser.py`](../../src/oqd_core/frontend/analog/AnalogParser.py) +- [`AnalogLexer.tokens`](../../src/oqd_core/frontend/analog/AnalogLexer.tokens) +- [`AnalogParser.tokens`](../../src/oqd_core/frontend/analog/AnalogParser.tokens) +- [`AnalogLexer.interp`](../../src/oqd_core/frontend/analog/AnalogLexer.interp) +- [`AnalogParser.interp`](../../src/oqd_core/frontend/analog/AnalogParser.interp) +- [`AnalogParserListener.py`](../../src/oqd_core/frontend/analog/AnalogParserListener.py) +- [`AnalogParserVisitor.py`](../../src/oqd_core/frontend/analog/AnalogParserVisitor.py) + +For more details on the analog grammar, see [`analog_grammar.md`](../grammar/analog_grammar.md). + +### AST Builder + +[`AnalogCircuitAST.py`](../../src/oqd_core/frontend/analog/AnalogCircuitAST.py) contains the implementation of the AST Builder. The `parse_analog` function uses the `AnalogASTBuilder` class to convert the analog source text into an [`AnalogCircuit`][oqd_core.interface.analog.circuit.AnalogCircuit]. + +### Serializer + +[`serialize.py`](../../src/oqd_core/frontend/analog/serialize.py) contains the implementation of the serializer. The `serialize_analog` function uses the `SerializeAnalog` class to convert an [`AnalogCircuit`][oqd_core.interface.analog.circuit.AnalogCircuit] into analog source text. + +## Usage of the AST Builder and Serializer + +### Parse Analog Source + + +/// admonition | Example + type: example + +```py +from oqd_core.frontend.analog import parse_analog + +source = """ +q = qreg(2) +h = %X %@ %I +evolve(h, 1.0, q) +measure(q) +""" + +circuit = parse_analog(source) +``` + +/// + +### Serialize an Analog Circuit + + +/// admonition | Example + type: example + +```py +from oqd_core.frontend.analog import parse_analog, serialize_analog + +source = "q = qreg(1)\ninitialize(q)\nmeasure(q)\n" +circuit = parse_analog(source) +serialized = serialize_analog(circuit) +``` + +/// diff --git a/docs/frontend/atomic_frontend.md b/docs/frontend/atomic_frontend.md new file mode 100644 index 00000000..f19d5d50 --- /dev/null +++ b/docs/frontend/atomic_frontend.md @@ -0,0 +1,75 @@ +The atomic frontend provides tools to convert atomic source text into a parsed tree and to convert a parsed tree back into source text. + +## Frontend Components + +The atomic frontend is implemented in `src/oqd_core/frontend/atomic`. + +### ANTLR4 Generated Files + +These files are generated from the grammar `src/grammar/atomic` using ANTLR4: + +- [`AtomicLexer.py`](../../src/oqd_core/frontend/atomic/AtomicLexer.py) +- [`AtomicParser.py`](../../src/oqd_core/frontend/atomic/AtomicParser.py) +- [`AtomicLexer.tokens`](../../src/oqd_core/frontend/atomic/AtomicLexer.tokens) +- [`AtomicParser.tokens`](../../src/oqd_core/frontend/atomic/AtomicParser.tokens) +- [`AtomicLexer.interp`](../../src/oqd_core/frontend/atomic/AtomicLexer.interp) +- [`AtomicParser.interp`](../../src/oqd_core/frontend/atomic/AtomicParser.interp) +- [`AtomicParserListener.py`](../../src/oqd_core/frontend/atomic/AtomicParserListener.py) +- [`AtomicParserVisitor.py`](../../src/oqd_core/frontend/atomic/AtomicParserVisitor.py) + +For more details on the atomic grammar, see [`atomic_grammar.md`](../grammar/atomic_grammar.md). + +### AST Builder + +[`AtomicCircuitAST.py`](../../src/oqd_core/frontend/atomic/AtomicCircuitAST.py) contains the implementation of the AST Builder. The `parse_atomic` function uses the `AtomicASTBuilder` class to convert the atomic source text into an [`AtomicCircuit`][oqd_core.interface.atomic.circuit.AtomicCircuit]. + +### Serializer + +[`serialize.py`](../../src/oqd_core/frontend/atomic/serialize.py) contains the implementation of the serializer. The `serialize_atomic` function uses the `SerializeAtomic` class to convert an [`AtomicCircuit`][oqd_core.interface.atomic.circuit.AtomicCircuit] into atomic source text. + +## Usage of the AST Builder and Serializer + +### Parse Atomic Source + + +/// admonition | Example + type: example + +```py +from oqd_core.frontend.atomic import parse_atomic + +source = """ +ions = ionreg(2) +mw = beam(2.0, 1.0, 0.0, [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]) +pulse1 = pulse(mw, 1e-5, ions[0]) +parallel { +pulse(mw, 5e-6, ions[0], false) +pulse(mw, 5e-6, ions[1], true) +} +""" + +circuit = parse_atomic(source) +``` + +/// + +### Serialize an Atomic Circuit + + +/// admonition | Example + type: example + +```py +from oqd_core.frontend.atomic import parse_atomic, serialize_atomic + +source = """ +ions = ionreg(1) +mw = beam(2.0, 1.0, 0.0, [1.0, 0.0, 0.0], [0.0, 0.0, 1.0]) +pulse(mw, 1e-5, ions[0], true) +""" + +circuit = parse_atomic(source) +serialized = serialize_atomic(circuit) +``` + +/// diff --git a/docs/grammar/analog_grammar.md b/docs/grammar/analog_grammar.md new file mode 100644 index 00000000..af8cdeb4 --- /dev/null +++ b/docs/grammar/analog_grammar.md @@ -0,0 +1,85 @@ +The analog grammar defines the text syntax for the analog frontend. + +It is implemented with ANTLR4 using: + +- [`AnalogLexer.g4`](../../src/grammar/analog/AnalogLexer.g4) for tokens +- [`AnalogParser.g4`](../../src/grammar/analog/AnalogParser.g4) for grammar rules + +## ANTLR4 Basics + +ANTLR4 splits the language definition into two parts: + +- A lexer grammar that converts characters into tokens +- A parser grammar that converts tokens into a parse tree + +## Grammar Features + +### Program and Blocks + +- `program` is the container for the code +- `block` supports newline-separated statements and empty lines +- `statement` supports declarations, control flow, and expressions + +### Statements and Control Flow + +The grammar supports: + +- Variable declarations with `declaration` +- Conditionals with `ifelse_stmt` +- Loops with `while_stmt` +- Loop control with `break_stmt` and `continue_stmt` + +### Registers, Lists, and Indexing + +The grammar includes register constructors and list extraction: + +- `quantum_register` +- `mode_register` +- `analog_list` +- `analog_list_extract` + +### Expressions and Operators + +The grammar supports: + +- Arithmetic precedence through `aexpr`, `mexpr`, `uexpr`, and `eexpr` +- Boolean logic with both word and symbolic forms (`and`/`&&`, `or`/`||`, `not`/`!`) +- Comparators (`==`, `!=`, `<`, `<=`, `>`, `>=`) +- Arithmetic operator tokens (`+`, `-`, `*`, `/`, `^`) +- Analog operator tokens (`%@`, `%+`, `%-`, `%*`) + +### Literals, Functions, and Operators + +The lexer defines: + +- Integer and float literals (`INT`, `FLOAT`) +- Math variables (`MATH_VAR`) and imaginary literal (`IMAG`) +- Function names (`abs`, `sin`, `cos`, `tan`, `exp`, `log`, `sinh`, `cosh`, `tanh`, `atan`, `acos`, `asin`, `atanh`, `asinh`, `acosh`, `heaviside`, `conj`, `real`, `imag`, `atan2`) +- Quantum operator tokens (`%I`, `%X`, `%Y`, `%Z`, `%C`, `%A`, `%J`) + +### Built-in Functions + +The grammar supports the core analog statements through `initialize`, `evolve`, and `measure`: + +- `initialize(targets)` + - `targets`: target expression (`expr`) +- `measure(targets)` + - `targets`: target expression (`expr`) +- `evolve(hamiltonian, duration, targets)` + - `hamiltonian`: operator expression (`expr`) + - `duration`: math expression (`aexpr`) + - `targets`: target expression (`expr`) + +## Generate Parser Files for Frontend + +Run generation from the grammar directory and output generated files into `src/oqd_core/frontend/analog`. Run `antlr4` on the Lexer first, and then the Parser, as the Parser depends on the Lexer. + +```bash +uv sync +source .venv/bin/activate +cd src/grammar/analog +antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/analog AnalogLexer.g4 +antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/analog AnalogParser.g4 +``` + +This generates lexer, parser, listener, and visitor artifacts used by the frontend parser pipeline. diff --git a/docs/grammar/atomic_grammar.md b/docs/grammar/atomic_grammar.md new file mode 100644 index 00000000..01118314 --- /dev/null +++ b/docs/grammar/atomic_grammar.md @@ -0,0 +1,87 @@ +The atomic grammar defines the text syntax for the atomic frontend. + +It is implemented with ANTLR4 using: + +- [`AtomicLexer.g4`](../../src/grammar/atomic/AtomicLexer.g4) for tokens +- [`AtomicParser.g4`](../../src/grammar/atomic/AtomicParser.g4) for grammar rules + +## ANTLR4 Basics + +ANTLR4 splits the language definition into two parts: + +- A lexer grammar that converts characters into tokens +- A parser grammar that converts tokens into a parse tree + +## Grammar Features + +### Program and Blocks + +- `program` is the container for the code +- `block` supports newline-separated statements and empty lines +- `statement` supports declarations, control flow, and expressions + +### Statements and Control Flow + +The grammar supports: + +- Variable declarations with `declaration` +- Conditionals with `ifelse_stmt` +- Loops with `while_stmt` +- Loop control with `break_stmt` and `continue_stmt` + +### Registers, Lists, and Indexing + +The grammar includes register constructors and list extraction: + +- `ion_register` +- `atomic_list` +- `atomic_list_extract` + +### Expressions and Operators + +The grammar supports: + +- Arithmetic precedence through `aexpr`, `mexpr`, `uexpr`, and `eexpr` +- Boolean logic with both word and symbolic forms (`and`/`&&`, `or`/`||`, `not`/`!`) +- Comparators (`==`, `!=`, `<`, `<=`, `>`, `>=`) +- Arithmetic operator tokens (`+`, `-`, `*`, `/`, `^`) + +### Literals, Functions, and Operators + +The lexer defines: + +- Integer and float literals (`INT`, `FLOAT`) +- Math variables (`MATH_VAR`) and imaginary literal (`IMAG`) +- Function names (`abs`, `sin`, `cos`, `tan`, `exp`, `log`, `sinh`, `cosh`, `tanh`, `atan`, `acos`, `asin`, `atanh`, `asinh`, `acosh`, `heaviside`, `conj`, `real`, `imag`, `atan2`) + +### Built-in Functions + +The grammar supports the core atomic statements through `beam`, `pulse`, and `parallel`. + +- `beam(frequency, rabi, phase, polarization, wavevector)` + - `frequency`: math expression (`aexpr`) + - `rabi`: math expression (`aexpr`) + - `phase`: math expression (`aexpr`) + - `polarization`: vector expression (`aexpr`), + - `wavevector`: vector expression (`aexpr`), +- `pulse(beam, duration, target[, measured])` + - `beam`: beam expression (`aexpr`), + - `duration`: math expression (`aexpr`) + - `target`: target expression (`aexpr`) + - `measured`: boolean expression (`aexpr`), optional, defaults to `false` +- `parallel { ... }` + - `...`: block (`block`) containing pulse statements to run in parallel + +## Generate Parser Files for Frontend + +Run generation from the grammar directory and output generated files into `src/oqd_core/frontend/atomic`. Run `antlr4` on the Lexer first, and then the Parser, as the Parser depends on the Lexer. + +```bash +uv sync +source .venv/bin/activate +cd src/grammar/atomic +antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/atomic AtomicLexer.g4 +antlr4 -Dlanguage=Python3 -visitor -listener -o ../../oqd_core/frontend/atomic AtomicParser.g4 +``` + +This generates lexer, parser, listener, and visitor artifacts used by the frontend parser pipeline. diff --git a/docs/interfaces/analog_interface.md b/docs/interfaces/analog_interface.md new file mode 100644 index 00000000..764b2874 --- /dev/null +++ b/docs/interfaces/analog_interface.md @@ -0,0 +1,134 @@ +The analog interface represents a quantum experiment in terms of time evolving Hamiltonians. + +## Quantum Degrees of Freedom + +In this analog interface, we allow for 2 different quantum degrees of freedom: + +- Qubits consist of a pair of states (spin $\uparrow$ and spin $\downarrow$). +- Bosonic degrees of freedom form a fock space. + +They are implemented using registers and index-based extraction: + +- [`QuantumRegister`][oqd_core.interface.analog.expr.QuantumRegister] creates a qubit register +- [`ModeRegister`][oqd_core.interface.analog.expr.ModeRegister] creates a bosonic mode register +- [`Extract`][oqd_core.interface.analog.expr.Extract] accesses a target by index +- [`AnalogList`][oqd_core.interface.analog.expr.AnalogList] collects analog expressions in a list + +## Analog Operators + +/// tab | Pauli + +The basis of operators for the qubits are the Pauli operators: + +- $\sigma^I$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.PauliI]
+- $\sigma^x$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.PauliX]
+- $\sigma^y$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.PauliY]
+- $\sigma^z$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.PauliZ]
+ +/// + +/// tab | Ladder + +The basis of operators for the bosonic degree of freedom are the ladder operators: + +- $a$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.Annihilation]
+- $a^{\dagger}$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.Creation]
+- $I$
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.Identity]
+ +/// + +### Operator Operations + +The basis operators can be combined with the operations: + +- Addition
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.OperatorAdd]
+ +- Subtraction
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.OperatorSub]
+ +- Multiplication
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.OperatorMul]
+ +- Tensor Product
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.OperatorKron]
+ +## Math Expressions + +Analog parameters support math expressions. + +### Math Primitives + +- [`MathNum`][oqd_core.interface.analog.expr.MathNum] represents numeric literals in analog math expressions. +- [`MathImag`][oqd_core.interface.analog.expr.MathImag] represents the imaginary unit. +- [`MathVar`][oqd_core.interface.analog.expr.MathVar] represents compile-time variables in expressions. + +### Math Operations + +- Addition
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.MathAdd]
+- Subtraction
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.MathSub]
+- Multiplication
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.MathMul]
+- Division
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.MathDiv]
+- Exponentiation
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.MathPow]
+- Named functions
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.MathFunc]
+ +Compatible named functions include: +`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `exp`, `log`, `real`, `imag`, `conj`, `abs`, `heaviside`. + +## Boolean Expressions + +Boolean expressions are used for conditional and loop control flow.
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.Bool]
+ +### Boolean Operations + +- NOT
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolNot]
+- AND
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolAnd]
+- OR
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolOr]
+- Equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolEq]
+- Not equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolNotEq]
+- Less than
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolLessThan]
+- Less than or equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolLessThanEq]
+- Greater than
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolGreaterThan]
+- Greater than or equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.analog.expr.BoolGreaterThanEq]
+ + +# Analog Circuit + +The [AnalogCircuit][oqd_core.interface.analog.circuit.AnalogCircuit] is the top level structure that contains analog statements and control flow. + +## Statements + +### Analog Operations + +- [`Initialize`][oqd_core.interface.analog.expr.Initialize] initializes the specified targets before evolution. + +- [`Evolve`][oqd_core.interface.analog.expr.Evolve] applies a Hamiltonian for a duration on the specified targets. + +- [`Measure`][oqd_core.interface.analog.expr.Measure] performs measurement on the specified targets. + +### Declarations + +- [`Declaration`][oqd_core.interface.analog.statement.Declaration] binds an expression result to a named identifier for later use. + +### Control Flow + +- [`IfElse`][oqd_core.interface.analog.statement.IfElse] conditionally executes `then_branch` or `else_branch`. + +- [`While`][oqd_core.interface.analog.statement.While] implements the While loop when the condition is true. + +- [`Break`][oqd_core.interface.analog.statement.Break] exits the innermost loop. + +- [`Continue`][oqd_core.interface.analog.statement.Continue] skips to the next loop iteration. + +## Usage + + +/// admonition | Example + type: example + +```py +from oqd_core.interface.analog import AnalogCircuit, Initialize, Measure, Evolve + +circuit = AnalogCircuit() +circuit.Initialize(targets=q) +circuit.Evolve(hamiltonian=H, duration=1, targets=q) +circuit.Measure(targets=q) +``` + +/// diff --git a/docs/interfaces/atomic_interface.md b/docs/interfaces/atomic_interface.md new file mode 100644 index 00000000..10044510 --- /dev/null +++ b/docs/interfaces/atomic_interface.md @@ -0,0 +1,100 @@ +The atomic interface expresses quantum information experiments in terms of light-matter interactions. + +## Ions + +Ions are implemented through ion registers and index-based extraction. + +- [`IonRegister`][oqd_core.interface.atomic.expr.IonRegister] creates an ion register +- [`Extract`][oqd_core.interface.atomic.expr.Extract] accesses a target ion by index +- [`AtomicList`][oqd_core.interface.atomic.expr.AtomicList] collects Atomic Expressions in a list + +## Math Expressions + +Atomic parameters support math expressions. + +### Math Primitives + +- [`MathNum`][oqd_core.interface.atomic.expr.MathNum] represents numeric literals in atomic math expressions. +- [`MathImag`][oqd_core.interface.atomic.expr.MathImag] represents the imaginary unit. +- [`MathVar`][oqd_core.interface.atomic.expr.MathVar] represents compile-time variables in expressions. + +### Math Operations + +- Addition
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.MathAdd]
+- Subtraction
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.MathSub]
+- Multiplication
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.MathMul]
+- Division
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.MathDiv]
+- Exponentiation
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.MathPow]
+- Named functions
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.MathFunc]
+ +Compatible named functions include: +`sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `exp`, `log`, `real`, `imag`, `conj`, `abs`, `heaviside`. + +## Boolean Expressions + +Boolean expressions are used for conditional and loop control flow.
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.Bool]
+ +### Boolean Operations + +- NOT
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolNot]
+- AND
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolAnd]
+- OR
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolOr]
+- Equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolEq]
+- Not equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolNotEq]
+- Less than
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolLessThan]
+- Less than or equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolLessThanEq]
+- Greater than
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolGreaterThan]
+- Greater than or equal
[![](https://img.shields.io/badge/Implementation-7C4DFF)][oqd_core.interface.atomic.expr.BoolGreaterThanEq]
+ + +# Atomic Circuit + +The [`AtomicCircuit`][oqd_core.interface.atomic.circuit.AtomicCircuit] is the top-level structure that contains atomic statements and control flow. + +## Statements + +### Atomic Operations + +- [`Beam`][oqd_core.interface.atomic.expr.Beam] represents the optical channel. + +- [`Pulse`][oqd_core.interface.atomic.expr.Pulse] applies a beam for a duration on a target ion. + +- [`ParallelProtocol`][oqd_core.interface.atomic.statement.ParallelProtocol] composes pulses in a parallel fashion. + +### Declarations + +- [`Declaration`][oqd_core.interface.atomic.statement.Declaration] binds an expression result to a named identifier for later use. + +### Control Flow + +- [`IfElse`][oqd_core.interface.atomic.statement.IfElse] conditionally executes `then_branch` or `else_branch`. + +- [`While`][oqd_core.interface.atomic.statement.While] implements the While loop when the condition is true. + +- [`Break`][oqd_core.interface.atomic.statement.Break] exits the innermost loop. + +- [`Continue`][oqd_core.interface.atomic.statement.Continue] skips to the next loop iteration. + +## Usage + + +/// admonition | Example + type: example + +```py +from oqd_core.interface.atomic import AtomicCircuit, Beam + +circuit = AtomicCircuit() + +mw = Beam( + frequency=2.0, + rabi=1.0, + phase=0.0, + polarization=[1.0, 0.0, 0.0], + wavevector=[0.0, 0.0, 1.0], +) + +circuit.pulse(duration=10e-6, target=0, beam=mw, measured=False) +``` + +/// diff --git a/docs/reference/analog_interface.md b/docs/reference/analog_interface.md index 1a0fe394..a73818da 100644 --- a/docs/reference/analog_interface.md +++ b/docs/reference/analog_interface.md @@ -1,43 +1,77 @@ -## Operations +::: oqd_core.interface.analog +## Circuit -::: oqd_core.interface.analog.operation +::: oqd_core.interface.analog.circuit options: heading_level: 3 members: [ "AnalogCircuit", - "AnalogGate", - "AnalogOperation", - "Evolve", - "Measure", - "Initialize", ] -## Operators +## Expressions -::: oqd_core.interface.analog.operator +::: oqd_core.interface.analog.expr options: heading_level: 3 members: [ - "Operator", - "OperatorTerminal", - "Pauli", + "AnalogExpr", + "AnalogExprSubtypes", + "CastAnalogExpr", + "Terminal", + "Access", + "QuantumRegister", + "ModeRegister", + "MathExpr", + "MathVar", + "MathNum", + "MathImag", + "MathFunc", + "MathAdd", + "MathSub", + "MathMul", + "MathDiv", + "MathPow", + "BoolExpr", + "Bool", + "BoolNot", + "BoolAnd", + "BoolOr", + "BoolEq", + "BoolNotEq", + "BoolLessThan", + "BoolLessThanEq", + "BoolGreaterThan", + "BoolGreaterThanEq", "PauliI", "PauliX", "PauliY", "PauliZ", - "PauliPlus", - "PauliMinus", - "Ladder", "Creation", "Annihilation", "Identity", - "OperatorBinaryOp", "OperatorAdd", "OperatorSub", "OperatorMul", - "OperatorScalarMul", "OperatorKron", - "OperatorSubtypes", + "AnalogList", + "Extract", + "Initialize", + "Evolve", + "Measure", + ] + + +## Statements + +::: oqd_core.interface.analog.statement + options: + heading_level: 3 + members: [ + "Declaration", + "IfElse", + "While", + "Break", + "Continue", ] diff --git a/docs/reference/atomic_interface.md b/docs/reference/atomic_interface.md index 3d9c2536..5dfebc7e 100644 --- a/docs/reference/atomic_interface.md +++ b/docs/reference/atomic_interface.md @@ -1 +1,81 @@ ::: oqd_core.interface.atomic + +## Circuit + +::: oqd_core.interface.atomic.circuit + options: + heading_level: 3 + members: [ + "AtomicCircuit", + ] + + +## Expressions + +::: oqd_core.interface.atomic.expr + options: + heading_level: 3 + members: [ + "AtomicExpr", + "AtomicExprSubtypes", + "CastAtomicExpr", + "Terminal", + "Access", + "IonRegister", + "MathExpr", + "MathVar", + "MathNum", + "MathImag", + "MathFunc", + "MathAdd", + "MathSub", + "MathMul", + "MathDiv", + "MathPow", + "BoolExpr", + "Bool", + "BoolNot", + "BoolAnd", + "BoolOr", + "BoolEq", + "BoolNotEq", + "BoolLessThan", + "BoolLessThanEq", + "BoolGreaterThan", + "BoolGreaterThanEq", + "AtomicList", + "Extract", + "Beam", + "Pulse", + ] + + +## Statements + +::: oqd_core.interface.atomic.statement + options: + heading_level: 3 + members: [ + "Declaration", + "ParallelProtocol", + "IfElse", + "While", + "Break", + "Continue", + ] + + +## Species + +::: oqd_core.interface.atomic.species + options: + heading_level: 3 + members: [ + "Level", + "Transition", + "Ion", + "IonBuilder", + "Yb171IIBuilder", + "Ba133IIBuilder", + "ZeemanShift", + ] diff --git a/docs/reference/math_interface.md b/docs/reference/math_interface.md index a625ddc7..e69de29b 100644 --- a/docs/reference/math_interface.md +++ b/docs/reference/math_interface.md @@ -1 +0,0 @@ -::: oqd_core.interface.math diff --git a/mkdocs.yaml b/mkdocs.yaml index 96c27862..22ee5322 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -22,20 +22,23 @@ nav: - Installation: get-started/installation.md - Acknowledgement: get-started/acknowledgement.md - - Explanation: - - Interfaces: - - Analog: explanation/analog_interface.md - - Atomic: explanation/atomic_interface.md - - Math: explanation/math_interface.md - - - Compilers: - - Canonicalization: explanation/canonicalization.md + - Interfaces: + - Analog: interfaces/analog_interface.md + - Atomic: interfaces/atomic_interface.md + - Canonicalization: interfaces/canonicalization.md + + - Grammar: + - Analog: grammar/analog_grammar.md + - Atomic: grammar/atomic_grammar.md + + - Frontend: + - Analog: frontend/analog_frontend.md + - Atomic: frontend/atomic_frontend.md - API Reference: - Interface: - Analog: reference/analog_interface.md - Atomic: reference/atomic_interface.md - - Math: reference/math_interface.md - Compiler: - Math: reference/math_compiler.md @@ -65,7 +68,6 @@ theme: icon: material/weather-night name: Switch to light mode - features: - search.suggest - search.highlight @@ -140,7 +142,7 @@ markdown_extensions: - mdx_truly_sane_lists: nested_indent: 2 - truly_sane: True + truly_sane: true extra_javascript: - javascripts/mathjax.js @@ -151,4 +153,4 @@ extra_css: - stylesheets/headers.css - stylesheets/admonitions.css - stylesheets/brand.css - - stylesheets/logo.css + - stylesheets/logo.css \ No newline at end of file