-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
23 changed files
with
584 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# The `constructors` module | ||
|
||
The `constructors` module holds a collection of convenience functions for expression type constructions and quantum operations (_e.g._ unitary and Hermitian operators, projectors) as well as trainable and non-trainable parameters as symbols. | ||
|
||
|
||
::: qadence2_expressions.core.constructors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# The `environment` module | ||
|
||
The `environment` module defines an `Environment` type that plays a similar role as a context (or typing environment) for type checking systems. Here, it is a record of information for the qubit register and compilation directives. | ||
|
||
|
||
::: qadence2_expressions.core.environment |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# The `expression` module | ||
|
||
The `expression` module defines an `Expression` type as a symbolic representation for mathematical expressions together with arithmetic rules. It is syntactically constructed using [S-Expressions](https://en.wikipedia.org/wiki/S-expression) in prefix notation where the ordered parameters are: | ||
|
||
- A tag as a Python `Enum`: a token identifier for variables, functions or operations. | ||
- Arguments: a set of arguments to define or be passed to the expression. | ||
- Attributes: keyword arguments for symbolic evaluation and compilation directives. | ||
|
||
The `Expression` type defines constructors for four identifiers and operations variants: | ||
|
||
- `VALUE`: A value type to hold numerical `complex`, `float` or `int` primitive types. | ||
- `SYMBOL`: A symbol type for names definition. | ||
- `FN`: A variadic function type defined as a symbolic name and arguments. | ||
- `QUANTUM_OP`: A quantum operator type defined as an expression, a support of qubit resources and a collection of property attributes. | ||
- `ADD`: A variadic addition type as the sum of arguments. | ||
- `MUL`: A variadic multiplication type as the product of arguments. | ||
- `KRON`: A variadic multiplication type as the product of arguments with commutative rules. | ||
- `POW`: A power type as the exponentiation of a base and power arguments. | ||
|
||
|
||
::: qadence2_expressions.core.expression |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
## The `support` module | ||
|
||
The `support` module defines a `Support` type to handle qubit support for single, multi and controlled quantum operations. | ||
|
||
|
||
::: qadence2_expressions.core.support |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# Expression system | ||
|
||
Qadence 2 Expression system is designed to create expressive, self-contained and abstract symbolic expressions to represent quantum programs in the digital-analog paradigm. These expressions can be transpiled later with concretized and specific data types, such as `numpy`, `pytorch` and `jax` for execution on targeted backends. | ||
|
||
The Expression system defines syntactic rules to generate symbolic quantum expressions, that can contain parametric expressions for **parameters** (static, `FeatureParameter`) and **variables** (dynamic, `VariationalParameter`) to be used for training purposes. Expression composition can be seamlessly applied to quantum operators for digital, analog and digital-analog computations. It also supports arithmetic operations for both classical and quantum expressions as well as reduction, simplification and replacement methods. | ||
|
||
|
||
## Symbolic manipulation | ||
|
||
In these examples, basic arithmetic expressions on symbols (parameters) are evaluated to illustrate simplifications and reductions. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
from qadence2_expressions import * | ||
|
||
a = parameter('a') | ||
b = parameter('b') | ||
|
||
print(f"a + a \u2192 {a + a}") # markdown-exec: hide | ||
print(f"a - a \u2192 {a - a}") # markdown-exec: hide | ||
print(f"a / a \u2192 {a / a}") # markdown-exec: hide | ||
print(f"a + b \u2192 {a + b}") # markdown-exec: hide | ||
print(f"a / (2*b) \u2192 {a / (2*b)}") # markdown-exec: hide | ||
print(f"a ** 0 \u2192 {a ** 0}") # markdown-exec: hide | ||
print(f"a ** 1 \u2192 {a ** 1}") # markdown-exec: hide | ||
print(f"2 ** (a + b' \u2192 {2 ** (a + b)}") # markdown-exec: hide | ||
``` | ||
|
||
Products of sums are expanded | ||
|
||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
(a + b) * (a + b) | ||
|
||
print(f"\u2192 {(a + b) * (a + b)}") # markdown-exec: hide | ||
``` | ||
|
||
But exponentiations of sums are not as power simplifications take precedence. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
(a + b) * (a + b) ** 2 / (a + b) | ||
|
||
print(f"\u2192 {(a + b) * (a + b) ** 2 / (a + b)}\n") # markdown-exec: hide | ||
``` | ||
|
||
## Quantum operators | ||
|
||
Standard quantum operators are defined as Python `Callable` that accept a qubit support as argument. Please note that the support can either be a single `int` for single qubit operations or a tuple of qubit indices for operations that span across multiple qubits or nothing to create global operations that span across the whole register (denoted by the `*` wildcard). | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
X(2) * Y() * Z(1,2) | ||
|
||
print(f"\u2192 {X(2) * Y() * Z(1,2)}") # markdown-exec: hide | ||
``` | ||
|
||
(Multi-)Controlled operators need to be provided with non-overlapping tuples for control and target qubits. The notation convention is to display target indices first followed by control indices in increasing ordering. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
NOT(control=(1,), target=(2,)) * NOT(target=(1,3), control=(2,4)) | ||
|
||
print(f"\u2192 {NOT(control=(1,), target=(2,)) * NOT(target=(1,3), control=(2,4))}") # markdown-exec: hide | ||
``` | ||
|
||
Quantum operators can be parametrized and expressions expanded. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
X() * (cos(a) * X() + 1j * sin(a) * Y()) / 2 | ||
|
||
print(f"\u2192 {X() * (cos(a) * X() + 1j * sin(a) * Y()) / 2}") # markdown-exec: hide | ||
``` | ||
|
||
Global and local operators can be combined. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
X(1) * (cos(a) * X() + 1j * sin(a) * Y()) * Z(1) / 2 | ||
|
||
print(f"\u2192 {X(1) * (cos(a) * X() + 1j * sin(a) * Y()) * Z(1) / 2}") # markdown-exec: hide | ||
``` | ||
|
||
Custom operators can be created as functions or based on other operators. For instance, the `CNOT`: | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
CNOT = lambda ctrl, tgt: NOT(target=(tgt,), control=(ctrl,)) | ||
Y(4) * X(3) * Y(5,4) * CNOT(1,2) * Z(3) | ||
|
||
print(f"\u2192 {Y(4) * X(3) * Y(5,4) * CNOT(1,2) * Z(3)}") # markdown-exec: hide | ||
``` | ||
|
||
Or the number operator. Expansion rules still hold. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
N = lambda k: (1 - Z(k)) / 2 | ||
|
||
sum(a * X(i) - b * Z(i) + N(i) * N(i + 1) for i in range(1)) | ||
print(f"\u2192 {sum(a * X(i) - b * Z(i) + N(i) * N(i + 1) for i in range(1))}") # markdown-exec: hide | ||
``` | ||
|
||
Parametric operators need to get passed a parameter as first argument, then the qubit support. This ensures syntactic consistency across operators. Unitarity still holds. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
phi = variable("phi") | ||
|
||
RX(phi / 2)(1) * RX(phi / 2)(1).dag | ||
print(f"\u2192 {RX(phi / 2)(1) * RX(phi / 2)(1).dag}") # markdown-exec: hide | ||
``` | ||
|
||
Arithmetic operations still hold for operator parameters defined over the same support. | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
RX(phi / 2)(1) * RX(- phi / 2)(1) | ||
|
||
print(f"\u2192 {RX(phi / 2)(1) * RX(- phi / 2)(1)}") # markdown-exec: hide | ||
``` | ||
|
||
As opposed to: | ||
|
||
```python exec="on" source="material-block" result="json" session="expressions" | ||
RX(phi / 2)(1) * RX(phi / 2)(2).dag | ||
|
||
print(f"\u2192 {RX(phi / 2)(1) * RX(phi / 2)(2).dag}") # markdown-exec: hide | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Intermediate Representation compilation | ||
|
||
Qadence 2 expression package provides compilation functionality to target Qadence 2 Intermediate Representation (IR) defined [here](https://github.com/pasqal-io/qadence2-ir). Please note that the IR follows [SSA form](https://en.wikipedia.org/wiki/Static_single-assignment_form) for classical computations. | ||
|
||
|
||
In following is a pure digital program with local possibly parametrized gates compiled to the IR model. | ||
|
||
|
||
```python exec="on" source="material-block" result="json" session="compilation" | ||
from qadence2_expressions import * | ||
|
||
a = parameter('a') | ||
b = parameter('b') | ||
|
||
phi = variable("phi") | ||
|
||
expr = RX(a * phi / 2)(2) * Z(1) * RY(b * phi / 2)(0) | ||
|
||
reset_ir_options() | ||
ir = compile_to_model(expr) | ||
|
||
print(f"{ir}") # markdown-exec: hide | ||
``` | ||
|
||
Similar example with interleaved global gates. | ||
|
||
```python exec="on" source="material-block" result="json" session="compilation" | ||
expr = RX(a * phi / 2)(2) * CZ() * RY(b * phi / 2)(0) | ||
|
||
ir = compile_to_model(expr) | ||
|
||
print(str(ir)) # markdown-exec: hide | ||
``` | ||
|
||
Options can be set at any point to supplement the model to be recompiled. | ||
|
||
```python exec="on" source="material-block" result="json" session="compilation" | ||
set_qubits_positions([(-2, 1), (0, 0), (3, 1)]) | ||
set_grid_type("triangular") | ||
|
||
ir = compile_to_model(expr) | ||
|
||
print(str(ir)) # markdown-exec: hide | ||
``` | ||
|
||
Pure analog programs can be constructed using `NativeDrive` and `FreeEvolution` operations that leave their concrete definitions and implementations to the backend. They can accept arbitrary combinations of single valued or arrays of parameters. | ||
|
||
```python exec="on" source="material-block" result="json" session="compilation" | ||
set_qubits_positions([(-1,0), (-1, 1), (1, 0), (1, 1)]) | ||
set_grid_type("triangular") | ||
|
||
t = variable("t") | ||
omega = array_variable("omega", 4) | ||
detuning = array_variable("detuning", 3) | ||
phase = parameter("phase") | ||
|
||
expr = ( | ||
NativeDrive(t / 2, omega, detuning, phase)() | ||
* FreeEvolution(2.5)() | ||
* NativeDrive(t / 2, omega, -detuning, phase)() | ||
) | ||
|
||
ir = compile_to_model(expr) | ||
|
||
print(str(ir)) # markdown-exec: hide | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Useful functions | ||
|
||
Currently, there are two useful methods for querying and manipulating expressions, namely `collect_operators` and `replace`. In following are examples for each. | ||
|
||
|
||
```python exec="on" source="material-block" result="json" session="functions" | ||
from qadence2_expressions import * | ||
|
||
collected_ops = collect_operators(Z(1) + 2 * Z(1) * Z (2) - X(3)) | ||
|
||
print(collected_ops) # markdown-exec: hide | ||
``` | ||
|
||
|
||
```python exec="on" source="material-block" result="json" session="functions" | ||
replacement_rules = {Z(1): X(1)} | ||
|
||
replaced_ops = replace(Z(1) + 2 * Z(1) * Z (2) - X(3), replacement_rules) | ||
|
||
print(f"\u2192 {replaced_ops}") # markdown-exec: hide | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
:root { | ||
/* | ||
Proposal palette for Qadence | ||
*/ | ||
--marian-blue: #023E8A; | ||
--federal-blue: #03045E; | ||
--baby-powder: #FFFDFA; | ||
--azure-blue: #DFF0F6; | ||
|
||
--md-primary-fg-color: var(--federal-blue); | ||
--md-accent-fg-color: var(--marian-blue); | ||
} |
Oops, something went wrong.