Skip to content

Commit a2ca0f9

Browse files
authored
v0.4.0
**Breaking Changes** - `overlapwithpaulisum()` now has an extra factor of `2^nqubits` to be in line with other `overlap` functions. `scalarproduct()` takes its place instead. - The Y Clifford gate definition had a missing minus sign. - Removal of some toy functions like `commutes()` between two symbols. - The low-level truncation functions are no longer exported **Further Changes** - Many docs clarifications or removals for functions exposed on the docs page - Addition of functions like `+` and `*` between `PauliSum` and `PauliString` - Automatic promotion of types for these operations - Automatic wrapping of coefficients into `PauliFreqTracker` when `max_sin` or `max_freq` are not `Inf`.
2 parents 7fb65ea + 81e6a52 commit a2ca0f9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+3605
-3231
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Generates the package documentation via Documenter.jl,
2+
# and deploys it to Github Pages, as per the hosting guide
3+
# at https://documenter.juliadocs.org/stable/man/hosting/.
4+
# See /docs/make.jl for more information about generation.
5+
6+
name: Documentation
7+
8+
9+
# Regenerate doc (updating Github Pages site) whenever...
10+
on:
11+
push:
12+
13+
# 'dev' is updated (updates /dev/ subdomain). Note we cannot
14+
# simply add other branchces (like 'main') here because it must
15+
# correspond to 'devbranch' passed to deploydocs() in make.jl,
16+
# else the generated doc will not be published to gh-pages
17+
branches:
18+
- dev
19+
20+
# a new release tag is created. Only releases with semantic
21+
# versioning tags of the form 'vX.Y.Z' will be published to
22+
# gh-pages, updating subdomains /stable/ and /vX.Y.Z/. This
23+
# is further constrained by the 'versions' arg to deploydocs()
24+
tags: '*'
25+
26+
# a PR is opened to the below branches (updates /previews/PR# subdomain)
27+
pull_request:
28+
branches:
29+
- main
30+
- dev
31+
32+
# the workflow is manually triggered in the Github Actions tab, using
33+
# the dev branch (updates /dev/).
34+
workflow_dispatch:
35+
36+
37+
# prevent concurrent doc gen
38+
concurrency:
39+
group: doc
40+
cancel-in-progress: false
41+
42+
43+
# give both doc-gen and tidy jobs below necessary
44+
# access to read/write from the gh-pages branch
45+
permissions:
46+
actions: write
47+
contents: write
48+
pull-requests: read
49+
statuses: write
50+
51+
52+
jobs:
53+
54+
# regenerate the doxygen using Documenter.jl
55+
# and re-deploy it to the gh-pages branch
56+
build-doc:
57+
name: Build and deploy documentation
58+
runs-on: ubuntu-latest
59+
60+
steps:
61+
62+
# generate doc using files from the triggering branch
63+
- name: Obtain PP
64+
uses: actions/checkout@v4
65+
66+
- name: Setup Julia
67+
uses: julia-actions/setup-julia@v2
68+
with:
69+
version: '1'
70+
71+
# using cache speeds up workflow
72+
- name: Setup Julia cache
73+
uses: julia-actions/cache@v2
74+
75+
- name: Install dependencies
76+
shell: julia --color=yes --project=docs {0}
77+
run: |
78+
using Pkg
79+
Pkg.develop(PackageSpec(path=pwd()))
80+
Pkg.instantiate()
81+
82+
# symlink repo README to 'docs/src/index.md'
83+
# as needed by subsequent doc generation
84+
- name: Setup symlink
85+
run: ln -s ../../README.md index.md
86+
working-directory: docs/src
87+
88+
- name: Build and deploy
89+
run: julia --color=yes --project=docs docs/make.jl
90+
env:
91+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
92+
93+
# delete superfluous files remaining on the
94+
# gh-pages branch to speed up user cloning
95+
tidy-doc:
96+
name: Tidy documentation
97+
runs-on: ubuntu-latest
98+
99+
# perform this after doc regen
100+
needs: build-doc
101+
102+
# only cleanup when main is pushed, preserving all the
103+
# working clones of the doc (like from PRs) in the meantime
104+
if: github.event_name == 'push' && github.ref_name == 'main'
105+
106+
steps:
107+
108+
- name: Checkout gh-pages branch
109+
uses: actions/checkout@v4
110+
with:
111+
ref: gh-pages
112+
113+
# make a cleaning commit as "Documenter.jl" bot
114+
- name: Delete preview and history + push changes
115+
run: |
116+
if [ -d "${preview_dir}" ]; then
117+
git config user.name "Documenter.jl"
118+
git config user.email "documenter@juliadocs.github.io"
119+
git rm -rf "${preview_dir}"
120+
git commit -m "delete preview"
121+
git branch gh-pages-new "$(echo "delete history" | git commit-tree "HEAD^{tree}")"
122+
git push --force origin gh-pages-new:gh-pages
123+
fi
124+
env:
125+
preview_dir: previews/PR${{ github.event.number }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
# Files generated by invoking Julia with --track-allocation
66
*.jl.mem
77

8+
# ipython notebook checkpoints
9+
.ipynb_checkpoints
10+
811
# System-specific files and directories generated by the BinaryProvider and BinDeps packages
912
# They contain absolute paths specific to the host computer, and so should not be committed
1013
deps/deps.jl

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PauliPropagation"
22
uuid = "293282d5-3c99-4fb6-92d0-fd3280a19750"
33
authors = ["Manuel S. Rudolph"]
4-
version = "0.3.0"
4+
version = "0.4.0"
55

66
[deps]
77
BitIntegers = "c3b6d118-76ef-56ca-8cc7-ebb389d030a1"

README.md

Lines changed: 93 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1+
| **Documentation**|
2+
|:----------------:|
3+
|[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://msrudolph.github.io/PauliPropagation.jl)[![](https://img.shields.io/badge/docs-dev-green.svg)](https://msrudolph.github.io/PauliPropagation.jl/dev)|
4+
15
# PauliPropagation.jl
2-
`PauliPropagation.jl` is a Julia package for Pauli propagation simulation of quantum circuits and quantum systems.
6+
`PauliPropagation.jl` is a Julia package for simulating Pauli propagation in quantum circuits and systems. It focuses on simulating the evolution of observables expressed in the Pauli basis under the action of unitary gates and non-unitary channels in a quantum circuit.
37

4-
The package simulates the evolution of objects expressed in the Pauli basis under noiseless and noisy quantum circuits. Commonly, this is used for the Heisenberg picture evolution of an observable. For example, if $`\hat{O}`$ is an observable that is preferably sparse in Pauli basis and $`\mathcal{E}`$ is a quantum circuit, we simulate $`\mathcal{E}^\dagger(\hat{O})`$ instead of most quantum simulation packages simulating the Schrödinger evolution $`\mathcal{E}(\rho)`$ of states $`\rho`$. For the case of unitary quantum circuits $`U`$, the evolved observable $`\mathcal{E}^\dagger(\hat{O})`$ is usually written like $`U^\dagger \hat{O} U`$.
8+
Unlike traditional simulators which simulate a circuit $\mathcal{E}$ evolving the state $\rho$ in the Schrödinger picture, Pauli propagation often adopts the Heisenberg picture, evolving an observable $O$ under $\mathcal{E}^\dagger$. This can be particularly efficient when the observables remain sparse or structured under evolution, and is useful for estimating expectation values such as $\text{Tr}\left[\rho \mathcal{E}^{\dagger}(O)\right]$, studying operator dynamics, and computing correlation functions.
59

6-
Some opt-in truncations or approximations are particularly suited for estimating expectation values $`Tr[\rho \mathcal{E}^\dagger(\hat{O})]`$ of evolved observables with quantum states.
10+
Pauli propagation is related to the so-called (extended) stabilizer simulation, but is fundamentally different from, for example, tensor networks. It offers a distinct approach that can handle different regimes of quantum dynamics.
711

12+
Implemented in Julia, `PauliPropagation.jl` combines high-performance computation (using features such as multiple dispatch) with an accessible and high-level interface.
813

914
## Installation
1015

16+
> Note the current package requires `Julia 1.10+`.
17+
1118
The `PauliPropagation.jl` package is registered and can be installed into your environment in the following way:
1219
```julia
1320
using Pkg
@@ -24,78 +31,126 @@ Pkg.add(url="https://github.com/MSRudolph/PauliPropagation.jl.git", rev="branchn
2431
where you can use the keyword `rev="branchname"` to install development versions of the package.
2532
We don't recommend using branches other than `main` or `dev`.
2633

27-
### Clone repository and install locally
34+
### Clone the repository and install locally
2835
Navigate to a local directory where you want to clone this repository into and run the following in a terminal
2936
```bash
3037
git clone git@github.com:MSRudolph/PauliPropagation.jl.git
3138
```
32-
Inside this cloned repository you can now freely import `PauliPropagation` or install it into your environment.\
39+
Inside this cloned repository, you can now freely import `PauliPropagation` or install it into your environment.\
3340
Alternatively, you can push the relative path to the cloned repository to the Julia package load path called `LOAD_PATH` via
3441
```julia
3542
rel_path = "your/relative/path/PauliPropagation"
3643
push!(LOAD_PATH,rel_path);
3744
```
3845
This may require that you have no global installation of `PauliPropagation` in your enviroment.
3946

40-
## Examples
47+
### A note on installing Julia
48+
It is recommended to install julia using `juliaup` with instructions from [here](https://github.com/JuliaLang/juliaup). Then, Julia's _long-term support_ version (currently a `1.10` version) can be installed via
49+
50+
```juliaup add lts```
51+
52+
To get started running Jupyter notebooks, start a Julia session and install the `IJulia` package.
53+
54+
If you are working on several projects with potentially conflicting packages, it is recommended to work with within local environments or projects.
4155

42-
You can find example notebooks in the `examples` folder.
56+
For more details, we refer to this useful [guide](https://modernjuliaworkflows.org/writing/).
57+
58+
## Quick Start
59+
60+
You can find detailed example notebooks in the `examples` folder. We provide a brief example of how to use `PauliPropagation.jl`.
61+
62+
Consider simulating the dynamics of an operator $O=Z_{16}$ under the evolution of a unitary channel $\mathcal{E}(\cdot) = U^\dagger \cdot U$ in a $n=32$ qubits system.
4363

44-
Here is a tiny working example where we approximately simulate the expectation value of a quantum circuit.
4564
```julia
4665
using PauliPropagation
4766

48-
## number of qubits
4967
nqubits = 32
5068

51-
## define the observable
52-
# here I...IZI...I
53-
observable = PauliString(nqubits, :Z, 16)
69+
observable = PauliString(nqubits, :Z, 16) # I...IZI...I
70+
```
71+
72+
Our goal is to compute
5473

55-
## define the circuit
56-
# the number of layers
57-
nlayers = 32
74+
```math
75+
\text{Tr}[U^\dagger O U \rho].
76+
```
77+
78+
A simple unitary $U$ is the brickwork circuit, composed of two qubit gates alternating neighbouring sites. We define the circuit connectivity by
5879

59-
# bricklayertopology is also the default if you don't provide any
80+
```julia
6081
topology = bricklayertopology(nqubits; periodic=true)
82+
```
83+
84+
where `periodic` specifies the boundary condition of the gates. The library has built-in circuits with e.g. a circuit containing alternating RX and RZZ Pauli gates on the topology. This can be defined by Trotterization of a transverse field Ising Hamiltonian with $l$ steps
85+
86+
```math
87+
U = \prod_{a=1}^{l} \prod_{j=1}^n e^{-i dt X_j} e^{-i dt Z_j Z_{j+1}}.
88+
```
89+
90+
```julia
91+
nlayers = 32 # l as above
6192

62-
# a circuit containing RX and RZZ Pauli gates on the topology
63-
# derived from the Trotterization of a transverse field Ising Hamiltonian
6493
circuit = tfitrottercircuit(nqubits, nlayers; topology=topology)
94+
```
6595

66-
# time step
67-
dt = 0.1
68-
# count the number of parameters
69-
nparams = countparameters(circuit)
70-
# define the parameter vector
71-
parameters = ones(nparams) * dt
96+
In our simulations, we can choose the circuit parameter $dt$
7297

98+
```julia
99+
dt = 0.1 # time step
100+
101+
parameters = ones(countparameters(circuit)) * dt # all parameters
102+
```
103+
**Important:** The circuit and parameters are defined in the order that they would act in the Schrödinger picture. Within our `propagate()` function, the order will be _reversed_ to act on the observable.
104+
105+
During the propagation via `propagate()`, we employ truncation strategies such as coefficient or weight truncations, these options can be specified as keywords.
106+
107+
```julia
73108
## the truncations
74-
# maximum Pauli weight
75-
max_weight = 6
76-
# minimal coefficient magnitude
77-
min_abs_coeff = 1e-4
109+
max_weight = 6 # maximum Pauli weight
110+
111+
min_abs_coeff = 1e-4 # minimal coefficient magnitude
78112

79-
## propagate through the circuit with our best (and currently only propagation method)
80-
pauli_sum = propagate(circuit, observable, parameters; max_weight=max_weight, min_abs_coeff=min_abs_coeff)
113+
## propagate through the circuit
114+
pauli_sum = propagate(circuit, observable, parameters; max_weight, min_abs_coeff)
115+
```
116+
The output `pauli_sum` gives us an approximation of propagated Pauli strings
117+
118+
```math
119+
U^\dagger O U \approx \sum_{\alpha} c_{\alpha} P_{\alpha}
120+
```
81121

122+
Finally we can compute expectation values with an initial state such as $\rho = (|0 \rangle \langle 0 |)^{\otimes n}$
123+
```julia
82124
## overlap with the initial state
83125
overlapwithzero(pauli_sum)
84126
# yields 0.154596728241...
85127
```
86128

129+
This computation is efficient because the initial state can be written in terms of only $\mathbb{I}$ and $Z$ strings
130+
131+
```math
132+
\rho = \left(\frac{\mathbb{I} + Z}{2}\right)^{\otimes n}
133+
```
134+
135+
Therefore, the trace is equivalent to the sum over the coefficients of Pauli strings containing only `I` and `Z` Paulis,
136+
137+
```math
138+
\mathrm{Tr}[U^\dagger O U \rho] \approx \sum_{\alpha \in \{\mathbb{I}, Z\}\, \text{strings}} c_{\alpha}.
139+
```
140+
87141
## Important Notes and Caveats
88-
All of the following points can be addressed by you writing the necessary missing code due to the nice extensibility of Julia.
89-
- The package is tested for Julia `1.10` and `1.11`.
90-
- The default is the Heisenberg _backpropagation_. Schrödinger propagation may soon be natively supported. At this moment, there are options to transpose `PauliRotation` gates by multiplying their angles with `-1` and `CliffordGate`s by using `transposecliffordmap()`.
91-
- We currently do not support the strong simulation of quantum states in non-exponential time (even for Stabilizer states). Pauli propagation could in principle be used as a backend for extended stabilizer simulation.
142+
- Circuits are specified in the _Schrödinger_ picture, as if operated upon states. Behind the scenes, `propagate()` will (by default) apply the _adjoint_ circuit upon the passed `PauliSum` which is treated as the observable operator.
143+
- Schrödinger propagation is planned but not yet supported _except_ through manually passing the _adjoint_ of the intended circuit to `propagate()`. This is often easy. For instance, with the circuit order reversed, angles in `PauliRotation` gates are negated, and `CliffordGate` are passed to `transposecliffordmap()`.
144+
- While Pauli propagation can, in principle, be used for _extended_ stabilizer simulation, we do not currently support sub-exponential strong simulation of stabilizer states.
92145
- Sampling quantum states is currently not supported.
93146
- Many underlying data structures and functions can be used for other purposes involving Pauli operators.
94147

148+
All of the above can be addressed by writing the additional missing code due to the nice extensibility of Julia.
149+
95150
## Upcoming Features
96151
This package is still work-in-progress. You will probably find certain features that you would like to have and that are currently missing.\
97152
Here are some features that we want to implement in the future. Feel free to contribute!
98-
- **A documentation website!**
153+
- **Multi-threading and improved scalability**. Currently, PauliPropagation.jl works uses a single CPU thread and may run your hardware out of memory. Future versions should be even faster and with options to trade-off computational runtime and memory requirements.
99154
- **Easier Schrödinger picture propagation**. Currently, the default is Heisenberg and there is no easy way to transpose the gates.
100155
- **A fast and flexible Surrogate version**. Currently, we provide a version of the Pauli propagation Surrogate that is _good_ and _works_, at least for Pauli gates and Clifford gates. Stay tuned for a whole lot more.
101156

@@ -110,12 +165,11 @@ Otherwise, feel free to reach out to the developers!
110165

111166
## Authors
112167

113-
The main developer of this package is Manuel S. Rudolph in the Quantum Information and Computation Laboratory of Prof. Zoë Holmes at EPFL, Switzerland.
168+
The main developer of this package is [Manuel S. Rudolph](https://github.com/MSRudolph) in the Quantum Information and Computation Laboratory of Prof. Zoë Holmes at EPFL, Switzerland.
114169
Contact Manuel via manuel.rudolph@epfl.ch.
115170

116-
This package is the derivative of ongoing collaborations with Armando Angrisani and [Tyson Jones](https://github.com/TysonRayJones) at EPFL, supervised by Prof. Zoë Holmes at EPFL.
117-
118-
Further contributors to this package include [Yanting Teng](https://github.com/teng10) and [Su Yeon Chang](https://github.com/sychang42).
171+
Further contributors to this package include [Yanting Teng](https://github.com/teng10), [Tyson Jones](https://github.com/TysonRayJones), and [Su Yeon Chang](https://github.com/sychang42).
172+
This package is the derivative of ongoing work at the Quantum Information and Computation lab at EPFL, supervised by Prof. Zoë Holmes.
119173

120174
For more specific code issues, bug fixes, etc. please open a [GitHub issue](https://github.com/MSRudolph/PauliPropagation.jl/issues).
121175

docs/Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[deps]
2+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
PauliPropagation = "293282d5-3c99-4fb6-92d0-fd3280a19750"
4+
5+
[compat]
6+
Documenter = "1.10"

0 commit comments

Comments
 (0)