Metadata-Version: 2.4
Name: envelopes-qc
Version: 0.1.5
Summary: Envelopes implemented by C++ and Python.
Author-email: Shibo Xu <sbxu@zju.edu.cn>
License: MIT
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.19.3
Requires-Dist: scipy>=1.5.3
Dynamic: license-file

# envelopes-qc

High performance tools for building and decoding envelopes used in superconducting qubit experiments.

The core is a C++ extension (pybind11) with a matching pure-Python implementation:

- `envelopes.evc` — C++ accelerated implementation
- `envelopes.evp` — pure-Python (numpy/scipy) implementation, used for cross-validation

Both expose the same API and agree to float32 precision (cross-checked by the test suite).

## Requirements

- Python >= 3.9
- A C++17 compiler: MSVC (Visual Studio 2019+) on Windows, or gcc/clang on Linux
- Runtime: `numpy`, `scipy` (installed automatically)

The [libcerf](https://jugit.fz-juelich.de/mlz/libcerf) sources (v3.1, MIT licence) are vendored in `src/libcerf/` and compiled directly into the extension, so **no system packages are required** on Windows or Linux.

## Build

Build a wheel:

```bash
python -m build -w
```

Or build from source:

1. Clone the repository to your machine.
2. Install the package locally with one of the following commands:

```bash
# Development build (compile in place)
python setup.py build_ext --inplace
```

```bash
# Install into the active Python environment
pip install .
```

## Tests

```bash
python -m pytest tests/
```

- `tests/test_wave_data.py` — cross-checks every envelope class between the C++ and pure-Python implementations
- `tests/test_vendored_cerf.py` — verifies the vendored libcerf complex error function against independent references

## Usage

```python
from envelopes import evc
import numpy as np

# Create a GaussianDRAG envelope
center = 15
width = 10
pi_pulse = evc.GaussianDRAG(
    t0=center, w=width, amp=1.0, coef=0.5, df=0.1, phase=0.0
)

# Schedule multiple pulses
amp = np.array([1, 0.3, 0.7, 0.8])
dt = np.array([0, 50, 100, 200])
xy = evc.align(pi_pulse, dt, amp)  # align the envelope to the given dt and amplitude

# The following code has equivalent effect but is less efficient:
# xy = 0
# for _dt, _amp in zip(dt, amp):
#     xy += (pi_pulse >> _dt) * _amp

# Decode the envelope
resolution = 0.5
wc = evc.WaveCache(resolution)
# t, wave = evc.decode_envelope(xy, wc)  # default start and end from the envelope
t_start, wave = evc.decode_envelope(xy, wc, start=-50, end=250)
# wave is a zero-copy numpy ndarray over a freshly-allocated buffer,
# so it is safe to modify in place without affecting the WaveCache
t_list = np.arange(t_start, t_start + len(wave) * resolution, resolution)

import matplotlib.pyplot as plt

plt.figure()
plt.plot(t_list, wave.real, '.-', label='real')
plt.plot(t_list, wave.imag, '.-', label='imag')
plt.legend()
plt.xlabel('time')
plt.ylabel('amplitude')
plt.tight_layout()
plt.show()
```

## Project Structure

```
envelopes-qc/
├── envelopes/          # Python package
│   ├── envelopes_cpp   # C++ extension (.pyd on Windows, .so on Linux, built)
│   ├── envelopes_py.py # pure-Python implementation
│   └── envelopes_cpp.pyi
├── src/                # C++ sources of the extension
│   ├── bind.cpp        # pybind11 bindings
│   ├── envelopes.cpp   # envelope implementations
│   ├── envelopes.h
│   ├── sha256.h
│   └── libcerf/        # vendored libcerf v3.1 (MIT, see LICENSE inside)
├── tests/              # pytest suite + notebooks
├── docs/               # documentation
├── pyproject.toml
└── setup.py
```

## Supported Envelopes

See [tests/supported_envelopes.ipynb](./tests/supported_envelopes.ipynb) and the detailed envelope reference in [docs/envelope_reference.md](./docs/envelope_reference.md).

## Speed Test

See [tests/speed_test.ipynb](./tests/speed_test.ipynb).

## Documentation

Detailed usage documentation is available in the [docs/](./docs/) folder. Start from [docs/index.md](./docs/index.md):

- [docs/index.md](./docs/index.md) — documentation entry point
- [docs/quickstart.md](./docs/quickstart.md) — quick start guide
- [docs/concepts.md](./docs/concepts.md) — core concepts (WaveCache, operators, serialization)
- [docs/envelope_reference.md](./docs/envelope_reference.md) — parameter reference for every envelope class
- [docs/api_reference.md](./docs/api_reference.md) — module-level functions and operators
- [docs/examples.md](./docs/examples.md) — complete usage examples

## License

MIT License — see [LICENSE](./LICENSE). The vendored libcerf in `src/libcerf/` is also MIT licensed (see [src/libcerf/LICENSE](./src/libcerf/LICENSE)).
