Skip to content

Repository files navigation

ShadowSim.py

Test and coverage codecov

Overview

ShadowSim.py is an open-source Python library with two main purposes:

  1. Shadow Hamiltonian research: support analysis and further research on shadow Hamiltonian simulation.
  2. Algorithm comparison: make it easy to compare quantum simulation algorithms for open and closed systems.

Installation

Development installation

Install uv, then fork and clone the repository:

git clone https://github.com/<your-github-username>/ShadowSim.py.git
cd ShadowSim.py

Sync the project (creates .venv and installs runtime plus test tools from uv.lock):

uv sync

Install directly from GitHub

python -m pip install git+https://github.com/simsaidan/ShadowSim.py.git

The package can then be imported as shadowsim.

Tests and coverage

uv sync
uv run pytest --cov=shadowsim --cov-config=.coveragerc --cov-report=term-missing

Pushes to main run the same in GitHub Actions and upload coverage to Codecov (enable the Codecov GitHub app for this repo the first time so uploads succeed).

Linting

Install the lint tools, then run Ruff check and format (CI runs the same checks):

uv sync --group lint
uv run --group lint ruff check .
uv run --group lint ruff format .
# CI equivalent of the format gate:
uv run --group lint ruff format --check .

Usage

Public objects are imported from their domain subpackages:

from shadowsim.core import Hamiltonian, Operator, State
from shadowsim.shadow import ShadowHamiltonian
from shadowsim.simulators import QutipSimulator

The following simulators are supported by the package:

Name Type Can handle open systems
Qutip simulator classical true
Split JMatrix quantum-inspired true
Trotterization (coming soon)
Wave matrix Lindbladization (coming soon)
Pauli propagation (coming soon)

Examples

Example 1: Exploring a simple shadow simulation example

The complete example is in examples/simple_shadow.py and can be run after uv sync:

uv run python examples/simple_shadow.py

Example 2: Comparing a quantum algorithm against a classical solver

Imagine a scenario in which you want to compare the results of a new quantum simulation algorithm against a source of truth like QuTiP.

We first define some constants used in our system:

import numpy as np

from shadowsim.benchmarking import Benchmark
from shadowsim.core import (
    Hamiltonian,
    LocalHamiltonian,
    LocalOperator,
    Operator,
    State,
)
from shadowsim.simulators import (
    QutipSimulator,
    SplitJMatrixSimulator,
    cavity_population,
    population_one,
)
from shadowsim.utils import (
    I,
    one_state_two_qubits,
    three_state_two_qubits,
    tensor,
    two_state_two_qubits,
    zero_state_two_qubits,
)

# Define system parameters
omega_c = 245000
omega_e = 245000
kappa = np.sqrt(24.5)
gamma = np.sqrt(0.4)
g = 100

a = (
    np.outer(zero_state_two_qubits, one_state_two_qubits)
    + np.sqrt(2) * np.outer(one_state_two_qubits, two_state_two_qubits)
    + np.sqrt(3) * np.outer(two_state_two_qubits, three_state_two_qubits)
)

zero = np.array([1, 0], dtype=np.complex128)
one = np.array([0, 1], dtype=np.complex128)
sigma = np.outer(zero, one)

Now that the system constants are built, let's define our operators. Since this is an open-system simulation we have both Hamiltonians and Lindblad operators.

H1 = omega_c * a.conjugate().T @ a
H2 = omega_e * np.outer(one, one)
H3 = g * (np.kron(a, sigma.conjugate().T) + np.kron(a.conjugate().T, sigma))

local_hamiltonians = [
    LocalHamiltonian(H1, [0, 1]),
    LocalHamiltonian(H2, [2]),
    LocalHamiltonian(H3, [0, 1, 2]),
]
full_hamiltonians = [
    Hamiltonian(tensor([H1, I])),
    Hamiltonian(tensor([I, I, H2])),
    Hamiltonian(H3),
]

# Define Lindblad operators
L1_full = Operator(kappa * np.kron(a, I))
L2_full = Operator(gamma * (tensor([I, I, sigma])))
L1_local = LocalOperator(kappa * a, [0, 1])
L2_local = LocalOperator(gamma * sigma, [2])

# Define initial state
psi_0 = State(tensor([two_state_two_qubits, zero]), 3)

Next, we create two simulators, one for the new algorithm and one for the source of truth.

# Qutip simulator
qutip_simulator = QutipSimulator(
    full_hamiltonians,
    [L1_full, L2_full],
    psi_0,
    [
        Operator(tensor([a.conjugate().T @ a, I])),
        Operator(tensor([I, I, sigma.conjugate().T @ sigma])),
    ],
    3,
    0.25,
    301,
)
# Split JMatrix simulator
splitjmatrix_simulator = SplitJMatrixSimulator(
    local_hamiltonians,
    [L1_local, L2_local],
    psi_0,
    3,
    0.25,
    301,
    40,
    measurement_groups=[[1, 2], 3],
    reducers=[cavity_population, population_one],
)

To easily compare results, we initialize a benchmark with a reference simulator and one or more challengers. All simulators must share the same time grid. We run the benchmark, which runs the underlying simulations. Numeric L∞ / L2 error metrics vs the reference are available via error_metrics (and can be exported with save_error_metrics). We can also visualize the result by calling save_result_plot, which saves a plot per simulator and an absolute-difference plot vs the reference for each challenger.

benchmark = Benchmark(qutip_simulator, splitjmatrix_simulator)
benchmark.run()
print(benchmark.error_metrics())
metrics_path = benchmark.save_error_metrics()
paths = benchmark.save_result_plot(labels=["cavity population", "emitter population"])
for path in [metrics_path, *paths]:
    print(f"Saved: {path}")

Output

QuTiP (reference):

QuTiP expectations

Split JMatrix:

Split JMatrix expectations

Absolute difference between the two:

Absolute difference between the two simulators

Documentation

Contributing

Contributions are welcome and appreciated.

  1. Fork the repository and clone your fork (see the Installation section).
  2. Create a feature branch:
git checkout -b feature/your-change
  1. Make your changes and keep commits focused.
  2. Run tests and Ruff locally (uv run pytest and the linting commands above).
  3. Open a pull request with a clear description of what changed and why.

For larger changes, please open an issue first to discuss scope and design.

License

This project is licensed under the MIT License. See LICENSE for details.

Citing

References

  • arXiv Somma, R. D., King, R., Kothari, R., O'Brien, T., and Babbush, R. Shadow Hamiltonian Simulation. PDF
  • arXiv Sims, A. N., Patel, D., Philip, A., Rubin, A. H., Bandyopadhyay, R., Radulaski, M., and Wilde, M. M. Digital Quantum Simulations of the Non-Resonant Open Tavis-Cummings Model. PDF

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages