dense-evolution 8.3.0__tar.gz → 8.3.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.
Files changed (174) hide show
  1. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/PKG-INFO +13 -6
  2. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/README.md +10 -5
  3. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/__init__.py +20 -3
  4. dense_evolution-8.3.2/dense_evolution/circuits/__init__.py +37 -0
  5. dense_evolution-8.3.2/dense_evolution/circuits/arithmetic.py +241 -0
  6. dense_evolution-8.3.2/dense_evolution/circuits/arithmetic_qasm.py +227 -0
  7. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/parser.py +69 -6
  8. dense_evolution-8.3.2/dense_evolution/circuits/postselect.py +59 -0
  9. dense_evolution-8.3.2/dense_evolution/circuits/shor.py +70 -0
  10. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/config.py +13 -0
  11. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/__init__.py +4 -4
  12. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/kl_divergence.py +3 -1
  13. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/magic_entropy.py +3 -1
  14. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/magic_entropy_shadows.py +5 -0
  15. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/renyi.py +3 -1
  16. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/stabilizer_renyi_entropy.py +3 -1
  17. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/zne.py +123 -7
  18. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/basis.py +12 -1
  19. dense_evolution-8.3.2/dense_evolution/native_hf/scf.py +870 -0
  20. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution.egg-info/PKG-INFO +13 -6
  21. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution.egg-info/SOURCES.txt +4 -0
  22. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution.egg-info/requires.txt +3 -0
  23. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/pyproject.toml +4 -1
  24. dense_evolution-8.3.0/dense_evolution/circuits/__init__.py +0 -20
  25. dense_evolution-8.3.0/dense_evolution/native_hf/scf.py +0 -404
  26. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/autodiff.py +0 -0
  27. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/__init__.py +0 -0
  28. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/__init__.py +0 -0
  29. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/_engine_imports.py +0 -0
  30. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/circuit_chunker.py +0 -0
  31. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/core.py +0 -0
  32. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/disk_overflow.py +0 -0
  33. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/geometry.py +0 -0
  34. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/guard.py +0 -0
  35. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/chunk/kernels.py +0 -0
  36. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/mps.py +0 -0
  37. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/backends/statevector.py +0 -0
  38. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/chunk.py +0 -0
  39. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/compiler.py +0 -0
  40. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/diagram.py +0 -0
  41. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/gates.py +0 -0
  42. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/qft.py +0 -0
  43. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/random_circuit.py +0 -0
  44. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/registry.py +0 -0
  45. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/topology.py +0 -0
  46. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/trotter.py +0 -0
  47. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/circuits/uccsd.py +0 -0
  48. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/cli.py +0 -0
  49. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/compiler.py +0 -0
  50. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/drawing.py +0 -0
  51. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/entropy.py +0 -0
  52. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/fermions.py +0 -0
  53. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/gates.py +0 -0
  54. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/harrison_tb.py +0 -0
  55. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/healing.py +0 -0
  56. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/interop/__init__.py +0 -0
  57. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/interop/qiskit_pennylane.py +0 -0
  58. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/measurement.py +0 -0
  59. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mitigation/healing.py +0 -0
  60. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/mps.py +0 -0
  61. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/__init__.py +0 -0
  62. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/assembly.py +0 -0
  63. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/boys.py +0 -0
  64. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/bridge.py +0 -0
  65. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/cartesian.py +0 -0
  66. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/coulomb.py +0 -0
  67. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/differentiable.py +0 -0
  68. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/gaussians.py +0 -0
  69. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/kinetic.py +0 -0
  70. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/libcint_bridge.py +0 -0
  71. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/native_hf/overlap.py +0 -0
  72. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/__init__.py +0 -0
  73. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/coherent_attack.py +0 -0
  74. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/cosmic_ray.py +0 -0
  75. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/density_matrix_channels.py +0 -0
  76. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/differentiable.py +0 -0
  77. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus/__init__.py +0 -0
  78. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus/amplitude_damping.py +0 -0
  79. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus/bitflip.py +0 -0
  80. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus/combined.py +0 -0
  81. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus/depolarizing.py +0 -0
  82. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus/ideal.py +0 -0
  83. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus/phaseflip.py +0 -0
  84. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/kraus_channels.py +0 -0
  85. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/oscillating.py +0 -0
  86. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/noise/pink.py +0 -0
  87. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/observables.py +0 -0
  88. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/parser.py +0 -0
  89. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/physics/__init__.py +0 -0
  90. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/physics/entropy.py +0 -0
  91. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/physics/fermions.py +0 -0
  92. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/physics/observables.py +0 -0
  93. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/physics/qec.py +0 -0
  94. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/physics/spectral.py +0 -0
  95. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/physics/states.py +0 -0
  96. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/protocols/__init__.py +0 -0
  97. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/protocols/bb84.py +0 -0
  98. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/protocols/di_qkd_ghz.py +0 -0
  99. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/protocols/dicka_protocol2.py +0 -0
  100. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/qec.py +0 -0
  101. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/qft.py +0 -0
  102. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/qmmm/__init__.py +0 -0
  103. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/qmmm/ase_bridge.py +0 -0
  104. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/qmmm/forces.py +0 -0
  105. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/qmmm/propagation.py +0 -0
  106. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/qmmm/region.py +0 -0
  107. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/random_circuit.py +0 -0
  108. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/registry.py +0 -0
  109. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/simulator.py +0 -0
  110. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/solvers/__init__.py +0 -0
  111. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/solvers/autodiff.py +0 -0
  112. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/solvers/harrison_tb.py +0 -0
  113. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/solvers/vhd_tb.py +0 -0
  114. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/states.py +0 -0
  115. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/topology.py +0 -0
  116. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/trotter.py +0 -0
  117. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/utils/__init__.py +0 -0
  118. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/utils/drawing.py +0 -0
  119. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/utils/mass_decomposition.py +0 -0
  120. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/utils/measurement.py +0 -0
  121. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution/vhd_tb.py +0 -0
  122. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution.egg-info/dependency_links.txt +0 -0
  123. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution.egg-info/entry_points.txt +0 -0
  124. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/dense_evolution.egg-info/top_level.txt +0 -0
  125. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/license.md +0 -0
  126. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/research/local_site/__init__.py +0 -0
  127. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/research/local_site/app/__init__.py +0 -0
  128. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/research/local_site/app/server.py +0 -0
  129. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/setup.cfg +0 -0
  130. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/__init__.py +0 -0
  131. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/_gate_tables.py +0 -0
  132. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/band_structure.py +0 -0
  133. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/circuit_builder_component.py +0 -0
  134. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/circuit_diagram.py +0 -0
  135. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/crypto_protocols.py +0 -0
  136. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/engine.py +0 -0
  137. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/graphical_builder.py +0 -0
  138. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/hamiltonians.py +0 -0
  139. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/mass_decomposition_tool.py +0 -0
  140. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/mitigation.py +0 -0
  141. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/native_hf_diagnostics.py +0 -0
  142. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/noise_tools.py +0 -0
  143. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/qasm_library.py +0 -0
  144. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/qmmm.py +0 -0
  145. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/rag_tool.py +0 -0
  146. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/state_visuals.py +0 -0
  147. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/system_limits.py +0 -0
  148. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/vector_healing.py +0 -0
  149. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/visuals.py +0 -0
  150. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/vqe.py +0 -0
  151. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/dashboard/core/wormhole.py +0 -0
  152. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/ia_utils/__init__.py +0 -0
  153. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/ia_utils/adversarial_vector_attack.py +0 -0
  154. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/ia_utils/rag.py +0 -0
  155. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/ia_utils/vector_healing.py +0 -0
  156. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/__init__.py +0 -0
  157. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/client.py +0 -0
  158. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/config.py +0 -0
  159. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/models.py +0 -0
  160. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/molecules.py +0 -0
  161. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/server.py +0 -0
  162. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/__init__.py +0 -0
  163. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/chemistry_tools.py +0 -0
  164. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/circuit_tools.py +0 -0
  165. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/crypto_tools.py +0 -0
  166. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/mitigation_tools.py +0 -0
  167. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/noise_tools.py +0 -0
  168. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/retrieval_tools.py +0 -0
  169. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/system_tools.py +0 -0
  170. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/tools/wormhole_tools.py +0 -0
  171. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/utils/__init__.py +0 -0
  172. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/utils/cache.py +0 -0
  173. {dense_evolution-8.3.0 → dense_evolution-8.3.2}/tools/mcp_server/utils/images.py +0 -0
  174. {dense_evolution-8.3.0 → dense_evolution-8.3.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.3.0
3
+ Version: 8.3.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
@@ -46,6 +46,8 @@ Requires-Dist: qiskit>=1.0.0; extra == "qiskit"
46
46
  Provides-Extra: pennylane
47
47
  Requires-Dist: pennylane>=0.35.0; extra == "pennylane"
48
48
  Requires-Dist: basis_set_exchange>=0.9; extra == "pennylane"
49
+ Provides-Extra: hf
50
+ Requires-Dist: basis_set_exchange>=0.9; extra == "hf"
49
51
  Provides-Extra: stim
50
52
  Requires-Dist: stim>=1.13.0; extra == "stim"
51
53
  Provides-Extra: pymatching
@@ -99,7 +101,7 @@ Requires-Dist: rdkit>=2023.9.1; extra == "docs"
99
101
  Dynamic: license-file
100
102
 
101
103
  <p align="center">
102
- <img src="docs/assets/banner.svg" alt="Dense Evolution — NISQ quantum simulation toolkit, JAX-native" width="900">
104
+ <img src="docs/assets/banner.png" alt="Dense Evolution — NISQ quantum simulation toolkit, JAX-native" width="900">
103
105
  </p>
104
106
 
105
107
 
@@ -111,8 +113,8 @@ Statevector/MPS engines with compilation, noise, VQE, QEC, chemistry, and agent-
111
113
  <p align="center">
112
114
  <img src="docs/assets/favicon.svg" width="32" alt=""><br>
113
115
  <b>Download the Dense Evolution Dashboard (Streamlit)</b><br>
114
- <a href="https://github.com/tatopenn-cell/Dense-Evolution/raw/main/tools/installer/install-dashboard.bat">Windows (.bat)</a> &middot;
115
- <a href="https://github.com/tatopenn-cell/Dense-Evolution/raw/main/tools/installer/install-dashboard.sh">macOS / Linux (.sh)</a>
116
+ <a href="https://tatopenn-cell.github.io/Dense-Evolution/assets/installer/install-dashboard.bat">Windows (.bat)</a> &middot;
117
+ <a href="https://tatopenn-cell.github.io/Dense-Evolution/assets/installer/install-dashboard.sh">macOS / Linux (.sh)</a>
116
118
  </p>
117
119
 
118
120
  [![CI](https://github.com/tatopenn-cell/Dense-Evolution/actions/workflows/ci.yml/badge.svg)](https://github.com/tatopenn-cell/Dense-Evolution/actions/workflows/ci.yml)
@@ -165,6 +167,9 @@ pip install dense-evolution[full]
165
167
  pip install dense-evolution[qiskit]
166
168
  pip install dense-evolution[pennylane]
167
169
 
170
+ # native Hartree-Fock (basis-set data)
171
+ pip install dense-evolution[hf]
172
+
168
173
  # Composer's local kernel (see "Composer" below)
169
174
  pip install dense-evolution[composer]
170
175
 
@@ -300,9 +305,11 @@ sim.run_chunk(circuit.to_tuples(), chunk_size_gates=500)
300
305
 
301
306
  - **JIT-fused statevector engine.** No Kronecker-product overhead — stride-sliced linear kernel fusion compiled through JAX XLA, real GPU/TPU dispatch with no code change. [Simulator](https://tatopenn-cell.github.io/Dense-Evolution/api/simulator/) · [MPS backend](https://tatopenn-cell.github.io/Dense-Evolution/api/mps/) for low-entanglement circuits at scale.
302
307
  - **Anti-OOM `Chunk` engine.** Circuits too large for one array, split dynamically and sized off the real compute device's own free memory — with disk-backed overflow past even that ceiling. [Chunk guide](https://tatopenn-cell.github.io/Dense-Evolution/api/chunk/).
303
- - **Real noise, real mitigation.** Stochastic Kraus channels, real-device noise imported from Qiskit backends, and Zero-Noise Extrapolation to correct for it. [Noise](https://tatopenn-cell.github.io/Dense-Evolution/api/noise/) · [Mitigation](https://tatopenn-cell.github.io/Dense-Evolution/api/mitigation/) · [what noise/mitigation/healing each mean](https://tatopenn-cell.github.io/Dense-Evolution/concepts/).
308
+ - **Real noise, real mitigation.** Stochastic Kraus channels, real-device noise imported from Qiskit backends, and Zero-Noise Extrapolation, with the shot budget split optimally across noise factors and a single-qubit Bloch-vector variant that always returns a valid state, to correct for it. [Noise](https://tatopenn-cell.github.io/Dense-Evolution/api/noise/) · [Mitigation](https://tatopenn-cell.github.io/Dense-Evolution/api/mitigation/) · [what noise/mitigation/healing each mean](https://tatopenn-cell.github.io/Dense-Evolution/concepts/).
304
309
  - **Differentiable VQE, from scratch.** `circuit_to_energy_fn` is the same JAX-differentiable engine real molecular VQE runs on — real Hartree-Fock Hamiltonians, UCCSD/hardware-efficient ansätze, Adam optimization. [Autodiff](https://tatopenn-cell.github.io/Dense-Evolution/api/autodiff/).
305
- - **libcint integrals on Windows, macOS and Linux.** `pip install dense-evolution` ships libcint compiled for each system: the full two-electron tensor of ethanol in 6-31G* in 0.32 s. [native_hf](https://tatopenn-cell.github.io/Dense-Evolution/api/native_hf/).
310
+ - **libcint integrals on Windows, macOS and Linux.** `pip install dense-evolution` ships libcint compiled for each system: the full two-electron tensor of ethanol in 6-31G* in 0.32 s. Open-shell molecules with UHF and ROHF (`run_uhf`, `run_cuhf`). [native_hf](https://tatopenn-cell.github.io/Dense-Evolution/api/native_hf/).
311
+ - **Reversible arithmetic.** Register adders, subtraction, comparisons and modular arithmetic up to modular exponentiation, applied as exact basis permutations, and as OPENQASM 2.0 gate circuits (Cuccaro, Draper and Beauregard adders, controlled modular multiplication), up to Shor order finding with one control qubit. [Arithmetic](https://tatopenn-cell.github.io/Dense-Evolution/api/arithmetic/).
312
+ - **Postselection.** Keep the branch where a qubit is found in `|0>`, `|1>`, `|±>` or `|±i>`, with its probability. [Postselection](https://tatopenn-cell.github.io/Dense-Evolution/api/postselect/).
306
313
  - **OpenQASM 2.0/3.0, both directions.** A real parser, plus Qiskit/PennyLane interop bridges. [QASM Parser](https://tatopenn-cell.github.io/Dense-Evolution/api/parser/) · [Interop](https://tatopenn-cell.github.io/Dense-Evolution/api/interop/).
307
314
  - **Code-agnostic QEC decoding**, Majorana/Jordan-Wigner fermion mapping, from-scratch Hartree-Fock for elements outside PennyLane's own basis set, a traversable-wormhole-inspired teleportation protocol, and real QM/MM region partitioning (ring-safe BFS, Diffuse2Seg-derived relevance propagation) — see the [full API reference](https://tatopenn-cell.github.io/Dense-Evolution/api/) for all of it.
308
315
 
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="docs/assets/banner.svg" alt="Dense Evolution — NISQ quantum simulation toolkit, JAX-native" width="900">
2
+ <img src="docs/assets/banner.png" alt="Dense Evolution — NISQ quantum simulation toolkit, JAX-native" width="900">
3
3
  </p>
4
4
 
5
5
 
@@ -11,8 +11,8 @@ Statevector/MPS engines with compilation, noise, VQE, QEC, chemistry, and agent-
11
11
  <p align="center">
12
12
  <img src="docs/assets/favicon.svg" width="32" alt=""><br>
13
13
  <b>Download the Dense Evolution Dashboard (Streamlit)</b><br>
14
- <a href="https://github.com/tatopenn-cell/Dense-Evolution/raw/main/tools/installer/install-dashboard.bat">Windows (.bat)</a> &middot;
15
- <a href="https://github.com/tatopenn-cell/Dense-Evolution/raw/main/tools/installer/install-dashboard.sh">macOS / Linux (.sh)</a>
14
+ <a href="https://tatopenn-cell.github.io/Dense-Evolution/assets/installer/install-dashboard.bat">Windows (.bat)</a> &middot;
15
+ <a href="https://tatopenn-cell.github.io/Dense-Evolution/assets/installer/install-dashboard.sh">macOS / Linux (.sh)</a>
16
16
  </p>
17
17
 
18
18
  [![CI](https://github.com/tatopenn-cell/Dense-Evolution/actions/workflows/ci.yml/badge.svg)](https://github.com/tatopenn-cell/Dense-Evolution/actions/workflows/ci.yml)
@@ -65,6 +65,9 @@ pip install dense-evolution[full]
65
65
  pip install dense-evolution[qiskit]
66
66
  pip install dense-evolution[pennylane]
67
67
 
68
+ # native Hartree-Fock (basis-set data)
69
+ pip install dense-evolution[hf]
70
+
68
71
  # Composer's local kernel (see "Composer" below)
69
72
  pip install dense-evolution[composer]
70
73
 
@@ -200,9 +203,11 @@ sim.run_chunk(circuit.to_tuples(), chunk_size_gates=500)
200
203
 
201
204
  - **JIT-fused statevector engine.** No Kronecker-product overhead — stride-sliced linear kernel fusion compiled through JAX XLA, real GPU/TPU dispatch with no code change. [Simulator](https://tatopenn-cell.github.io/Dense-Evolution/api/simulator/) · [MPS backend](https://tatopenn-cell.github.io/Dense-Evolution/api/mps/) for low-entanglement circuits at scale.
202
205
  - **Anti-OOM `Chunk` engine.** Circuits too large for one array, split dynamically and sized off the real compute device's own free memory — with disk-backed overflow past even that ceiling. [Chunk guide](https://tatopenn-cell.github.io/Dense-Evolution/api/chunk/).
203
- - **Real noise, real mitigation.** Stochastic Kraus channels, real-device noise imported from Qiskit backends, and Zero-Noise Extrapolation to correct for it. [Noise](https://tatopenn-cell.github.io/Dense-Evolution/api/noise/) · [Mitigation](https://tatopenn-cell.github.io/Dense-Evolution/api/mitigation/) · [what noise/mitigation/healing each mean](https://tatopenn-cell.github.io/Dense-Evolution/concepts/).
206
+ - **Real noise, real mitigation.** Stochastic Kraus channels, real-device noise imported from Qiskit backends, and Zero-Noise Extrapolation, with the shot budget split optimally across noise factors and a single-qubit Bloch-vector variant that always returns a valid state, to correct for it. [Noise](https://tatopenn-cell.github.io/Dense-Evolution/api/noise/) · [Mitigation](https://tatopenn-cell.github.io/Dense-Evolution/api/mitigation/) · [what noise/mitigation/healing each mean](https://tatopenn-cell.github.io/Dense-Evolution/concepts/).
204
207
  - **Differentiable VQE, from scratch.** `circuit_to_energy_fn` is the same JAX-differentiable engine real molecular VQE runs on — real Hartree-Fock Hamiltonians, UCCSD/hardware-efficient ansätze, Adam optimization. [Autodiff](https://tatopenn-cell.github.io/Dense-Evolution/api/autodiff/).
205
- - **libcint integrals on Windows, macOS and Linux.** `pip install dense-evolution` ships libcint compiled for each system: the full two-electron tensor of ethanol in 6-31G* in 0.32 s. [native_hf](https://tatopenn-cell.github.io/Dense-Evolution/api/native_hf/).
208
+ - **libcint integrals on Windows, macOS and Linux.** `pip install dense-evolution` ships libcint compiled for each system: the full two-electron tensor of ethanol in 6-31G* in 0.32 s. Open-shell molecules with UHF and ROHF (`run_uhf`, `run_cuhf`). [native_hf](https://tatopenn-cell.github.io/Dense-Evolution/api/native_hf/).
209
+ - **Reversible arithmetic.** Register adders, subtraction, comparisons and modular arithmetic up to modular exponentiation, applied as exact basis permutations, and as OPENQASM 2.0 gate circuits (Cuccaro, Draper and Beauregard adders, controlled modular multiplication), up to Shor order finding with one control qubit. [Arithmetic](https://tatopenn-cell.github.io/Dense-Evolution/api/arithmetic/).
210
+ - **Postselection.** Keep the branch where a qubit is found in `|0>`, `|1>`, `|±>` or `|±i>`, with its probability. [Postselection](https://tatopenn-cell.github.io/Dense-Evolution/api/postselect/).
206
211
  - **OpenQASM 2.0/3.0, both directions.** A real parser, plus Qiskit/PennyLane interop bridges. [QASM Parser](https://tatopenn-cell.github.io/Dense-Evolution/api/parser/) · [Interop](https://tatopenn-cell.github.io/Dense-Evolution/api/interop/).
207
212
  - **Code-agnostic QEC decoding**, Majorana/Jordan-Wigner fermion mapping, from-scratch Hartree-Fock for elements outside PennyLane's own basis set, a traversable-wormhole-inspired teleportation protocol, and real QM/MM region partitioning (ring-safe BFS, Diffuse2Seg-derived relevance propagation) — see the [full API reference](https://tatopenn-cell.github.io/Dense-Evolution/api/) for all of it.
208
213
 
@@ -31,7 +31,7 @@ from .backends.mps import MPSSimulator
31
31
  from .mitigation.zne import (richardson_extrapolate, richardson_amplification_factor,
32
32
  zero_noise_extrapolation, polynomial_extrapolate,
33
33
  bounded_exponential_extrapolate,
34
- project_to_physical, uhlmann_fidelity, zne_density_matrix,
34
+ project_to_physical, bloch_zne, bloch_zne_jit, uhlmann_fidelity, zne_density_matrix,
35
35
  jsd_predictive_zne_density_matrix,
36
36
  coherence_predictive_zne_density_matrix,
37
37
  classically_augmented_zne_phaseflip,
@@ -45,6 +45,17 @@ from .physics.observables import (pauli_expectation, pauli_sum_expectation, paul
45
45
  from .physics.states import ghz_state
46
46
  from .utils.measurement import sample_counts, statevector_fidelity
47
47
  from .circuits.qft import qft
48
+ from .circuits.arithmetic import (
49
+ add_registers, subtract_registers, add_constant,
50
+ compare_registers, compare_constant,
51
+ add_registers_mod, add_constant_mod, multiply_add_mod, multiply_mod, power_mod,
52
+ )
53
+ from .circuits.arithmetic_qasm import (
54
+ cuccaro_adder_qasm, draper_adder_qasm, constant_adder_qasm, modular_constant_adder_qasm,
55
+ cmult_mod_qasm, controlled_ua_qasm,
56
+ )
57
+ from .circuits.shor import shor_order_finding
58
+ from .circuits.postselect import postselect
48
59
  from .circuits.random_circuit import random_circuit
49
60
  from .utils.drawing import draw_circuit
50
61
  from .solvers.harrison_tb import (ELEMENTS as HARRISON_ELEMENTS, ETA as HARRISON_ETA,
@@ -62,7 +73,7 @@ from .physics.qec import (pauli_commutes, compute_syndrome, erasure_aware_decode
62
73
  peeling_decode, union_find_decode, matching_erasure_decode,
63
74
  estimate_edge_probabilities_from_detection_events)
64
75
 
65
- __version__ = "8.3.0"
76
+ __version__ = "8.3.2"
66
77
 
67
78
  __all__ = [
68
79
  "__version__",
@@ -75,6 +86,12 @@ __all__ = [
75
86
  "NoiseModel", "NoiseSpec", "QuantumHardwareRegistry",
76
87
  "GATES", "PARAMETRIC_GATES", "GATE_IDS",
77
88
  "entangling_layer", "qft",
89
+ "add_registers", "subtract_registers", "add_constant",
90
+ "compare_registers", "compare_constant",
91
+ "add_registers_mod", "add_constant_mod", "multiply_add_mod", "multiply_mod", "power_mod",
92
+ "cuccaro_adder_qasm", "draper_adder_qasm", "constant_adder_qasm", "modular_constant_adder_qasm",
93
+ "cmult_mod_qasm", "controlled_ua_qasm", "shor_order_finding",
94
+ "postselect",
78
95
  "pauli_rotation_ops", "trotter_evolve_ops", "continuous_pulse_evolve",
79
96
  "continuous_dissipative_evolve",
80
97
  "find_excitations", "single_excitation_ops", "double_excitation_ops",
@@ -91,7 +108,7 @@ __all__ = [
91
108
  "richardson_extrapolate", "richardson_amplification_factor",
92
109
  "zero_noise_extrapolation", "polynomial_extrapolate",
93
110
  "bounded_exponential_extrapolate",
94
- "project_to_physical", "uhlmann_fidelity", "zne_density_matrix",
111
+ "project_to_physical", "bloch_zne", "bloch_zne_jit", "uhlmann_fidelity", "zne_density_matrix",
95
112
  "jsd_predictive_zne_density_matrix", "coherence_predictive_zne_density_matrix",
96
113
  "classically_augmented_zne_phaseflip",
97
114
  "global_depolarizing_channel", "amplitude_damping_channel", "phaseflip_channel_exact",
@@ -0,0 +1,37 @@
1
+ """Circuits subpackage: gate registry, parsing, compilation, topology."""
2
+ from .gates import GATES, PARAMETRIC_GATES, GATE_IDS
3
+ from .parser import QASMParser, QASMCircuit
4
+ from .compiler import QuantumTranspiler
5
+ from .registry import HAS_JAX, NoiseModel, NoiseSpec, QuantumHardwareRegistry
6
+ from .topology import entangling_layer, VALID_PATTERNS
7
+ from .qft import qft
8
+ from .arithmetic import (
9
+ add_registers, subtract_registers, add_constant,
10
+ compare_registers, compare_constant,
11
+ add_registers_mod, add_constant_mod, multiply_add_mod, multiply_mod, power_mod,
12
+ )
13
+ from .arithmetic_qasm import (
14
+ cuccaro_adder_qasm, draper_adder_qasm, constant_adder_qasm, modular_constant_adder_qasm,
15
+ cmult_mod_qasm, controlled_ua_qasm,
16
+ )
17
+ from .shor import shor_order_finding
18
+ from .postselect import postselect
19
+ from .random_circuit import random_circuit
20
+ from .trotter import pauli_rotation_ops, trotter_evolve_ops
21
+
22
+ __all__ = [
23
+ "GATES", "PARAMETRIC_GATES", "GATE_IDS",
24
+ "QASMParser", "QASMCircuit",
25
+ "QuantumTranspiler",
26
+ "HAS_JAX", "NoiseModel", "NoiseSpec", "QuantumHardwareRegistry",
27
+ "entangling_layer", "VALID_PATTERNS",
28
+ "qft",
29
+ "add_registers", "subtract_registers", "add_constant",
30
+ "compare_registers", "compare_constant",
31
+ "add_registers_mod", "add_constant_mod", "multiply_add_mod", "multiply_mod", "power_mod",
32
+ "cuccaro_adder_qasm", "draper_adder_qasm", "constant_adder_qasm", "modular_constant_adder_qasm",
33
+ "cmult_mod_qasm", "controlled_ua_qasm", "shor_order_finding",
34
+ "postselect",
35
+ "random_circuit",
36
+ "pauli_rotation_ops", "trotter_evolve_ops",
37
+ ]
@@ -0,0 +1,241 @@
1
+ """
2
+ Reversible arithmetic on qubit registers, applied to a statevector.
3
+
4
+ Every operation here is a bijection f on computational basis states, so its
5
+ unitary is the permutation U|x> = |f(x)> (Vedral, Barenco, Ekert,
6
+ quant-ph/9511018, Sect. II, Eqs. 2-3). It is applied directly as an index
7
+ permutation of the statevector, which is exact and costs one gather over the
8
+ 2^n amplitudes. The gate-level circuits from the papers (Cuccaro et al.
9
+ quant-ph/0410184 ripple-carry adder, Draper quant-ph/0008033 transform
10
+ adder) are the references the tests compare against.
11
+
12
+ A register is a list of qubit indices, least significant bit first. Qubit 0
13
+ is the most significant bit of the statevector index, as everywhere in the
14
+ engine.
15
+ """
16
+ import numpy as np
17
+
18
+ from ..config import ensure_x64
19
+ from .registry import HAS_JAX
20
+
21
+ if HAS_JAX:
22
+ import jax.numpy as jnp
23
+ xp = jnp
24
+ else:
25
+ xp = np
26
+
27
+ __all__ = ['add_registers', 'subtract_registers', 'add_constant',
28
+ 'compare_registers', 'compare_constant',
29
+ 'add_registers_mod', 'add_constant_mod', 'multiply_add_mod',
30
+ 'multiply_mod', 'power_mod']
31
+
32
+ _COMPARISONS = {
33
+ '<': np.less, '>': np.greater, '<=': np.less_equal,
34
+ '>=': np.greater_equal, '==': np.equal, '!=': np.not_equal,
35
+ }
36
+
37
+
38
+ def _register_values(n_qubits, register):
39
+ idx = np.arange(2 ** n_qubits)
40
+ value = np.zeros_like(idx)
41
+ for k, q in enumerate(register):
42
+ value |= ((idx >> (n_qubits - 1 - q)) & 1) << k
43
+ return idx, value
44
+
45
+
46
+ def _with_register(n_qubits, idx, register, value):
47
+ out = idx.copy()
48
+ for k, q in enumerate(register):
49
+ shift = n_qubits - 1 - q
50
+ out = (out & ~(1 << shift)) | (((value >> k) & 1) << shift)
51
+ return out
52
+
53
+
54
+ def _check(n_qubits, *registers):
55
+ used = [q for r in registers for q in r]
56
+ if len(set(used)) != len(used):
57
+ raise ValueError("registers must not share qubits")
58
+ if any(q < 0 or q >= n_qubits for q in used):
59
+ raise ValueError(f"qubit index out of range for {n_qubits} qubits")
60
+ if any(len(r) == 0 for r in registers):
61
+ raise ValueError("registers must not be empty")
62
+
63
+
64
+ def _permute(sv, target):
65
+ if xp is np:
66
+ sv = np.asarray(sv)
67
+ out = np.zeros_like(sv)
68
+ out[target] = sv
69
+ return out
70
+ ensure_x64()
71
+ sv = xp.asarray(sv)
72
+ return xp.zeros_like(sv).at[target].set(sv)
73
+
74
+
75
+ def add_registers(sv, n_qubits, a, b):
76
+ """
77
+ |a, b> -> |a, (a + b) mod 2^len(b)>.
78
+
79
+ With len(b) = len(a) + 1 the sum never overflows (Vedral et al.,
80
+ Sect. III.A, Eq. 9); with len(b) = len(a) it is addition modulo 2^n
81
+ (Cuccaro et al., Sect. 4.1).
82
+ """
83
+ _check(n_qubits, a, b)
84
+ idx, va = _register_values(n_qubits, a)
85
+ _, vb = _register_values(n_qubits, b)
86
+ target = _with_register(n_qubits, idx, b, (va + vb) % (1 << len(b)))
87
+ return _permute(sv, target)
88
+
89
+
90
+ def subtract_registers(sv, n_qubits, a, b):
91
+ """
92
+ |a, b> -> |a, (b - a) mod 2^len(b)>, the inverse of add_registers.
93
+
94
+ If b < a the result is 2^len(b) - (a - b) and, with len(b) = len(a) + 1,
95
+ its most significant qubit is 1 (Vedral et al., Sect. III.A).
96
+ """
97
+ _check(n_qubits, a, b)
98
+ idx, va = _register_values(n_qubits, a)
99
+ _, vb = _register_values(n_qubits, b)
100
+ target = _with_register(n_qubits, idx, b, (vb - va) % (1 << len(b)))
101
+ return _permute(sv, target)
102
+
103
+
104
+ def add_constant(sv, n_qubits, b, c):
105
+ """
106
+ |b> -> |(b + c) mod 2^len(b)> for a classical integer c.
107
+
108
+ c = 1 is increment, c = -1 decrement. Same operation as Draper's
109
+ transform adder with classical addend (Sect. 5) and Beauregard's
110
+ phiADD(c) (quant-ph/0205095, Sect. 2.1).
111
+ """
112
+ _check(n_qubits, b)
113
+ idx, vb = _register_values(n_qubits, b)
114
+ target = _with_register(n_qubits, idx, b, (vb + int(c)) % (1 << len(b)))
115
+ return _permute(sv, target)
116
+
117
+
118
+ def _flip_if(n_qubits, idx, out, condition):
119
+ return idx ^ (condition.astype(idx.dtype) << (n_qubits - 1 - out))
120
+
121
+
122
+ def _comparison(op):
123
+ if op not in _COMPARISONS:
124
+ raise ValueError(f"op must be one of {sorted(_COMPARISONS)}, got {op!r}")
125
+ return _COMPARISONS[op]
126
+
127
+
128
+ def compare_registers(sv, n_qubits, a, b, out, op='<'):
129
+ """
130
+ |a, b, z> -> |a, b, z XOR [a op b]>, inputs unchanged.
131
+
132
+ op = '<' is the comparator of Cuccaro et al. (Sect. 4.3): the high bit of
133
+ a - b, which is 1 if and only if a < b. The other comparisons follow by
134
+ swapping the operands and negating the output qubit.
135
+ """
136
+ _check(n_qubits, a, b, [out])
137
+ idx, va = _register_values(n_qubits, a)
138
+ _, vb = _register_values(n_qubits, b)
139
+ return _permute(sv, _flip_if(n_qubits, idx, out, _comparison(op)(va, vb)))
140
+
141
+
142
+ def compare_constant(sv, n_qubits, b, c, out, op='<'):
143
+ """
144
+ |b, z> -> |b, z XOR [b op c]> for a classical integer c.
145
+
146
+ op = '<' is the most significant qubit after the reverse phiADD(c) of
147
+ Beauregard (quant-ph/0205095, Sect. 2.1, Fig. 4).
148
+ """
149
+ _check(n_qubits, b, [out])
150
+ idx, vb = _register_values(n_qubits, b)
151
+ return _permute(sv, _flip_if(n_qubits, idx, out, _comparison(op)(vb, int(c))))
152
+
153
+
154
+ def _active(n_qubits, idx, controls):
155
+ on = np.ones(idx.shape, dtype=bool)
156
+ for q in controls:
157
+ on &= ((idx >> (n_qubits - 1 - q)) & 1).astype(bool)
158
+ return on
159
+
160
+
161
+ def _check_modulus(N, *registers):
162
+ if N < 1 or any(N > (1 << len(r)) for r in registers):
163
+ raise ValueError(f"modulus N={N} must be >= 1 and fit in the register")
164
+
165
+
166
+ def add_registers_mod(sv, n_qubits, a, b, N):
167
+ """
168
+ |a, b> -> |a, (a + b) mod N> for 0 <= a, b < N (Vedral et al., Sect. III.B,
169
+ Eq. 10). Basis states with a >= N or b >= N are left unchanged, which
170
+ keeps the map a permutation.
171
+ """
172
+ _check(n_qubits, a, b)
173
+ _check_modulus(N, a, b)
174
+ idx, va = _register_values(n_qubits, a)
175
+ _, vb = _register_values(n_qubits, b)
176
+ ok = (va < N) & (vb < N)
177
+ return _permute(sv, _with_register(n_qubits, idx, b, np.where(ok, (va + vb) % N, vb)))
178
+
179
+
180
+ def add_constant_mod(sv, n_qubits, b, c, N, controls=()):
181
+ """
182
+ |b> -> |(b + c) mod N> for 0 <= b < N, applied only where every control
183
+ qubit is 1: the doubly controlled phiADD(c)MOD(N) of Beauregard
184
+ (quant-ph/0205095, Sect. 2.2, Fig. 5). Basis states with b >= N are left
185
+ unchanged.
186
+ """
187
+ _check(n_qubits, b, *([list(controls)] if controls else []))
188
+ _check_modulus(N, b)
189
+ idx, vb = _register_values(n_qubits, b)
190
+ ok = _active(n_qubits, idx, controls) & (vb < N)
191
+ return _permute(sv, _with_register(n_qubits, idx, b, np.where(ok, (vb + int(c)) % N, vb)))
192
+
193
+
194
+ def multiply_add_mod(sv, n_qubits, x, b, a, N, controls=()):
195
+ """
196
+ |x, b> -> |x, (b + a*x) mod N> for 0 <= b < N, applied only where every
197
+ control qubit is 1: CMULT(a)MOD(N) of Beauregard (Sect. 2.3, Fig. 6),
198
+ built in the paper from n controlled modular additions of 2^i*a mod N
199
+ (Vedral et al., Sect. III.C). Basis states with b >= N are left unchanged.
200
+ """
201
+ _check(n_qubits, x, b, *([list(controls)] if controls else []))
202
+ _check_modulus(N, b)
203
+ idx, vx = _register_values(n_qubits, x)
204
+ _, vb = _register_values(n_qubits, b)
205
+ ok = _active(n_qubits, idx, controls) & (vb < N)
206
+ new = (vb + (int(a) % N) * (vx % N)) % N
207
+ return _permute(sv, _with_register(n_qubits, idx, b, np.where(ok, new, vb)))
208
+
209
+
210
+ def multiply_mod(sv, n_qubits, x, a, N, controls=()):
211
+ """
212
+ |x> -> |a*x mod N> in place for 0 <= x < N and gcd(a, N) = 1, applied only
213
+ where every control qubit is 1 (Vedral et al., Sect. II, Eqs. 4-6;
214
+ Beauregard, Sect. 2.3, Fig. 7). With N = 2^len(x) and odd a this is plain
215
+ multiplication modulo 2^n. Basis states with x >= N are left unchanged.
216
+ """
217
+ _check(n_qubits, x, *([list(controls)] if controls else []))
218
+ _check_modulus(N, x)
219
+ if np.gcd(int(a), N) != 1:
220
+ raise ValueError(f"a={a} and N={N} must be coprime for an in-place multiplication")
221
+ idx, vx = _register_values(n_qubits, x)
222
+ ok = _active(n_qubits, idx, controls) & (vx < N)
223
+ return _permute(sv, _with_register(n_qubits, idx, x, np.where(ok, (int(a) * vx) % N, vx)))
224
+
225
+
226
+ def power_mod(sv, n_qubits, x, y, a, N):
227
+ """
228
+ |x, y> -> |x, y * a^x mod N> for 0 <= y < N and gcd(a, N) = 1. With y = 1
229
+ this is the modular exponentiation |x, 1> -> |x, a^x mod N> of Shor's
230
+ algorithm (Vedral et al., Eq. 1 and Sect. III.D). Basis states with
231
+ y >= N are left unchanged.
232
+ """
233
+ _check(n_qubits, x, y)
234
+ _check_modulus(N, y)
235
+ if np.gcd(int(a), N) != 1:
236
+ raise ValueError(f"a={a} and N={N} must be coprime")
237
+ idx, vx = _register_values(n_qubits, x)
238
+ _, vy = _register_values(n_qubits, y)
239
+ powers = np.array([pow(int(a), int(e), N) for e in range(1 << len(x))])
240
+ ok = vy < N
241
+ return _permute(sv, _with_register(n_qubits, idx, y, np.where(ok, (vy * powers[vx]) % N, vy)))