Skip to content

Commit

Permalink
[Docs] Populate docs. (#34)
Browse files Browse the repository at this point in the history
Closes #28
  • Loading branch information
RolandMacDoland authored Nov 8, 2024
1 parent b4ffaf5 commit 7598263
Show file tree
Hide file tree
Showing 23 changed files with 584 additions and 76 deletions.
47 changes: 38 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,58 @@
# Qadence Expressions

Qadence Expressions consisting of symbolic expressions and blocks, i.e. quantum digital, analog, digital-analog and composite gates, together with their logic and engine.
!!! note
Qadence 2 Expressions is currently a *work in progress* and is under active development. Please be aware that the software is in an early stage, and frequent updates, including breaking changes, are to be expected. This means that:
* Features and functionalities may change without prior notice.
* The codebase is still evolving, and parts of the software may not function as intended.
* Documentation and user guides may be incomplete or subject to significant changes.

Qadence 2 Expressions consisting of symbolic expressions and blocks, i.e. quantum digital, analog, digital-analog and composite gates, together with their logic and engine.

## Installation

Installation guidelines
!!! note
It is advised to set up a python environment before installing the package, such as [venv](https://docs.python.org/3/library/venv.html#creating-virtual-environments), [hatch](https://hatch.pypa.io/latest/), [pyenv](https://github.com/pyenv/pyenv), [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html) or [poetry](https://python-poetry.org/). (Qadence 2 Expressions in development mode uses `hatch`).

To install the current version of Qadence 2 Expressions, there are a few options:

### 1. Installation from PYPI

On the terminal, type

```bash
pip install qadence2-expressions
```

### 2. Installation from Source

Clone this repository by typing on the terminal

```bash
git clone https://github.com/pasqal-io/qadence2-expressions.git
```

Go to `qadence2-expressions` folder and install it using [hatch](https://hatch.pypa.io/latest/)

```bash
hatch -v shell
```

Use hatch environment on your IDE or terminal to use `qadence2-expressions` package.

## Usage

Usage guidelines


## Documentation
Documentation guidelines


## Contribute
Documentation guidelines

Before making a contribution, please review our [code of conduct](docs/getting_started/CODE_OF_CONDUCT.md).
## Contributing

- **Submitting Issues:** To submit bug reports or feature requests, please use our [issue tracker](https://github.com/pasqal-io/wip-qadence2-expressions/issues).
- **Developing in qadence expressions:** To learn more about how to develop within `qadence-expressions`, please refer to [contributing guidelines](docs/getting_started/CONTRIBUTING.md).
Before making a contribution, please review our [code of conduct](getting_started/CODE_OF_CONDUCT.md).

- **Submitting Issues:** To submit bug reports or feature requests, please use our [issue tracker](https://github.com/pasqal-io/qadence2-expressions/issues).
- **Developing in qadence:** To learn more about how to develop within `qadence2-expressions`, please refer to [contributing guidelines](getting_started/CONTRIBUTING.md).

## License

Expand Down
6 changes: 6 additions & 0 deletions docs/api/constructors.md
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
6 changes: 6 additions & 0 deletions docs/api/environment.md
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
21 changes: 21 additions & 0 deletions docs/api/expressions.md
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
6 changes: 6 additions & 0 deletions docs/api/support.md
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
120 changes: 120 additions & 0 deletions docs/contents/expression_system.md
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
```
66 changes: 66 additions & 0 deletions docs/contents/ir_compilation.md
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
```
21 changes: 21 additions & 0 deletions docs/contents/useful_functions.md
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
```
12 changes: 12 additions & 0 deletions docs/extras/css/colors.css
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);
}
Loading

0 comments on commit 7598263

Please sign in to comment.