All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.3.11 - 2026-11-01
Changed
- Result dictionaries report simulator, method and cluster_methods as SimulatorType and SimulationType members instead of bare integers, so print(result["simulator"]) shows SimulatorType.QCSim. Both enums are now integer enums, so the members still compare equal to the old values and result["method"] == 0 keeps working.
- The Python documentation moved from the Doxygen site to a new site at the documentation root, with a user guide, examples and API reference whose code examples run when the site is built. The C++ reference is now under /cpp/, and the old C++ and Python guide URLs redirect.
- macOS wheels need macOS 15 or later, up from 14, because GitHub retired its macOS 14 build machines. They remain Apple Silicon (arm64) only.
Fixed
- Docstrings in the Python bindings and maestro.sinter that contained text such as |0> or <psi|phi> no longer produce reStructuredText warnings and errors in the generated API reference.
0.3.10 - 2026-10-30
Added
- The QASM parser accepts qelib1.inc's rzz and rxx, expanding them into cx, rz, cx (between h gates for rxx), so the gates no longer need decomposing before they reach Maestro.
- maestro.sinter runs Stim's own noise. DEPOLARIZE1/2, X/Y/Z_ERROR and PAULI_CHANNEL_1/2 translate to the new QuantumCircuit.pauli_channel, and measurement flips such as M(p) to the new measure(..., readout_error=p), so a noisy Stim circuit such as SI1000 needs no NoiseModel. Pure-state and MPS backends draw one Pauli per noise realization; density-matrix and MPO backends apply the channel exactly. E and heralded noise still raise.
- MaestroCompiledSampler.sample_measurements(shots, seed=None) returns the raw measurement record.
- MaestroSinterSampler(noise_model=...) also accepts a picklable task -> NoiseModel callable, so one sampler serves a noise-strength sweep.
- QuantumCircuit.h/s/sdg(..., noiseless=True) exempts a basis change from a NoiseModel's gate noise.
Changed
- Breaking: set_coherent_depolarizing (and set_all_coherent_depolarizing, set_coherent_strength) is now isotropic: it rotates by ε = 2·arcsin(√p) about a body diagonal (±1, ±1, ±1)/√3, whose Pauli twirl is exactly DEPOLARIZE1(p). It was a Z rotation, so Z-basis logicals never saw it. set_coherent_dephasing keeps the old behaviour.
- Coherent setters replace only the component they name, so set_coherent_bit_flip followed by set_coherent_dephasing keeps both axes.
- Breaking: MaestroSinterSampler raises ValueError when no decoder resolves. Under sinter.collect, task.decoder is the custom_decoders key; the key "maestro" used to mean "undecoded" silently. Pass decoder="pymatching", or decoder="vacuous" for the undecoded rate.
- The basis changes maestro.sinter inserts for RX, RY, MX, MY, MRX and MRY are noiseless, so a NoiseModel adds gate noise only where Stim has gates. CLEAN_CIRCUIT_API_VERSION is now 2.
- A NoiseModel's readout error composes with a measurement's own readout error instead of replacing it.
Fixed
- Noise-model call logs record only successful setters and snapshot mutable arguments, preserving their configured values during pickle and call-log replay.
- Conflicting T1 and thermal-relaxation settings are rejected before changing the noise model, including uniform T1 updates across multiple qubits.
- NoiseModel setters accessed on an instance keep their docstrings.
- The docstrings of set_2q_depolarizing (Stim's DEPOLARIZE2, after any 2-qubit gate on the pair) and set_2q_gate_depolarizing (independent single-qubit depolarizing) now say how they differ.
0.3.9 - 2026-10-28
Added
- mps_routing_strategy for CPU MPS/MPO automatic swap routing. The default "legacy" preserves the existing routing behavior; opt-in "combined" uses bounded forecasts from live tensor ranks when automatic lookahead is zero. Combined prepares its gate table on first use and shares prepared immutable metadata between clones. It has measured runtime and finite-cap accuracy tradeoffs, so it is not selected automatically. Existing optimization thresholds, explicit lookahead settings, initial layouts, and GPU routing are preserved.
Changed
- CPU MPS/MPO setup and cloning reuse valid fusion routing metadata, avoiding repeated preparation while keeping each clone's execution state independent.
- x86 builds with GCC and Clang pass -ffp-contract=off, so the compiler no longer fuses multiplies and adds on its own. Serial and multithreaded runs now give bit-identical results with GCC 15; floating-point results can differ from 0.3.8 in the last bits.
Fixed
- Concurrent first calls from several threads no longer fail with Failed to create simulator handle. The library instance is now initialised once, and threads that arrive during initialisation wait for it. 0.3.8 exposed the race by creating simulator handles with the GIL released.
- Source builds find OpenBLAS on systems whose OpenBLAS CMake package lists a library that does not exist, such as Ubuntu 26.04, by falling back to FindBLAS.
0.3.8 - 2026-10-26
Added
- Adjoint differentiation engine (AdjointProgram) supporting exact Jacobians, Vector-Jacobian Products (VJP), and batched expectation values for parametrized statevector circuits.
- Probability readouts for AdjointProgram.
- Observable clustering with configurable lightcone size budget (cluster_budget) to group commuting observables during expectation value evaluation.
- Added observables parameter to mirror_fidelity for expectation-based mirror fidelity computations, preserving state truncation.
- The QASM parser accepts qelib1.inc's u0, a parametrised idle that adds no operation.
- Accepted seed as an alias for noise_seed in noise execution helpers.
Changed
- MPS/MPO swap routing improved with a multi-policy rollout portfolio, adaptive lookahead depth, and Schmidt-rank-based bond growth estimations derived from gate unitaries instead of fixed upper bounds.
- The MPS initial-layout search keeps the circuit's qubit order unless another layout is predicted to be at least four times cheaper (MPSDummySimulator::setMinLayoutGain). MPO layouts are unchanged.
- Circuits are compacted to continuous qubit indices in ascending order, not in order of first use. Seeded samples of circuits that first touch their qubits out of order can differ from earlier releases; their distributions do not.
- Worker threads in the shot execution pool are now retained between successive executions instead of being respawned each run.
- Trajectory execution thread counts for large states are capped at QCSim's team size.
- Prebuilt Windows dependencies and abi3 wheel builds for faster CI.
- Updated qcsim dependency pin.
Fixed
- Two race conditions in the persistent worker thread pool.
- MPS QFT at 64 qubits took 20 s instead of 0.2 s and truncated: the layout search scrambled the qubit order, and whether a run recovered depended on its random seed.
- macOS compilation errors from qubit_t and size_t type differences, and mixed-type template deduction in Sampling.cpp.
- Adjoint differentiation guarded against physical memory exhaustion and cgroup limits on Linux and Windows, with validation for cotangent shapes and qubit ranges.
- Potential crash during test shutdown caused by duplicate simulator factory globals.
- Single-qubit GPU tensor estimates defaulting to statevector backend.
- Missing GPU device metadata for identity-only expectation estimates.
0.3.7 - 2026-10-19
Added
- Circuit::RemoveEndMeasurements, exposed in Python as QuantumCircuit.remove_end_measurements.
Changed
- Expectation estimation strips terminal measurements before execution, across the Python, native request and noisy estimation paths.
Fixed
- get_statevector and get_probabilities lost amplitudes or swapped qubit order for circuits that leave lower-indexed qubits untouched; x(1) alone returned [0, 0].
0.3.6 - 2026-10-12
Added
- Automatic parity reduction transform (ParityReductionTransform / parity_reduction) for observable estimation, reducing active qubit count by exploiting Z2 symmetries (#40).
- Automatic causal-cone reduction transform (CausalConeReductionTransform / causal_cone_reduction) for observable estimation, stripping non-causal operations and spectator qubits (#39).
- Pre-execution transform configuration fields in SimulatorConfig: causal_cone_reduction and parity_reduction.
- Batched tensor expectations across public C and Python APIs.
- Native diagnostic capabilities and build metadata reporting.
- Modular nanobind Python bindings split into translation units under bindings/python/ (#38).
- Workflow input option in GitHub Actions to conditionally run the complete test suite.
Changed
- QCSim trajectory performance improvements, defaulting to per-shot execution.
- Improved reproducible sampling across QCSim backends.
- C++ codebase organization: grouped Maestro headers into functional subfolders and normalized native source filenames to UpperCamelCase.
- Optional, path-configurable Composer integration.
- Expanded README.md with feature overview, Python quickstart, and HPC execution guide.
- Updated Python reference documentation for pre-execution transforms and reduction config options.
Fixed
- Restored simulator validity retention before execution for Composer compatibility.
- Trajectory threading and terminal density sampling dispatch.
Dependencies
- Updated QCSim pin to 217c60953795 with improved extended stabilizer and Pauli propagation simulators and additional non-Clifford gates.
0.3.5 - 2026-10-02
Added
- Gate fusion for the QCSim and GPU backends, controlled by gate_fusion in SimulatorConfig and exposed through the simulator, network, C and native request interfaces with fusion statistics. SimulatorConfig.gate_fusion is optional: None means unset, and GetConfiguration("gate_fusion") then reports "auto".
- Native MPO queries on the QCSim and GPU backends: bit-vector probabilities, density matrix elements, dense density-matrix output, complex Pauli expectations and local operators A rho A†, through IState, the C interface, the Python bindings and the native request API.
- trim() and recanonicalize() for matrix-product states, and the trim and recanonicalize maintenance actions for MPS in the request API.
- Swap optimization (look-ahead routing) for MPOs, and disable_optimized_swapping and lookahead_depth for MPO requests.
Changed
- Breaking: the Python methods trim_mpo and recanonicalize_mpo are renamed trim and recanonicalize; they now work on MPS as well as MPO.
- When gate_fusion is not set, QCSim statevectors below 11 qubits and density matrices below 5 qubits run unfused, as fusion is slower there. An explicit true or false still forces fusion on or off at any size.
- MPO max_bond_dimension accepts zero for unlimited, and the trace-restore and hermitize options now apply to GPU MPO too.
- precision and use_double_precision are aliases kept in sync. Qiskit Aer honours single precision for initialization and state export, and the network no longer forces single precision.
- Faster CPU fused circuits, from the vectorized dense gate kernels and a cheaper fusion cache.
- The GPU diagnostics operation accepts an MPS for maintenance. An MPS reports no diagnostics by default.
Fixed
- Circuit layering no longer moves a measurement ahead of an earlier write to the same classical bit, or ahead of a conditional gate still reading it. Routed MPS/MPO runs returned wrong distributions for circuits that write a bit twice.
- Single-shot network calls keep the shot's classical bits when the executed circuit is narrower than the network allocation; ExecuteOnHost reported all zeros.
- MPS look-ahead routing survives gate fusion, so fused MPS circuits with mid-circuit measurements no longer fall back to local routing.
- FlushSimulator waits for queued GPU statevector and density-matrix work, and fusion boundaries no longer stall the GPU.
- Multithreading flags are forwarded to QCSim MPS and MPO simulators.
- Tensor network clones are isolated from the original.
- GPU, distributed GPU, Aer and composite simulators ignore a precision set after initialization instead of throwing. A new precision takes effect after Clear and the next Initialize.
- CI build installs apt packages after refreshing the package index.
Dependencies
- QCSim pin bumped to 1edb647: vectorized dense gate kernels, MPS recanonicalization fixes, MPO long-chain scaling, MPS sampling and input validation fixes, and Windows compile fixes.
0.3.4 - 2026-09-26
Changed
- Breaking: SimulatorConfig takes keyword arguments only and has one name per option, in Python and in the native JSON API:
- use_double_precision → precision ("single" or "double", Qiskit Aer and the GPU backends)
- mps_measure_no_collapse / mps_sample_measure_algorithm → mps_sampling ("probabilities" or "apply_measure")
- {mps,mpo,tensor_network}_use_gesvd{,j,p,r} → mps_svd_solver, mpo_svd_solver, tensor_network_svd_solver ("gesvd", "gesvdj", "gesvdp" or "gesvdr")
- pp_pauli_weight_threshold → pp_max_pauli_weight
- pp_steps_between_trims / pp_steps_between_deduplications → pp_gates_between_trims / pp_gates_between_deduplications
- Breaking: the noisy execution and estimation functions take noise_seed instead of seed, and config now comes before shots/noise_realizations. noise_seed must fit in 32 bits; when it is unset, the low 32 bits of config.seed are used. Zero shots or zero realisations are rejected.
- Breaking: NoiseModel.add_correlated_ou_band is renamed set_correlated_ou_band.
- Pauli propagation deduplicates every 10 operations when pp_gates_between_deduplications is unset. Deduplication alone leaves results unchanged; an explicit cadence still takes precedence.
Fixed
- Pickled noise models keep their correlated OU bands.
- Each noise realisation gets its own seed.
- Qiskit Aer ignores configuration settings it rejects instead of throwing, and no longer records them, so a cloned simulator does not replay them and they cannot change its reported simulation type.
- GPU Pauli propagation applies its settings after creating the native state, so thresholds and cadences take effect. A deduplication cadence also sets the truncation cadence unless one is given.
0.3.3 - 2026-09-24
Fixed
- Linux wheels import again. The 0.3.2 wheels failed with ImportError: libgfortran-83c28eba.so.5.0.0 because the bundled OpenBLAS could not locate its own bundled dependencies.
- Distributed expectation queries reset reused simulators before a new circuit, preventing state from leaking between Composer noise realizations when automatic simulator selection is disabled.
- Distributed reset splitting preserves target states and execution delays.
- Host mapping selects the current circuit even when its qubit IDs already fit the host, avoiding stale or missing circuits in Composer's NetQASM path.
- Python coherent_execute now seeds measurement execution from the public seed unless SimulatorConfig.seed overrides it, and derives a separate simulator stream for each realization.
- Direct simulator Configure("seed", ...) calls seed readout randomness as well as quantum sampling. Reapplying the same seed restarts both streams.
- A reset with no later measurement on its qubit is no longer dropped by the terminal-measurement execution path. Expectation values and state queries previously ignored such resets, so sampled T1/thermal-relaxation noise after the last gate had no effect on noisy_estimate_montecarlo or native estimate requests on pure-state methods.
- Python noisy execution and estimation (noisy_execute, noisy_estimate_montecarlo, noisy_fidelity, and the coherent_* and full_noise_* variants) fall back to SimulatorConfig.seed for noise injection when no seed argument is given, matching the native JSON API. Previously a configured simulator seed alone did not make the injected noise reproducible.
- Python noisy_estimate_montecarlo and full_noise_estimate use a separate simulator seed for each realization. Resets of entangled qubits now sample independent collapse outcomes while remaining reproducible from a public seed or SimulatorConfig.seed.
Changed
- QCSim pinned to 3ea2ea1, which seeds unseeded MPS/MPO simulators with std::random_device entropy as well as the clock.
Removed
- Removed NoiseAdd::apply_readout_error_to_counts (MAESTRO_NOISE_ADD_VERSION is now 4). Attach readout rates with noise::attach_readout_error before execution, or use the noisy/full execution helpers. Composer must be updated together with Maestro to remove its bindings to this method.
0.3.2 - 2026-09-18
Added
- Native Qiskit Aer Integration: Enabled Qiskit Aer backend by default in CMake (ENABLE_QISKIT_AER=ON), automatically fetching the fork from https://github.com/QoroQuantum/qiskit-aer and linking against OpenBLAS. Exposed SimulatorType.QiskitAer and SimulatorType.CompositeQiskitAer in the Python bindings.
Fixed
- Native JSON requests accept sampled thermal relaxation with T1 < T2 <= 2*T1, using effective T2 = T1 with a warning and approximation metadata, matching Python. Exact density-matrix/MPO execution preserves calibrated T2.
- Native readout noise applies at measurement time, including conditional measurements and noisy outcomes consumed by classical control.
- Native measurement/readout randomness follows the explicit simulator seed or falls back to noise.seed, independently of circuit-noise injection.
- Legacy SimpleExecute and SimpleEstimate honor config.seed, including zero and the full uint64 range, and reject invalid seeds.
Changed
- Python package version bumped to 0.3.2.
0.3.1 - 2026-09-10
Added
- Native Delay & Idle Operation: Added first-class Delay instruction across Circuit IR, Factory, Python bindings (qc.delay), and OpenQASM 2/3 parsers with duration validation in seconds.
- Idle Channel Decoherence: Introduced idle channel simulation via set_idle_noise(qubit, t1, t2, excited_population, detuning_hz) to model thermal relaxation, phase decay, and coherent detuning rotation accumulated over idling intervals.
- Continuous OU Noise Integration: Integrated continuous-time Ornstein-Uhlenbeck (OU) dephasing during delays, analytically propagating correlated frequency fluctuations across arbitrary idle durations.
- Multi-Band OU & 1/f Spectrum Noise: Added multi-band OU dephasing support (add_correlated_ou_band, set_multi_correlated_ou, set_all_multi_correlated_ou), synthetic 1/f noise generation (set_1_over_f_noise), and stationary equilibrium initialization (stationary_init).
- Sinter Integration: Added maestro.sinter module with MaestroSinterSampler and MaestroCompiledSampler implementing Sinter's sampling interface for Stim-based quantum error correction (QEC) benchmarking.
- GPU SVD Algorithm Selection: Added configuration parameters in SimulatorConfig to select specialized GPU SVD solvers (gesvd, gesvdj, gesvdp, gesvdr) for MPS, MPO, and Tensor Network backends.
Changed
- Python package version bumped to 0.3.1.
0.3.0 - 2026-09-07
Added
- GPU Density Matrix Simulator: Added full density matrix simulation on GPU (SimulationType.kDensityMatrix with SimulatorType.kGpuSim) for exact mixed-state quantum simulation.
- GPU Matrix Product Operator (MPO) Simulator: Added GPU-accelerated MPO simulation (SimulationType.kMatrixProductOperator with SimulatorType.kGpuSim), supporting non-unitary noise, truncation thresholding, trimming, and recanonicalization.
- QCSim Extended Stabilizer Simulator: Added extended stabilizer simulation backend support in QCSim for near-Clifford circuit execution.
- CPTP Quantum Channels & Exact Noise Models: Introduced QuantumChannel and QuantumChannelOperation classes supporting general Kraus representations, along with predefined channels (bit-flip, phase-flip, depolarizing, amplitude damping, phase damping, and thermal relaxation).
- Deterministic Simulation Seeding: Exposed seed parameter in SimulatorConfig and across simulator backends for reproducible stochastic simulations.
- GPU Device Selection: Added interface to select the target GPU device for GPU simulator backends.
- OpenQASM 3 Support: Added OpenQASM 3 import and export capabilities.
- Documentation Rework: Restructured Python API documentation into dedicated guides for backends, HPC execution, noise simulation, algorithms, and quickstart reference.
Fixed
- Bond Dimension Capping & Synchronization: Configured default MPS and MPO bond dimension to 128 in GpuState and GPU plugin to prevent unbounded device memory allocation.
- Mirror Fidelity Validation: Added validation in mirror_fidelity to raise informative errors if simulation yields zero measurement samples or zero shots instead of failing silently.
- Pauli Propagation: Fixed GPU Pauli destructive state hooks and truncation configuration propagation.
Changed
- Python package version bumped to 0.3.0.
0.2.18 - 2026-08-13
Added
- Bond dimension tracking per time step in incremental_evolve
- Simulators and networks Configuration classes and refactoring
Fixed
- Misaligned time step guard handling in network evolution
Changed
- Python package version bumped to 0.2.18
0.2.17 - 2026-08-11
Added
- Bond Dimension Callback & Max Bond Dimension Tracking — exposed maximum bond dimension reached during MPS simulation across execute, estimate, and incremental_evolve Python return dictionaries (max_bond_dim_reached)
- Integrated QCSim bond dimension callback support and GPU MPS simulator bond dimension callback
- Added simulator Configuration class to standardise parameter delivery across simulator backends
Changed
- Python package version bumped to 0.2.17
0.2.13 - 2026-05-02
Added
- Asymmetric readout error — set_readout_error(q, p_meas1_prep0, p_meas0_prep1), set_readout_error_symmetric(q, p), set_all_readout_error(n, p) for per-qubit classical measurement error modelling. Applied as a post-measurement channel in noisy_execute and full_noise_execute
- Two-qubit depolarizing channel — set_2q_depolarizing(q1, q2, p) for correlated 15-Pauli noise applied after CX/CZ gates on specific qubit pairs
- Gate-type-specific depolarizing — set_1q_gate_depolarizing(q, p) and set_2q_gate_depolarizing(q, p) for separate noise rates after single-qubit vs two-qubit gates, with bulk setters set_all_1q_gate_depolarizing and set_all_2q_gate_depolarizing
- qc.noisy_prob(target, nm) — readout-corrected path integral probability using first-order analytic expansion (n+1 PI evaluations instead of Monte Carlo)
- Readout error, two-qubit depolarizing, gate-type-specific noise, and noisy_prob sections in python.dox (Doxygen) and TUTORIAL.md
- Complete NoiseModel method reference table in both documentation sources
Changed
- Python package version bumped to 0.2.13
- Fixed set_pauli_channel documentation to use correct binding name set_qubit_noise
0.2.12 - 2026-04-28
Added
- Path Integral simulation backend — new exact-amplitude simulator (kPathIntegral) integrated into the QCSim common interface, supporting amplitudes, measurements, sampling, and Pauli-string expectation values. Exposed through the factory and the SimulatorConfig(simulator_type="path_integral") Python API
- Path Integral Python bindings — amplitude_from_zero() and amplitude() methods on QuantumCircuit for computing exact transition amplitudes via path integrals
- IsBranching() method on all quantum gate types, used by the path integral simulator to identify branching operations
- Path Integral via Network interface — SimpleDisconnectedNetwork now dispatches path integral jobs; multithreading is disabled for path integral simulators in networks when measurements are only at the end
- Coherent noise model — NoiseModel now supports deterministic rotation-gate noise injection (Rx/Ry/Rz) alongside stochastic Pauli channels. Coherent angle is derived from error probability via ε = 2·arcsin(√p) to match per-gate infidelity
- Coherent noise setters: set_coherent_depolarizing(), set_coherent_dephasing(), set_coherent_bit_flip(), set_coherent_rotation(), set_all_coherent_depolarizing()
- T1 amplitude damping noise — set_t1(), set_all_t1(), set_t1_from_time() for per-qubit T1 decay with physical time-constant conversion (γ = 1 − e^(−t_gate/T₁))
- ZZ crosstalk noise — set_crosstalk() for pairwise qubit coupling injection
- coherent_execute / coherent_estimate — Python bindings for executing circuits and estimating expectation values with coherent rotation noise
- full_noise_execute / full_noise_estimate — combined noise pipeline applying coherent + crosstalk + T1 + Pauli noise in a single call
- Comprehensive test suites: 600+ lines of path integral C++ tests (random circuits, amplitudes, measurements, sampling, Pauli strings), 290+ lines of network simulator tests, 1200+ lines of new Python binding tests covering all noise modes
- Noise simulation and path integral sections in TUTORIAL.md with usage examples
Changed
- NoiseModel header expanded to support Pauli, coherent, T1, and crosstalk noise in a unified model — both modes can be configured on the same instance
- QCSimSimulator routes all gate types through the path integral backend when kPathIntegral simulation type is selected
- QCSimState extended with path integral simulator state management, amplitude computation, and measurement support
- Doxygen upgraded to latest version; docs CI workflow updated
- Python package version bumped to 0.2.12
Fixed
- Missing public: access specifier on PathIntegralSimulator class methods
- Include path issues for Linux compilation in network simulator tests
- Compile warnings in NetworkJob.h and SimpleDisconnectedNetwork.h
0.2.11 - 2026-04-20
Added
- Python 3.13 and 3.14 wheels published to PyPI for Linux, macOS, and Windows
- QasmToCirc.failed() and QasmToCirc.get_error_message() Python bindings for inspecting parser state after a failed parse
- QASM parser: id gates and unrecognised no-op instructions are now silently skipped instead of raising
Changed
- SimulatorConfig struct — all execution, estimation, and fidelity functions now accept a single config=maestro.SimulatorConfig(...) parameter instead of repeating simulator_type, simulation_type, max_bond_dimension, singular_value_threshold, use_double_precision, disable_optimized_swapping, lookahead_depth, and mps_measure_no_collapse as individual keyword arguments. Create a config once and reuse it across calls.
- Updated all Python examples to use the new SimulatorConfig API
- Updated python.dox and TUTORIAL.md documentation with SimulatorConfig usage
- QasmToCirc.parse_and_translate now raises ValueError carrying the parser error message when QASM input is invalid, instead of returning a bad circuit silently
- Build toolchain: cibuildwheel upgraded from v2.22.0 to v3.4.1; default Linux manylinux image moved from manylinux2014 to manylinux_2_28 (wheels now require glibc 2.28+, i.e. RHEL 8 / Ubuntu 20.04 / Debian 10 or newer)
- MPS swap optimization: growthFactorGate heuristic tuned from 0.7 to 0.65 across QCSim, GPU, MPSDummy, and SimpleDisconnectedNetwork — may shift swap-vs-gate planning decisions on large circuits
Fixed
- simple_execute (QASM variant) was not forwarding mps_measure_no_collapse to the simulator
- noisy_estimate_montecarlo was not forwarding mps_measure_no_collapse to noisy runs
- mirror_fidelity returned incorrect values because the circuit optimizer cancelled the mirror's paired gate/adjoint operations before execution. Circuit optimization and MPS swap optimization are now disabled for the mirror run, and non-gate operations (e.g. measurements) are skipped during the adjoint reverse pass
- SampleCountsMany on the Qiskit Aer MPS backend returned bits in ascending-qubit-index order rather than the caller-requested qubit order, silently misaligning outcomes. Bits are now remapped to match the caller order (consistent with the statevector backend)
- singular_value_threshold values below ~1e-4 were truncated to 0 when serialized to the MPS backend (via std::to_string's default 6-digit precision), effectively disabling entanglement truncation. Serialization now uses max_digits10 (17 significant digits)
0.2.10 - 2026-04-16
Added
- Noise simulation API — NoiseModel class for per-qubit Pauli noise channels (depolarizing, dephasing, bit-flip, custom)
- noisy_estimate — analytical Pauli channel damping with zero simulation overhead for fast ansatz noise screening
- noisy_estimate_montecarlo — gate-by-gate Monte Carlo noisy estimation for accurate depth-dependent noise simulation
- noisy_execute — Monte Carlo shot-based noisy circuit execution with batched noise realizations
- Noise model helpers: set_depolarizing, set_dephasing, set_bit_flip, set_pauli_channel, set_all_depolarizing
- Comprehensive noise test suite (25 tests covering NoiseModel, analytical damping, Monte Carlo estimation, and execution)
- Noise simulation section in TUTORIAL.md with usage examples and parameter reference
Changed
- Default lookahead_depth changed from 20 to -1 (auto-tuning) to prevent hangs on larger MPS circuits
Fixed
- MPS swap optimization hang on larger circuits caused by hardcoded lookahead_depth=20 bypassing the C++ auto-tuning heuristic
0.2.7 - 2026-03-27
Added
- Inner product — compute ⟨ψ₁|ψ₂⟩ between two circuits via ProjectOnZero (maestro.inner_product(circ_1, circ_2) and qc.inner_product(other))
- Python documentation for inner_product in python.dox
- Comprehensive test suite for inner product (9 tests covering identical, orthogonal, parametric, MPS, and phase-difference cases)
0.2.6 - 2026-03-25
Added
- ProjectOnZero — efficient ⟨0|ψ⟩ projection for all simulator backends (QCSim MPS, GPU MPS, statevector, composite)
- ExecuteOnHostProjectOnZero network-level method with qubit remapping support
- ExecuteOnHostAmplitudes with proper qubit remapping for statevector extraction
- Mirror fidelity — maestro.mirror_fidelity() and qc.mirror_fidelity() with shot-based and exact statevector modes
- Statevector access — maestro.get_statevector() and qc.get_statevector() Python bindings
- Probability access — maestro.get_probabilities() Python binding
- MPS swap optimization with lookahead heuristics and initial qubit mapping
- Classically controlled gate support for MPS lookahead swap optimization
- Improved QCSim MPS sampling for partial qubit measurements
- ProjectOnZero C++ tests across all simulator backends
Fixed
- Linux GPU library compilation (missing include)
- MPS optimization test adjusted from 20 to 12 qubits for stability
0.2.5 - 2026-03-18
Added
- Windows wheel support — pre-built wheels for Windows AMD64 (Python 3.10, 3.11, 3.12) published to PyPI
- vcpkg-based dependency management for Windows CI builds
- Dry-run Windows CI workflow
Fixed
- Eigen type mismatch between Windows and Linux (Eigen::Index → long long int)
- OpenMP configuration on Windows
- Compile warnings in MPS simulator and QCSim
0.2.4 - 2026-03-12
Changed
- Split Python version builds into separate CI matrix elements for faster Windows builds
- Code styling and minor CI workflow improvements
0.2.3 - 2026-03-07
Added
- Exposed setting the initial qubits map from the Python API
- MPS swap cost optimization with improved heuristics
Fixed
- Linux wheel repair (auditwheel) patching for libmaestro linkage
- rpath configuration ($ORIGIN) for reliable library resolution in wheels
0.2.2 - 2026-03-01
Fixed
- Bundled excluded libmaestro shared library with Python wheel
- macOS build issues
0.2.1 - 2026-02-25
Fixed
- PyPI package metadata issue
- Version bump for initial stable release
Added
- Python bindings via nanobind with QuantumCircuit model and GPU support
- PyPI distribution with scikit-build-core and cibuildwheel for Linux & macOS
- Pauli propagator simulator — CPU and GPU implementations with non-Clifford gate decomposition
- Extended stabilizer simulator with support for > 64 qubits
- QuEST simulator integration with factory function and tests
- GPU stabilizer simulator exposed through the library API
- Rydberg atom array simulation examples (adiabatic preparation, phase diagrams, spatial correlations)
- MPS parameters passthrough in the SimpleExecute flow
- Expectation value estimation via Python (SimpleEstimate)
- Maestro executable support for new simulators (Pauli propagator, extended stabilizer, QuEST)
- Double-precision toggle from Python bindings
- ccache support for faster rebuilds
- Doxygen documentation GitHub Actions workflow
Changed
- Refactored GitHub Actions CI workflow for better dependency caching
- Build system configured for PyPI distribution (rpath, install targets)
- Improved GPU precision handling with placeholder params
Fixed
- macOS OpenMP/install build issues
- Linux GPU compilation errors
- Circuit distribution crash when no distributor is present in disconnected networks
- Build warnings suppressed for third-party dependencies
0.1.0 - 2026-01-18
Added
- Core simulation engine with multi-backend support (QCSim statevector, MPS tensor network, Qiskit Aer, Clifford)
- Composite simulator for automatic circuit distribution across backends
- GPU tensor network simulator with statevector and stabilizer support
- Maestro shared library (libmaestro) with SimpleExecute JSON/QASM API
- Maestro standalone executable with command-line interface
- QASM 2.0 parser (string → circuit conversion) with standard gate support
- Expectation value estimation framework
- Network-based job scheduling and execution
- OpenMP parallelization with SIMD (AVX2/FMA) acceleration
- Boost serialization support
- Doxygen API documentation with GitHub Pages deployment
- GitHub Actions CI (Ubuntu build + test)
- Pre-commit hooks with clang-format code formatting
- CITATION.cff, CODE_OF_CONDUCT.md, CONTRIBUTING.md, INSTALL.md