Skip to main content

solvephase

CI PyPI Python Docs License: MIT

Documentation: jacotay7.github.io/solvephase

Fast, GPU-optional phase retrieval for adaptive optics, optical metrology and coherent imaging.

A race between every solvephase focal-plane method on the same aberrated VLT-like wavefront (Gerchberg-Saxton/Misell, modal and zonal maximum likelihood, retrieve(), extended-scene phase diversity, LIFT and Fast & Furious) on one clock, with a live error-versus-time chart and a gallery of CDI, coded-diffraction and TIE reconstructions.

solvephase recovers phase from intensity. It covers focal-plane wavefront sensing (Gerchberg–Saxton/Misell, maximum-likelihood modal and zonal retrieval, phase diversity with unknown extended objects, LIFT, Fast & Furious), coherent diffraction imaging (ER, HIO, DM, RAAR, RRR, ASR, HPR, OSS, shrinkwrap), generic measurement models (Wirtinger, truncated, amplitude and reweighted flows) and the transport-of-intensity equation, all behind one API. It runs on NumPy by default and on CUDA (CuPy) with one argument.

Install

pip install solvephase                 # CPU
pip install "solvephase[cuda12]"       # + CuPy for CUDA 12.x
pip install "solvephase[cuda13]"       # + CuPy for CUDA 13.x
pip install "solvephase[interop]"      # + pyturb atmospheres and getframes detectors

Quickstart

import solvephase as sp

pupil = sp.Pupil.vlt(128)  # 8 m, obscured, four vanes
model = sp.FocalPlaneModel(
    pupil, 1.65e-6, 64, sampling=2.0, diversity=sp.zernike_diversity(pupil, 4, [0.0, 0.4e-6])
)
truth = sp.random_aberration(pupil, 100e-9, n_modes=40, start=4, seed=1)
images = sp.simulate_images(model, truth, photons=1e6, background=10, read_noise=3, seed=2)

result = sp.retrieve(
    images, pupil, 1.65e-6, sampling=2.0, diversity=[0.0, 0.4e-6], read_noise=3.0, device="auto"
)
print(result.summary())  # converged in a handful of LM steps
result.opd, result.coefficients  # wavefront [m], Zernike [m RMS]

retrieve is robust by default. It explores with Levenberg–Marquardt on the amplitude metric from a flat start and from Gerchberg–Saxton, keeps the better fit, and polishes with the Poisson likelihood. For full control, use FocalPlaneProblem and solve (choose the basis, likelihood, nuisance parameters and optimizer). The other families are one call each:

sp.phase_diversity(model, images_of_extended_scene)  # unknown object
sp.LIFT(pupil, wavelength, 32, sampling=2.0).estimate(img)  # one astigmatic image
sp.FastAndFurious(pupil, wavelength, 64, sampling=2.0).step(img, dm_change)
sp.cdi(magnitudes, support, schedule="hio:500,er:100", starts=16, device="gpu")
sp.tie(stack, [-dz, 0, dz], pitch=pitch, wavelength=wavelength)

See Choosing an algorithm for a side-by-side comparison: images needed, requirements, measured speed, accuracy and capture range of every method.

Highlights

  • Exact derivatives everywhere. Every propagator (FFT, matrix Fourier transform, angular spectrum, coded diffraction) has an exact adjoint. Gradients and Gauss–Newton Jacobians are analytic, with no autodiff tape. Levenberg–Marquardt typically converges in 5–10 iterations.
  • Statistically efficient. Poisson + read-noise likelihoods, fitted flux, background and registration, masks for bad and saturated pixels. The estimator reaches the Cramér–Rao bound in the validation suite.
  • Physically complete. Broadband light, any sampling (including undersampled detectors), pixel integration, segmented apertures, KL priors, and DM influence-function bases.
  • Fast on CPU and GPU. Batched FFTs, matrix Fourier transforms on BLAS, batched multi-start CDI, and device-resident optimizers. Single precision reaches the same noise floor as double.
  • Validated. It matches HCIPy to machine precision and the analytic Airy normalization, and the validation suite checks its Cramér–Rao efficiency and capture range on every CI run.
  • Part of an AO toolchain. Modal bases come from aobasis, realistic aberrations from pyturb, and detector frames from getframes.

Benchmarks

See the benchmarks page and the versioned artifacts in benchmarks/artifacts.

Same problem, same data, on an Intel i7-10700 and an entry-level NVIDIA Quadro P620 (artifacts):

Task Baseline solvephase CPU solvephase GPU
Focal-plane retrieval, 128², 36 modes, 2 images (time to solution) HCIPy + SciPy L-BFGS-B: 8.5 s; least_squares: 5.3 s 0.46 s 0.14 s
Misell/GS, 128², iterations/s textbook NumPy: 156 268 1,493
CDI HIO, 256², iterations/s textbook NumPy: 252 794 2,957 (3,492 per start with 16 batched starts)
Broadband (5 λ) gradient, 256² — 67 ms 9 ms
TIE, 2048², 3 planes — 253 ms 33 ms

On the focal-plane problem every method reaches 0.12–0.19 nm RMS; solvephase gets there 11–18x faster on the CPU and 38–61x faster on the GPU.

Validation

python validation/validate.py checks solvephase against theory and an independent code and writes a report; see the validation page.

Development

pip install -e ".[dev,docs,interop,validation]"
python -m pytest -q                       # fast suite
python -m pytest -q --run-slow --run-gpu  # everything

See CONTRIBUTING.md and AGENTS.md.

License

MIT; see LICENSE.

Metadata

Release files for solvephase 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for solvephase 0.1.0
File Size Uploaded
solvephase-0.1.0.tar.gz 1.2 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for solvephase 0.1.0
File Interpreter ABI Platform
solvephase-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / solvephase-0.1.0.tar.gz

Download URL solvephase-0.1.0.tar.gz
Size 1.2 MB
Tags Source
SHA-256 checksum
How to use checksums
b3c77f1017aaa63e703f436e8ba863abae4ad39bad38d0c12254b35925192352
BLAKE2b-256 checksum
How to use checksums
d9406d1a8a7fe482bd2deb4d7b883f066c19794b25782ff4874a4b7ad8511773
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / solvephase-0.1.0-py3-none-any.whl

Download URL solvephase-0.1.0-py3-none-any.whl
Size 109.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
64f35fa38e45479a5baefe78bd045913844eeffc47485fd5aae1ad45214d334b
BLAKE2b-256 checksum
How to use checksums
7a00fcd49a4837a16fd9613f6e31cce0c9145d70c6acb45f1f91edf75826565d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page