dense-evolution 8.2.0__tar.gz → 8.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/PKG-INFO +8 -2
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/README.md +1 -1
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/__init__.py +9 -4
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/__init__.py +4 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/zne.py +153 -1
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/scf.py +51 -4
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/__init__.py +13 -2
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/density_matrix_channels.py +30 -1
- dense_evolution-8.2.2/dense_evolution/noise/pink.py +80 -0
- dense_evolution-8.2.2/dense_evolution/utils/mass_decomposition.py +246 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution.egg-info/PKG-INFO +8 -2
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution.egg-info/SOURCES.txt +9 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution.egg-info/requires.txt +8 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/pyproject.toml +38 -2
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/research/local_site/app/server.py +184 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/__init__.py +12 -0
- dense_evolution-8.2.2/tools/dashboard/core/crypto_protocols.py +77 -0
- dense_evolution-8.2.2/tools/dashboard/core/mass_decomposition_tool.py +47 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/mitigation.py +76 -1
- dense_evolution-8.2.2/tools/dashboard/core/native_hf_diagnostics.py +62 -0
- dense_evolution-8.2.2/tools/dashboard/core/rag_tool.py +45 -0
- dense_evolution-8.2.2/tools/ia_utils/rag.py +288 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/client.py +105 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/models.py +52 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/server.py +24 -11
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/tools/chemistry_tools.py +45 -2
- dense_evolution-8.2.2/tools/mcp_server/tools/crypto_tools.py +66 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/tools/mitigation_tools.py +20 -0
- dense_evolution-8.2.2/tools/mcp_server/tools/retrieval_tools.py +44 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/tools/system_tools.py +12 -3
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/autodiff.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/_engine_imports.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/circuit_chunker.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/core.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/disk_overflow.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/geometry.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/guard.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/chunk/kernels.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/mps.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/backends/statevector.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/chunk.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/compiler.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/diagram.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/gates.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/parser.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/qft.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/random_circuit.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/registry.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/topology.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/trotter.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/circuits/uccsd.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/cli.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/compiler.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/config.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/drawing.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/entropy.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/fermions.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/gates.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/harrison_tb.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/healing.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/interop/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/interop/qiskit_pennylane.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/measurement.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/healing.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/kl_divergence.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/magic_entropy.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/magic_entropy_shadows.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/renyi.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mitigation/stabilizer_renyi_entropy.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/mps.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/assembly.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/basis.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/boys.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/bridge.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/cartesian.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/coulomb.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/differentiable.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/gaussians.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/kinetic.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/libcint_bridge.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/native_hf/overlap.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/coherent_attack.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/cosmic_ray.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/differentiable.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus/amplitude_damping.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus/bitflip.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus/combined.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus/depolarizing.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus/ideal.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus/phaseflip.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/kraus_channels.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/oscillating.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/observables.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/parser.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/physics/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/physics/entropy.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/physics/fermions.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/physics/observables.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/physics/qec.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/physics/spectral.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/physics/states.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/qec.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/qft.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/qmmm/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/qmmm/ase_bridge.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/qmmm/forces.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/qmmm/propagation.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/qmmm/region.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/random_circuit.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/registry.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/simulator.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/solvers/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/solvers/autodiff.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/solvers/harrison_tb.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/solvers/vhd_tb.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/states.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/topology.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/trotter.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/utils/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/utils/drawing.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/utils/measurement.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/vhd_tb.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution.egg-info/dependency_links.txt +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution.egg-info/entry_points.txt +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution.egg-info/top_level.txt +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/license.md +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/research/local_site/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/research/local_site/app/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/setup.cfg +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/_gate_tables.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/band_structure.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/circuit_builder_component.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/circuit_diagram.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/engine.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/graphical_builder.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/hamiltonians.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/noise_tools.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/qasm_library.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/qmmm.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/state_visuals.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/system_limits.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/vector_healing.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/visuals.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/vqe.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/dashboard/core/wormhole.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/ia_utils/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/ia_utils/adversarial_vector_attack.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/ia_utils/vector_healing.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/config.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/molecules.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/tools/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/tools/circuit_tools.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/tools/noise_tools.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/tools/wormhole_tools.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/utils/__init__.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/utils/cache.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/utils/images.py +0 -0
- {dense_evolution-8.2.0 → dense_evolution-8.2.2}/tools/mcp_server/utils/truncation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dense-evolution
|
|
3
|
-
Version: 8.2.
|
|
3
|
+
Version: 8.2.2
|
|
4
4
|
Summary: High-performance quantum simulation toolkit -- Statevector/MPS engines with JIT compilation, noise modeling, VQE, QEC, quantum chemistry, and agent-native tooling
|
|
5
5
|
Author-email: Salvatore Pennacchio <jtatopenn@libero.it>
|
|
6
6
|
License: Business Source License 1.1
|
|
@@ -64,6 +64,11 @@ Provides-Extra: qmmm
|
|
|
64
64
|
Requires-Dist: rdkit>=2023.9.1; extra == "qmmm"
|
|
65
65
|
Provides-Extra: ase
|
|
66
66
|
Requires-Dist: ase>=3.22.0; extra == "ase"
|
|
67
|
+
Provides-Extra: rag
|
|
68
|
+
Requires-Dist: scikit-learn>=1.0.0; extra == "rag"
|
|
69
|
+
Requires-Dist: sentence-transformers>=2.2.0; extra == "rag"
|
|
70
|
+
Provides-Extra: armor
|
|
71
|
+
Requires-Dist: dense-armor>=1.1.18; extra == "armor"
|
|
67
72
|
Provides-Extra: full
|
|
68
73
|
Requires-Dist: cupy-cuda12x>=12.0.0; extra == "full"
|
|
69
74
|
Requires-Dist: streamlit>=1.30.0; extra == "full"
|
|
@@ -80,6 +85,7 @@ Requires-Dist: httpx>=0.27; extra == "full"
|
|
|
80
85
|
Provides-Extra: dev
|
|
81
86
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
82
87
|
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
88
|
+
Requires-Dist: pytest-env>=1.0.0; extra == "dev"
|
|
83
89
|
Provides-Extra: docs
|
|
84
90
|
Requires-Dist: mkdocs>=1.6.0; extra == "docs"
|
|
85
91
|
Requires-Dist: mkdocs-material>=9.5.0; extra == "docs"
|
|
@@ -343,7 +349,7 @@ If Dense-Evolution is useful in academic work, please cite it via the metadata i
|
|
|
343
349
|
Archived on [Zenodo](https://zenodo.org/):
|
|
344
350
|
|
|
345
351
|
- **Concept DOI** (always resolves to the latest version): [10.5281/zenodo.21855643](https://doi.org/10.5281/zenodo.21855643)
|
|
346
|
-
- **This release (v8.
|
|
352
|
+
- **This release (v8.2.0)**: [10.5281/zenodo.22818319](https://doi.org/10.5281/zenodo.22818319)
|
|
347
353
|
|
|
348
354
|
---
|
|
349
355
|
|
|
@@ -249,7 +249,7 @@ If Dense-Evolution is useful in academic work, please cite it via the metadata i
|
|
|
249
249
|
Archived on [Zenodo](https://zenodo.org/):
|
|
250
250
|
|
|
251
251
|
- **Concept DOI** (always resolves to the latest version): [10.5281/zenodo.21855643](https://doi.org/10.5281/zenodo.21855643)
|
|
252
|
-
- **This release (v8.
|
|
252
|
+
- **This release (v8.2.0)**: [10.5281/zenodo.22818319](https://doi.org/10.5281/zenodo.22818319)
|
|
253
253
|
|
|
254
254
|
---
|
|
255
255
|
|
|
@@ -6,7 +6,8 @@ from .backends.statevector import DenseSVSimulator
|
|
|
6
6
|
from .circuits.parser import QASMParser, QASMCircuit
|
|
7
7
|
from .circuits.compiler import QuantumTranspiler
|
|
8
8
|
from .noise import (NoiseModel, NoiseSpec, global_depolarizing_channel, amplitude_damping_channel,
|
|
9
|
-
cosmic_ray_burst_profile, oscillating_p_eff
|
|
9
|
+
phaseflip_channel_exact, cosmic_ray_burst_profile, oscillating_p_eff,
|
|
10
|
+
pink_noise_p_eff)
|
|
10
11
|
from .circuits.registry import QuantumHardwareRegistry
|
|
11
12
|
from .circuits.gates import GATES, PARAMETRIC_GATES, GATE_IDS
|
|
12
13
|
from .backends.chunk import Chunk
|
|
@@ -32,6 +33,8 @@ from .mitigation.zne import (richardson_extrapolate, richardson_amplification_fa
|
|
|
32
33
|
bounded_exponential_extrapolate,
|
|
33
34
|
project_to_physical, uhlmann_fidelity, zne_density_matrix,
|
|
34
35
|
jsd_predictive_zne_density_matrix,
|
|
36
|
+
coherence_predictive_zne_density_matrix,
|
|
37
|
+
classically_augmented_zne_phaseflip,
|
|
35
38
|
richardson_extrapolate_jit, zero_noise_extrapolation_jit,
|
|
36
39
|
polynomial_extrapolate_jit, uhlmann_fidelity_jit, zne_density_matrix_jit)
|
|
37
40
|
from .circuits.diagram import plot_circuit
|
|
@@ -57,7 +60,7 @@ from .physics.qec import (pauli_commutes, compute_syndrome, erasure_aware_decode
|
|
|
57
60
|
blind_minimum_weight_decode, decode_with_erasure_fallback,
|
|
58
61
|
counts_in_intervals_dimension, nearest_coset_decode)
|
|
59
62
|
|
|
60
|
-
__version__ = "8.
|
|
63
|
+
__version__ = "8.2.2"
|
|
61
64
|
|
|
62
65
|
__all__ = [
|
|
63
66
|
"__version__",
|
|
@@ -87,8 +90,10 @@ __all__ = [
|
|
|
87
90
|
"zero_noise_extrapolation", "polynomial_extrapolate",
|
|
88
91
|
"bounded_exponential_extrapolate",
|
|
89
92
|
"project_to_physical", "uhlmann_fidelity", "zne_density_matrix",
|
|
90
|
-
"jsd_predictive_zne_density_matrix", "
|
|
91
|
-
"
|
|
93
|
+
"jsd_predictive_zne_density_matrix", "coherence_predictive_zne_density_matrix",
|
|
94
|
+
"classically_augmented_zne_phaseflip",
|
|
95
|
+
"global_depolarizing_channel", "amplitude_damping_channel", "phaseflip_channel_exact",
|
|
96
|
+
"cosmic_ray_burst_profile", "oscillating_p_eff", "pink_noise_p_eff",
|
|
92
97
|
"richardson_extrapolate_jit", "zero_noise_extrapolation_jit",
|
|
93
98
|
"polynomial_extrapolate_jit", "uhlmann_fidelity_jit", "zne_density_matrix_jit",
|
|
94
99
|
# Physics -- states, observables, entropy, fermions, QEC
|
|
@@ -13,6 +13,8 @@ from .zne import (
|
|
|
13
13
|
bounded_exponential_extrapolate,
|
|
14
14
|
project_to_physical, uhlmann_fidelity, zne_density_matrix,
|
|
15
15
|
jsd_predictive_zne_density_matrix,
|
|
16
|
+
coherence_predictive_zne_density_matrix,
|
|
17
|
+
classically_augmented_zne_phaseflip,
|
|
16
18
|
richardson_extrapolate_jit, zero_noise_extrapolation_jit,
|
|
17
19
|
polynomial_extrapolate_jit, uhlmann_fidelity_jit, zne_density_matrix_jit,
|
|
18
20
|
)
|
|
@@ -36,6 +38,8 @@ __all__ = [
|
|
|
36
38
|
"bounded_exponential_extrapolate",
|
|
37
39
|
"project_to_physical", "uhlmann_fidelity", "zne_density_matrix",
|
|
38
40
|
"jsd_predictive_zne_density_matrix",
|
|
41
|
+
"coherence_predictive_zne_density_matrix",
|
|
42
|
+
"classically_augmented_zne_phaseflip",
|
|
39
43
|
"richardson_extrapolate_jit", "zero_noise_extrapolation_jit",
|
|
40
44
|
"polynomial_extrapolate_jit", "uhlmann_fidelity_jit", "zne_density_matrix_jit",
|
|
41
45
|
"calculate_advanced_sigma", "calculate_phi_ab", "calculate_vettore_dinamico",
|
|
@@ -23,7 +23,8 @@ from .healing import calculate_delta_preemp
|
|
|
23
23
|
__all__ = ["richardson_extrapolate", "richardson_amplification_factor", "zero_noise_extrapolation",
|
|
24
24
|
"polynomial_extrapolate", "bounded_exponential_extrapolate",
|
|
25
25
|
"project_to_physical", "uhlmann_fidelity", "zne_density_matrix",
|
|
26
|
-
"jsd_predictive_zne_density_matrix", "
|
|
26
|
+
"jsd_predictive_zne_density_matrix", "coherence_predictive_zne_density_matrix",
|
|
27
|
+
"classically_augmented_zne_phaseflip", "global_depolarizing_channel",
|
|
27
28
|
"amplitude_damping_channel", "cosmic_ray_burst_profile",
|
|
28
29
|
"richardson_extrapolate_jit", "zero_noise_extrapolation_jit",
|
|
29
30
|
"polynomial_extrapolate_jit", "uhlmann_fidelity_jit", "zne_density_matrix_jit"]
|
|
@@ -836,3 +837,154 @@ def _jsd_predictive_zne_density_matrix_core(rho_at_scales: jnp.ndarray, nudge_sc
|
|
|
836
837
|
c3 = 1.0 - nudge_scale * rectified
|
|
837
838
|
extrapolated = (c1 * e_l1 + c2 * e_l2 + c3 * e_l3) / (c1 + c2 + c3)
|
|
838
839
|
return project_to_physical(extrapolated)
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
def _coherence_l1(rho: jnp.ndarray) -> jnp.ndarray:
|
|
843
|
+
"""l1-norm of coherence (Baumgratz, Cramer & Plenio, Phys. Rev. Lett.
|
|
844
|
+
113, 140401, 2014): the sum of the magnitudes of every off-diagonal
|
|
845
|
+
density-matrix entry. A standard, basis-dependent measure of how much
|
|
846
|
+
quantum coherence a state carries in the computational basis --
|
|
847
|
+
unlike `_js_divergence`, which only ever sees the diagonal
|
|
848
|
+
(populations), this is sensitive to exactly what dephasing destroys."""
|
|
849
|
+
n = rho.shape[0]
|
|
850
|
+
return jnp.sum(jnp.abs(rho) * (1.0 - jnp.eye(n, dtype=rho.dtype)))
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
def coherence_predictive_zne_density_matrix(rho_at_scales, noise_factors) -> jnp.ndarray:
|
|
854
|
+
"""Density-matrix ZNE with a coherence-informed coefficient nudge --
|
|
855
|
+
the same adaptive-nonlinearity mechanism as
|
|
856
|
+
`jsd_predictive_zne_density_matrix`, but signaled by the l1-norm of
|
|
857
|
+
coherence (`_coherence_l1`) instead of the Jensen-Shannon divergence
|
|
858
|
+
of the diagonal populations.
|
|
859
|
+
|
|
860
|
+
Motivation: `jsd_predictive_zne_density_matrix`'s signal is the
|
|
861
|
+
density-matrix diagonal only. Any purely dephasing-type noise
|
|
862
|
+
(phase-flip, or a coherent Z-axis over-rotation) is diagonal in the
|
|
863
|
+
computational basis -- it moves phase, never populations -- so that
|
|
864
|
+
signal is blind to it BY CONSTRUCTION, not merely weak: verified
|
|
865
|
+
directly in Dense-Evolution-Discovery's
|
|
866
|
+
scripts/jsd_zne_noise_generalization.py, the fidelity delta from the
|
|
867
|
+
classical-JSD nudge is exactly 0.0 at every tested phase-flip noise
|
|
868
|
+
strength and every tested coherent-rotation angle. A quantum-JSD
|
|
869
|
+
variant (von Neumann entropy of the full density matrix instead of
|
|
870
|
+
Shannon entropy of the diagonal) was tried there too and rejected: it
|
|
871
|
+
weakens the already-working amplitude-damping/combined-noise case
|
|
872
|
+
without fixing the coherent-error case, since a smooth deterministic
|
|
873
|
+
function of the noise-scale factor has `jsd_12~=jsd_23` regardless of
|
|
874
|
+
which divergence measures it -- the nonlinearity trigger this whole
|
|
875
|
+
family of methods relies on is structurally near-zero there no
|
|
876
|
+
matter the signal.
|
|
877
|
+
|
|
878
|
+
Validated scope, checked directly rather than assumed universal: real
|
|
879
|
+
effect on phase-flip/dephasing-dominated noise for `base_p<=0.10`;
|
|
880
|
+
NOT validated (and not claimed) for amplitude-damping-dominated noise
|
|
881
|
+
(use `jsd_predictive_zne_density_matrix` there instead) or for
|
|
882
|
+
coherent/deterministic errors (out of reach for this entire family of
|
|
883
|
+
methods, not just this signal -- see above).
|
|
884
|
+
|
|
885
|
+
Verified at 200 independent seeds on phase-flip noise (GHZ(4),
|
|
886
|
+
`base_p=0.05`, K=150 trajectories/scale) before promotion: the nudge
|
|
887
|
+
activates (rectified nonlinearity > 0) on 63/200 seeds (31.5%) --
|
|
888
|
+
among those, 63/63 improve over plain `zne_density_matrix`, mean
|
|
889
|
+
fidelity gain +0.014892, one-sample t-test against zero
|
|
890
|
+
p=1.07e-08, a 20000-resample permutation test finding no resample
|
|
891
|
+
matching or exceeding the observed effect (p<0.00005). Confirmed
|
|
892
|
+
across a noise-level sweep (100 seeds/level, GHZ(4)): significant by
|
|
893
|
+
both tests, 100% win rate among active points, at base_p in (0.03,
|
|
894
|
+
0.05, 0.08, 0.10); NOT significant at base_p=0.15 (p=0.288 t-test,
|
|
895
|
+
p=0.301 permutation) -- a real, honest upper boundary, not a
|
|
896
|
+
universal effect at any noise strength. Confirmed on a second circuit
|
|
897
|
+
family (hardware-efficient VQE-style ansatz, 2 layers) at
|
|
898
|
+
`base_p=0.05`: 69/150 active (46%, a higher activation rate than
|
|
899
|
+
GHZ), 67/69 positive, p=4.4e-06 -- the effect is not GHZ-specific.
|
|
900
|
+
When inactive, reduces EXACTLY to `zne_density_matrix` at 3
|
|
901
|
+
equally-spaced scales (verified: max deviation ~1e-8, floating-point
|
|
902
|
+
noise) -- zero risk in that regime, by construction, the same safety
|
|
903
|
+
property `jsd_predictive_zne_density_matrix` has.
|
|
904
|
+
|
|
905
|
+
Only defined for exactly 3 equally-spaced noise factors (1x, 2x, 3x),
|
|
906
|
+
same restriction and reason as `jsd_predictive_zne_density_matrix`:
|
|
907
|
+
the Lagrange coefficients (3, -3, 1) this nudges are specific to that
|
|
908
|
+
spacing."""
|
|
909
|
+
rho_at_scales = jnp.asarray(rho_at_scales, dtype=jnp.complex128)
|
|
910
|
+
noise_factors = jnp.asarray(noise_factors, dtype=jnp.float64)
|
|
911
|
+
if noise_factors.shape[0] != 3:
|
|
912
|
+
raise NotImplementedError(
|
|
913
|
+
"coherence_predictive_zne_density_matrix is only defined for exactly 3 noise "
|
|
914
|
+
"factors; call zne_density_matrix(...) directly for the plain N-point case."
|
|
915
|
+
)
|
|
916
|
+
return _coherence_predictive_zne_density_matrix_core(rho_at_scales)
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
def _coherence_predictive_zne_density_matrix_core(rho_at_scales: jnp.ndarray, nudge_scale: float = 0.5) -> jnp.ndarray:
|
|
920
|
+
"""`jax.jit`-traceable core of `coherence_predictive_zne_density_matrix`
|
|
921
|
+
-- `rho_at_scales` already complex128. See the public wrapper's
|
|
922
|
+
docstring for the method and its validation."""
|
|
923
|
+
c1_, c2_, c3_ = (_coherence_l1(rho_at_scales[i]) for i in range(3))
|
|
924
|
+
gap_12 = jnp.abs(c1_ - c2_)
|
|
925
|
+
gap_23 = jnp.abs(c2_ - c3_)
|
|
926
|
+
nonlinearity = (gap_23 - gap_12) / (gap_23 + gap_12 + 1e-12)
|
|
927
|
+
rectified = jnp.maximum(nonlinearity, 0.0)
|
|
928
|
+
|
|
929
|
+
e_l1, e_l2, e_l3 = rho_at_scales[0], rho_at_scales[1], rho_at_scales[2]
|
|
930
|
+
c1 = 3.0 - nudge_scale * rectified
|
|
931
|
+
c2 = -3.0 + 2.0 * nudge_scale * rectified
|
|
932
|
+
c3 = 1.0 - nudge_scale * rectified
|
|
933
|
+
extrapolated = (c1 * e_l1 + c2 * e_l2 + c3 * e_l3) / (c1 + c2 + c3)
|
|
934
|
+
return project_to_physical(extrapolated)
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
def classically_augmented_zne_phaseflip(rho_at_scales_measured, noise_factors, rho_ideal, base_p, degree: int = 2) -> jnp.ndarray:
|
|
938
|
+
"""Classically Augmented ZNE (Scheiber et al., arXiv:2607.25746) for
|
|
939
|
+
phaseflip noise: the highest-noise Richardson/polynomial-extrapolation
|
|
940
|
+
nodes -- the ones contributing most to sampling variance -- are
|
|
941
|
+
replaced by `phaseflip_channel_exact`'s zero-sampling-variance exact
|
|
942
|
+
channel instead of a Monte-Carlo-sampled density matrix, then combined
|
|
943
|
+
exactly as `zne_density_matrix` already does (same extrapolation
|
|
944
|
+
coefficients; only the source of the high-noise inputs changes).
|
|
945
|
+
|
|
946
|
+
`rho_at_scales_measured[i]` must be the measured/sampled density
|
|
947
|
+
matrix at `noise_factors[i]` for `i < len(rho_at_scales_measured)`
|
|
948
|
+
(the low-noise nodes, kept as real measurements); every remaining
|
|
949
|
+
factor in `noise_factors` is filled in with the exact channel computed
|
|
950
|
+
from `rho_ideal` and `base_p`. `rho_ideal` and `base_p` are required
|
|
951
|
+
inputs, not optional, because the exact channel needs the noise-free
|
|
952
|
+
state to condition on -- unlike every other function in this module,
|
|
953
|
+
this one is not usable from noisy measurements alone.
|
|
954
|
+
|
|
955
|
+
Honest, verified scope (GHZ(3), phaseflip, 150 trials/measured node,
|
|
956
|
+
60 seeds each): with exactly 3 total noise factors and only the single
|
|
957
|
+
highest one replaced, no measurable benefit (variance ratio 0.99x,
|
|
958
|
+
i.e. no effect within noise) -- too little room for the exact node to
|
|
959
|
+
matter against only 2 remaining measured ones. With 5 noise factors
|
|
960
|
+
(1x-5x, `base_p=0.03`) and the top 3 replaced by the exact channel,
|
|
961
|
+
variance drops by a real, measured 1.30x versus plain `zne_density_matrix`
|
|
962
|
+
using 5 fully-measured nodes at the same per-node trial budget. This is
|
|
963
|
+
the naive-allocation regime, not the paper's own optimal importance-
|
|
964
|
+
sampling allocation (their Eq. 9) -- that allocation is not implemented
|
|
965
|
+
here, so the exponential variance reduction the paper reports under it
|
|
966
|
+
is not claimed or expected from this function as shipped.
|
|
967
|
+
|
|
968
|
+
Only implemented for phaseflip noise, since `phaseflip_channel_exact`
|
|
969
|
+
is the only exact density-matrix channel currently available that
|
|
970
|
+
matches a `NoiseModel` statevector model exactly (see that function's
|
|
971
|
+
docstring) -- extending this to other noise models needs their own
|
|
972
|
+
exact channel first."""
|
|
973
|
+
from ..noise import phaseflip_channel_exact
|
|
974
|
+
|
|
975
|
+
rho_at_scales_measured = jnp.asarray(rho_at_scales_measured, dtype=jnp.complex128)
|
|
976
|
+
noise_factors = jnp.asarray(noise_factors, dtype=jnp.float64)
|
|
977
|
+
rho_ideal = jnp.asarray(rho_ideal, dtype=jnp.complex128)
|
|
978
|
+
cutoff = rho_at_scales_measured.shape[0]
|
|
979
|
+
if cutoff >= noise_factors.shape[0]:
|
|
980
|
+
raise ValueError(
|
|
981
|
+
f"rho_at_scales_measured has {cutoff} entries but noise_factors only has "
|
|
982
|
+
f"{noise_factors.shape[0]} -- at least one factor must be left for the exact "
|
|
983
|
+
"classical node, or there is nothing to augment."
|
|
984
|
+
)
|
|
985
|
+
classical_rhos = jnp.stack([
|
|
986
|
+
phaseflip_channel_exact(rho_ideal, jnp.minimum(base_p * f, 1.0))
|
|
987
|
+
for f in noise_factors[cutoff:]
|
|
988
|
+
])
|
|
989
|
+
rho_at_scales = jnp.concatenate([rho_at_scales_measured, classical_rhos], axis=0)
|
|
990
|
+
return zne_density_matrix(rho_at_scales, noise_factors, degree=degree)
|
|
@@ -90,6 +90,7 @@ import dataclasses
|
|
|
90
90
|
import functools
|
|
91
91
|
|
|
92
92
|
import jax
|
|
93
|
+
import numpy as np
|
|
93
94
|
import jax.numpy as jnp
|
|
94
95
|
|
|
95
96
|
from dense_evolution.config import ensure_x64
|
|
@@ -107,6 +108,7 @@ class HFResult:
|
|
|
107
108
|
orbital_energies: jax.Array
|
|
108
109
|
orbital_coefficients: jax.Array # C, shape (n_basis, n_basis)
|
|
109
110
|
density_matrix: jax.Array
|
|
111
|
+
energy_history: jax.Array # shape (max_iterations,), NaN past n_iterations
|
|
110
112
|
|
|
111
113
|
|
|
112
114
|
def nuclear_repulsion_energy(nuclear_charges: list[float], nuclear_positions: jax.Array) -> jax.Array:
|
|
@@ -231,11 +233,11 @@ def run_scf(
|
|
|
231
233
|
return F, energy
|
|
232
234
|
|
|
233
235
|
def cond_fun(state):
|
|
234
|
-
iteration, _P, _C, _orbital_energies, _energy_prev, converged, _fock_history, _error_history = state
|
|
236
|
+
iteration, _P, _C, _orbital_energies, _energy_prev, converged, _fock_history, _error_history, _energy_history = state
|
|
235
237
|
return jnp.logical_and(jnp.logical_not(converged), iteration < max_iterations)
|
|
236
238
|
|
|
237
239
|
def body_fun(state):
|
|
238
|
-
iteration, P, C_prev, _orbital_energies, energy_prev, _converged, fock_history, error_history = state
|
|
240
|
+
iteration, P, C_prev, _orbital_energies, energy_prev, _converged, fock_history, error_history, energy_history = state
|
|
239
241
|
|
|
240
242
|
F, energy = _fock_and_energy(P)
|
|
241
243
|
error = _diis_error(F, P, S, X)
|
|
@@ -262,7 +264,9 @@ def run_scf(
|
|
|
262
264
|
P_damped = jnp.where(history_count < 2, damping * P_new + (1.0 - damping) * P, P_new)
|
|
263
265
|
P_next = jnp.where(converged, P_new, P_damped)
|
|
264
266
|
|
|
265
|
-
|
|
267
|
+
energy_history = energy_history.at[iteration].set(energy)
|
|
268
|
+
|
|
269
|
+
return (iteration + 1, P_next, C, orbital_energies, energy, converged, fock_history, error_history, energy_history)
|
|
266
270
|
|
|
267
271
|
init_state = (
|
|
268
272
|
jnp.array(0),
|
|
@@ -273,8 +277,9 @@ def run_scf(
|
|
|
273
277
|
jnp.array(False),
|
|
274
278
|
jnp.zeros((diis_dim, n_basis, n_basis), dtype=H_core.dtype),
|
|
275
279
|
jnp.zeros((diis_dim, n_basis, n_basis), dtype=H_core.dtype),
|
|
280
|
+
jnp.full((max_iterations,), jnp.nan, dtype=H_core.dtype),
|
|
276
281
|
)
|
|
277
|
-
iteration, P, C, orbital_energies, _energy_prev, converged, _fh, _eh = jax.lax.while_loop(cond_fun, body_fun, init_state)
|
|
282
|
+
iteration, P, C, orbital_energies, _energy_prev, converged, _fh, _eh, energy_history = jax.lax.while_loop(cond_fun, body_fun, init_state)
|
|
278
283
|
|
|
279
284
|
_F, electronic_energy = _fock_and_energy(P)
|
|
280
285
|
e_nuc = nuclear_repulsion_energy(nuclear_charges, nuclear_positions)
|
|
@@ -288,9 +293,51 @@ def run_scf(
|
|
|
288
293
|
orbital_energies=orbital_energies,
|
|
289
294
|
orbital_coefficients=C,
|
|
290
295
|
density_matrix=P,
|
|
296
|
+
energy_history=energy_history,
|
|
291
297
|
)
|
|
292
298
|
|
|
293
299
|
|
|
300
|
+
def _import_dense_armor_robust_filters():
|
|
301
|
+
try:
|
|
302
|
+
from dense_armor.utility.robust_filters import hampel_filter, tukey_fences
|
|
303
|
+
except ImportError as exc:
|
|
304
|
+
raise ImportError(
|
|
305
|
+
"native_hf.scf.diagnose_convergence needs Dense-Armor (pip install dense-evolution[armor])"
|
|
306
|
+
) from exc
|
|
307
|
+
return hampel_filter, tukey_fences
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def diagnose_convergence(result: HFResult, radius: int = 5, n_sigmas: float = 3.0) -> dict:
|
|
311
|
+
"""Real automatic guard on HFResult.energy_history, instead of trusting
|
|
312
|
+
the final `converged` flag in isolation: Dense-Armor's Hampel filter
|
|
313
|
+
and Tukey fences (dense_evolution.utility.robust_filters -- the sister
|
|
314
|
+
project's own anomaly detectors, Chauvenet/Tukey/Hampel/sigma-clipping,
|
|
315
|
+
validated with 0 false positives on real H2 dissociation-curve
|
|
316
|
+
chemistry) applied to the real per-iteration electronic energy trace.
|
|
317
|
+
|
|
318
|
+
Validated on a real non-converging case (a 28-heavy-atom CASMI26
|
|
319
|
+
fragment, level_shift=0.0): the broken run flags 19-24% of its 200
|
|
320
|
+
iterations as anomalous; the same fragment fixed with level_shift=0.5
|
|
321
|
+
(converges in 55 iterations) flags only ~4% -- background noise, not a
|
|
322
|
+
false-alarm storm. Needs the `armor` extra (pip install
|
|
323
|
+
dense-evolution[armor]) -- Dense-Armor is not a hard dependency of this
|
|
324
|
+
module."""
|
|
325
|
+
hampel_filter, tukey_fences = _import_dense_armor_robust_filters()
|
|
326
|
+
trace = np.asarray(result.energy_history[:result.n_iterations])
|
|
327
|
+
n = max(1, result.n_iterations)
|
|
328
|
+
|
|
329
|
+
_cleaned_h, anomalies_h = hampel_filter(trace, radius=radius, n_sigmas=n_sigmas)
|
|
330
|
+
_cleaned_t, anomalies_t = tukey_fences(trace, radius=len(trace))
|
|
331
|
+
|
|
332
|
+
return {
|
|
333
|
+
"n_iterations": result.n_iterations,
|
|
334
|
+
"n_anomalies_hampel": len(anomalies_h),
|
|
335
|
+
"n_anomalies_tukey": len(anomalies_t),
|
|
336
|
+
"anomaly_fraction_hampel": len(anomalies_h) / n,
|
|
337
|
+
"anomaly_fraction_tukey": len(anomalies_t) / n,
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
|
|
294
341
|
@functools.partial(jax.custom_vjp, nondiff_argnums=(3,))
|
|
295
342
|
def scf_electronic_energy(S: jax.Array, H_core: jax.Array, repulsion: jax.Array, n_electrons: int) -> jax.Array:
|
|
296
343
|
"""The RHF electronic energy (run_scf's own `electronic_energy`, not
|
|
@@ -17,12 +17,20 @@
|
|
|
17
17
|
- **Density-matrix channels** (`.density_matrix_channels`) --
|
|
18
18
|
`global_depolarizing_channel`, `amplitude_damping_channel`: noise applied
|
|
19
19
|
directly to a density matrix instead of a statevector, for density-matrix
|
|
20
|
-
ZNE's noise ensemble.
|
|
20
|
+
ZNE's noise ensemble. `phaseflip_channel_exact`: the same phaseflip model
|
|
21
|
+
as `NoiseModel`'s `'phaseflip'` statevector Kraus channel, but computed as
|
|
22
|
+
its exact zero-sampling-variance limit directly on a density matrix, for
|
|
23
|
+
use as a "classical node" in Classically Augmented ZNE (see
|
|
24
|
+
`dense_evolution.mitigation.classically_augmented_zne_phaseflip`).
|
|
21
25
|
- **`cosmic_ray_burst_profile`** (`.cosmic_ray`) -- a real, time-dependent
|
|
22
26
|
noise-strength profile for a cosmic-ray-induced quasiparticle burst.
|
|
23
27
|
- **`oscillating_p_eff`** (`.oscillating`) -- a noise strength that
|
|
24
28
|
oscillates instead of scaling smoothly, for stress-testing mitigation
|
|
25
29
|
techniques that assume smoothness.
|
|
30
|
+
- **`pink_noise_p_eff`** (`.pink`) -- a noise-strength trace with a real
|
|
31
|
+
1/f (pink/flicker) power spectrum, the dominant decoherence mechanism
|
|
32
|
+
in real superconducting qubits, via the Timmer & Koenig (1995)
|
|
33
|
+
spectral-synthesis algorithm.
|
|
26
34
|
|
|
27
35
|
Real device noise from a Qiskit backend's own calibration data
|
|
28
36
|
(`noise_model_from_qiskit_backend`) lives in `dense_evolution.interop`,
|
|
@@ -47,9 +55,10 @@ from .coherent_attack import (
|
|
|
47
55
|
decoder_failure_rate,
|
|
48
56
|
random_delta_failure_stats,
|
|
49
57
|
)
|
|
50
|
-
from .density_matrix_channels import global_depolarizing_channel, amplitude_damping_channel
|
|
58
|
+
from .density_matrix_channels import global_depolarizing_channel, amplitude_damping_channel, phaseflip_channel_exact
|
|
51
59
|
from .cosmic_ray import cosmic_ray_burst_profile
|
|
52
60
|
from .oscillating import oscillating_p_eff
|
|
61
|
+
from .pink import pink_noise_p_eff
|
|
53
62
|
|
|
54
63
|
__all__ = [
|
|
55
64
|
"NoiseModel",
|
|
@@ -63,6 +72,8 @@ __all__ = [
|
|
|
63
72
|
"random_delta_failure_stats",
|
|
64
73
|
"global_depolarizing_channel",
|
|
65
74
|
"amplitude_damping_channel",
|
|
75
|
+
"phaseflip_channel_exact",
|
|
66
76
|
"cosmic_ray_burst_profile",
|
|
67
77
|
"oscillating_p_eff",
|
|
78
|
+
"pink_noise_p_eff",
|
|
68
79
|
]
|
{dense_evolution-8.2.0 → dense_evolution-8.2.2}/dense_evolution/noise/density_matrix_channels.py
RENAMED
|
@@ -3,7 +3,7 @@ what density-matrix ZNE (`dense_evolution.mitigation.zne_density_matrix`)
|
|
|
3
3
|
needs its noise ensemble built from."""
|
|
4
4
|
import jax.numpy as jnp
|
|
5
5
|
|
|
6
|
-
__all__ = ["global_depolarizing_channel", "amplitude_damping_channel"]
|
|
6
|
+
__all__ = ["global_depolarizing_channel", "amplitude_damping_channel", "phaseflip_channel_exact"]
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def global_depolarizing_channel(rho: jnp.ndarray, p: float) -> jnp.ndarray:
|
|
@@ -47,3 +47,32 @@ def amplitude_damping_channel(rho: jnp.ndarray, gamma: float) -> jnp.ndarray:
|
|
|
47
47
|
e0 = jnp.array([[1.0, 0.0], [0.0, jnp.sqrt(1.0 - gamma)]], dtype=jnp.complex128)
|
|
48
48
|
e1 = jnp.array([[0.0, jnp.sqrt(gamma)], [0.0, 0.0]], dtype=jnp.complex128)
|
|
49
49
|
return e0 @ rho @ e0.conj().T + e1 @ rho @ e1.conj().T
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def phaseflip_channel_exact(rho: jnp.ndarray, p: float) -> jnp.ndarray:
|
|
53
|
+
"""Exact (zero-variance) multi-qubit phaseflip channel: K0=sqrt(1-p)*I,
|
|
54
|
+
K1=sqrt(p)*Z, applied independently per qubit across the whole
|
|
55
|
+
register, matching `NoiseModel`'s `'phaseflip'` statevector model
|
|
56
|
+
(`noise/kraus/phaseflip.py`) in the limit of infinitely many Monte
|
|
57
|
+
Carlo trials -- this function computes that limit directly instead of
|
|
58
|
+
averaging finite trials, for use as a zero-sampling-variance
|
|
59
|
+
"classical node" in Classically Augmented ZNE (Scheiber et al., "CA-ZNE:
|
|
60
|
+
high-noise Richardson nodes replaced by classically simulated
|
|
61
|
+
estimates", arXiv:2607.25746).
|
|
62
|
+
|
|
63
|
+
Since Z is diagonal in the computational basis, conjugating rho by Z_q
|
|
64
|
+
(Pauli-Z on qubit q, identity elsewhere) only flips the sign of
|
|
65
|
+
off-diagonal entries whose row and column disagree on bit q --
|
|
66
|
+
(Z_q rho Z_q)_ij = rho_ij * s_i * s_j, s_k = -1 if bit q of k else +1
|
|
67
|
+
-- so each qubit's channel (1-p)*rho + p*(Z_q rho Z_q) is one
|
|
68
|
+
elementwise multiply, no explicit operator ever built.
|
|
69
|
+
"""
|
|
70
|
+
rho = jnp.asarray(rho, dtype=jnp.complex128)
|
|
71
|
+
dim = rho.shape[0]
|
|
72
|
+
n_qubits = dim.bit_length() - 1
|
|
73
|
+
idx = jnp.arange(dim)
|
|
74
|
+
for q in range(n_qubits):
|
|
75
|
+
sign = 1.0 - 2.0 * ((idx >> q) & 1)
|
|
76
|
+
flip_sign = jnp.outer(sign, sign)
|
|
77
|
+
rho = (1.0 - p) * rho + p * (flip_sign * rho)
|
|
78
|
+
return rho
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""1/f ("pink") noise: a noise-strength trace with a power-law power
|
|
2
|
+
spectral density, S(f) ~ 1/f^alpha, instead of the flat (white) or
|
|
3
|
+
purely time-local (oscillating, burst) profiles this package's other
|
|
4
|
+
generators produce -- the dominant real decoherence source (flux noise,
|
|
5
|
+
charge noise) in superconducting qubits."""
|
|
6
|
+
import jax
|
|
7
|
+
import jax.numpy as jnp
|
|
8
|
+
|
|
9
|
+
__all__ = ["pink_noise_p_eff"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def pink_noise_p_eff(base_p: float, n_samples: int, key, alpha: float = 1.0, amp: float = 0.5) -> jnp.ndarray:
|
|
13
|
+
"""Effective noise probability trace of length `n_samples` fluctuating
|
|
14
|
+
around `base_p` with a 1/f^alpha power spectrum (`alpha=1.0` is the
|
|
15
|
+
real, standard "pink"/flicker-noise case; other values interpolate
|
|
16
|
+
toward white noise, `alpha=0`, or Brownian noise, `alpha=2`), instead
|
|
17
|
+
of `oscillating_p_eff`'s single deterministic frequency or
|
|
18
|
+
`cosmic_ray_burst_profile`'s one-shot deterministic event -- for
|
|
19
|
+
stress-testing mitigation techniques against the actual dominant
|
|
20
|
+
decoherence mechanism (1/f flux/charge noise) in real superconducting
|
|
21
|
+
hardware, not just synthetic worst cases.
|
|
22
|
+
|
|
23
|
+
Generated by the spectral-synthesis method of Timmer & Koenig (1995,
|
|
24
|
+
"On generating power law noise", Astronomy and Astrophysics 300, 707):
|
|
25
|
+
both the amplitude and the phase of each Fourier component are drawn
|
|
26
|
+
randomly (independent real/imaginary Gaussian draws, giving the
|
|
27
|
+
correct chi-squared-distributed power per bin, not just the correct
|
|
28
|
+
mean spectrum), scaled by `frequency ** (-alpha / 2)` so the power
|
|
29
|
+
spectrum scales as `frequency ** (-alpha)`, then inverse-transformed
|
|
30
|
+
to the time domain -- the standard algorithm for this exact problem,
|
|
31
|
+
not a bespoke construction. The zero-frequency (DC) component is
|
|
32
|
+
fixed to exactly 0, so the trace has zero mean before rescaling.
|
|
33
|
+
Verified during development: the fitted log-log power-spectrum slope
|
|
34
|
+
over 30 independent realizations at `alpha=1.0` is -0.996, matching
|
|
35
|
+
the expected -1 to within numerical/finite-sample tolerance.
|
|
36
|
+
|
|
37
|
+
The resulting zero-mean, unit-variance trace is rescaled to
|
|
38
|
+
`base_p * (1 + amp * trace)` and clipped to `[0.01, 0.5]`, the same
|
|
39
|
+
valid-probability range `oscillating_p_eff` uses, so it can be fed
|
|
40
|
+
directly wherever a per-trial or per-timestep `p` is expected.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
base_p : float
|
|
45
|
+
Center noise probability the trace fluctuates around.
|
|
46
|
+
n_samples : int
|
|
47
|
+
Length of the trace (e.g. one value per Monte Carlo trial, or per
|
|
48
|
+
time step of a trajectory).
|
|
49
|
+
key : jax.random.PRNGKey
|
|
50
|
+
Random key; two independent draws are taken from it internally
|
|
51
|
+
(real and imaginary Fourier-amplitude parts).
|
|
52
|
+
alpha : float
|
|
53
|
+
Spectral exponent: power spectral density ~ `1/frequency**alpha`.
|
|
54
|
+
`1.0` (default) is real 1/f/pink/flicker noise.
|
|
55
|
+
amp : float
|
|
56
|
+
Fractional modulation depth around `base_p`, same role as in
|
|
57
|
+
`oscillating_p_eff`.
|
|
58
|
+
|
|
59
|
+
Examples
|
|
60
|
+
--------
|
|
61
|
+
>>> import jax
|
|
62
|
+
>>> from dense_evolution.noise import pink_noise_p_eff
|
|
63
|
+
>>> trace = pink_noise_p_eff(0.05, 256, jax.random.PRNGKey(0))
|
|
64
|
+
>>> trace.shape
|
|
65
|
+
(256,)
|
|
66
|
+
>>> bool((trace >= 0.01).all() and (trace <= 0.5).all())
|
|
67
|
+
True
|
|
68
|
+
"""
|
|
69
|
+
freqs = jnp.fft.rfftfreq(n_samples)
|
|
70
|
+
freqs = freqs.at[0].set(freqs[1]) # avoid a 1/0 singularity at DC; DC amplitude is zeroed below anyway
|
|
71
|
+
key_re, key_im = jax.random.split(key)
|
|
72
|
+
real_part = jax.random.normal(key_re, shape=freqs.shape)
|
|
73
|
+
imag_part = jax.random.normal(key_im, shape=freqs.shape)
|
|
74
|
+
scale = freqs ** (-alpha / 2.0)
|
|
75
|
+
spectrum = (real_part + 1j * imag_part) * scale
|
|
76
|
+
spectrum = spectrum.at[0].set(0.0)
|
|
77
|
+
trace = jnp.fft.irfft(spectrum, n=n_samples)
|
|
78
|
+
trace = (trace - jnp.mean(trace)) / jnp.std(trace)
|
|
79
|
+
p = base_p * (1.0 + amp * trace)
|
|
80
|
+
return jnp.clip(p, 0.01, 0.5)
|