qadence 1.10.2__tar.gz → 1.11.0__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 (165) hide show
  1. {qadence-1.10.2 → qadence-1.11.0}/PKG-INFO +16 -13
  2. {qadence-1.10.2 → qadence-1.11.0}/README.md +9 -6
  3. {qadence-1.10.2 → qadence-1.11.0}/mkdocs.yml +10 -3
  4. {qadence-1.10.2 → qadence-1.11.0}/pyproject.toml +9 -8
  5. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/horqrux/convert_ops.py +1 -1
  6. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/block_to_tensor.py +29 -32
  7. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/matrix.py +4 -0
  8. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/__init__.py +7 -1
  9. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/hamiltonians.py +96 -9
  10. {qadence-1.10.2 → qadence-1.11.0}/qadence/mitigations/analog_zne.py +6 -2
  11. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/__init__.py +3 -2
  12. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/callbacks/callback.py +80 -50
  13. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/callbacks/callbackmanager.py +3 -2
  14. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/callbacks/writer_registry.py +3 -2
  15. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/config.py +66 -5
  16. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/constructors.py +9 -62
  17. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/data.py +4 -0
  18. qadence-1.11.0/qadence/ml_tools/information/__init__.py +3 -0
  19. qadence-1.11.0/qadence/ml_tools/information/information_content.py +339 -0
  20. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/models.py +69 -4
  21. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/optimize_step.py +1 -2
  22. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/train_utils/__init__.py +3 -1
  23. qadence-1.11.0/qadence/ml_tools/train_utils/accelerator.py +480 -0
  24. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/train_utils/config_manager.py +7 -7
  25. qadence-1.11.0/qadence/ml_tools/train_utils/distribution.py +209 -0
  26. qadence-1.11.0/qadence/ml_tools/train_utils/execution.py +421 -0
  27. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/trainer.py +291 -98
  28. {qadence-1.10.2 → qadence-1.11.0}/qadence/operations/primitive.py +0 -4
  29. {qadence-1.10.2 → qadence-1.11.0}/qadence/types.py +7 -11
  30. {qadence-1.10.2 → qadence-1.11.0}/qadence/utils.py +45 -0
  31. {qadence-1.10.2 → qadence-1.11.0}/renovate.json +0 -1
  32. {qadence-1.10.2 → qadence-1.11.0}/.coveragerc +0 -0
  33. {qadence-1.10.2 → qadence-1.11.0}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  34. {qadence-1.10.2 → qadence-1.11.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  35. {qadence-1.10.2 → qadence-1.11.0}/.github/ISSUE_TEMPLATE/new-feature.yml +0 -0
  36. {qadence-1.10.2 → qadence-1.11.0}/.github/workflows/build_docs.yml +0 -0
  37. {qadence-1.10.2 → qadence-1.11.0}/.github/workflows/lint.yml +0 -0
  38. {qadence-1.10.2 → qadence-1.11.0}/.github/workflows/test_all.yml +0 -0
  39. {qadence-1.10.2 → qadence-1.11.0}/.github/workflows/test_examples.yml +0 -0
  40. {qadence-1.10.2 → qadence-1.11.0}/.github/workflows/test_fast.yml +0 -0
  41. {qadence-1.10.2 → qadence-1.11.0}/.gitignore +0 -0
  42. {qadence-1.10.2 → qadence-1.11.0}/.pre-commit-config.yaml +0 -0
  43. {qadence-1.10.2 → qadence-1.11.0}/LICENSE +0 -0
  44. {qadence-1.10.2 → qadence-1.11.0}/MANIFEST.in +0 -0
  45. {qadence-1.10.2 → qadence-1.11.0}/qadence/__init__.py +0 -0
  46. {qadence-1.10.2 → qadence-1.11.0}/qadence/analog/__init__.py +0 -0
  47. {qadence-1.10.2 → qadence-1.11.0}/qadence/analog/addressing.py +0 -0
  48. {qadence-1.10.2 → qadence-1.11.0}/qadence/analog/constants.py +0 -0
  49. {qadence-1.10.2 → qadence-1.11.0}/qadence/analog/device.py +0 -0
  50. {qadence-1.10.2 → qadence-1.11.0}/qadence/analog/hamiltonian_terms.py +0 -0
  51. {qadence-1.10.2 → qadence-1.11.0}/qadence/analog/parse_analog.py +0 -0
  52. {qadence-1.10.2 → qadence-1.11.0}/qadence/backend.py +0 -0
  53. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/__init__.py +0 -0
  54. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/api.py +0 -0
  55. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/gpsr.py +0 -0
  56. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/horqrux/__init__.py +0 -0
  57. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/horqrux/backend.py +0 -0
  58. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/horqrux/config.py +0 -0
  59. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/jax_utils.py +0 -0
  60. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/__init__.py +0 -0
  61. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/backend.py +0 -0
  62. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/channels.py +0 -0
  63. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/cloud.py +0 -0
  64. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/config.py +0 -0
  65. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/convert_ops.py +0 -0
  66. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/devices.py +0 -0
  67. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/pulses.py +0 -0
  68. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pulser/waveforms.py +0 -0
  69. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pyqtorch/__init__.py +0 -0
  70. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pyqtorch/backend.py +0 -0
  71. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pyqtorch/config.py +0 -0
  72. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/pyqtorch/convert_ops.py +0 -0
  73. {qadence-1.10.2 → qadence-1.11.0}/qadence/backends/utils.py +0 -0
  74. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/__init__.py +0 -0
  75. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/abstract.py +0 -0
  76. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/analog.py +0 -0
  77. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/composite.py +0 -0
  78. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/embedding.py +0 -0
  79. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/manipulate.py +0 -0
  80. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/primitive.py +0 -0
  81. {qadence-1.10.2 → qadence-1.11.0}/qadence/blocks/utils.py +0 -0
  82. {qadence-1.10.2 → qadence-1.11.0}/qadence/circuit.py +0 -0
  83. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/ala.py +0 -0
  84. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/daqc/__init__.py +0 -0
  85. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/daqc/daqc.py +0 -0
  86. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/daqc/gen_parser.py +0 -0
  87. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/daqc/utils.py +0 -0
  88. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/feature_maps.py +0 -0
  89. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/hea.py +0 -0
  90. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/iia.py +0 -0
  91. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/qft.py +0 -0
  92. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/rydberg_feature_maps.py +0 -0
  93. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/rydberg_hea.py +0 -0
  94. {qadence-1.10.2 → qadence-1.11.0}/qadence/constructors/utils.py +0 -0
  95. {qadence-1.10.2 → qadence-1.11.0}/qadence/decompose.py +0 -0
  96. {qadence-1.10.2 → qadence-1.11.0}/qadence/divergences.py +0 -0
  97. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/__init__.py +0 -0
  98. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/assets/dark/measurement.png +0 -0
  99. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/assets/dark/measurement.svg +0 -0
  100. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/assets/light/measurement.png +0 -0
  101. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/assets/light/measurement.svg +0 -0
  102. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/themes.py +0 -0
  103. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/utils.py +0 -0
  104. {qadence-1.10.2 → qadence-1.11.0}/qadence/draw/vizbackend.py +0 -0
  105. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/__init__.py +0 -0
  106. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/differentiable_backend.py +0 -0
  107. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/jax/__init__.py +0 -0
  108. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/jax/differentiable_backend.py +0 -0
  109. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/jax/differentiable_expectation.py +0 -0
  110. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/torch/__init__.py +0 -0
  111. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/torch/differentiable_backend.py +0 -0
  112. {qadence-1.10.2 → qadence-1.11.0}/qadence/engines/torch/differentiable_expectation.py +0 -0
  113. {qadence-1.10.2 → qadence-1.11.0}/qadence/exceptions/__init__.py +0 -0
  114. {qadence-1.10.2 → qadence-1.11.0}/qadence/exceptions/exceptions.py +0 -0
  115. {qadence-1.10.2 → qadence-1.11.0}/qadence/execution.py +0 -0
  116. {qadence-1.10.2 → qadence-1.11.0}/qadence/extensions.py +0 -0
  117. {qadence-1.10.2 → qadence-1.11.0}/qadence/libs.py +0 -0
  118. {qadence-1.10.2 → qadence-1.11.0}/qadence/log_config.yaml +0 -0
  119. {qadence-1.10.2 → qadence-1.11.0}/qadence/logger.py +0 -0
  120. {qadence-1.10.2 → qadence-1.11.0}/qadence/measurements/__init__.py +0 -0
  121. {qadence-1.10.2 → qadence-1.11.0}/qadence/measurements/protocols.py +0 -0
  122. {qadence-1.10.2 → qadence-1.11.0}/qadence/measurements/samples.py +0 -0
  123. {qadence-1.10.2 → qadence-1.11.0}/qadence/measurements/shadow.py +0 -0
  124. {qadence-1.10.2 → qadence-1.11.0}/qadence/measurements/tomography.py +0 -0
  125. {qadence-1.10.2 → qadence-1.11.0}/qadence/measurements/utils.py +0 -0
  126. {qadence-1.10.2 → qadence-1.11.0}/qadence/mitigations/__init__.py +0 -0
  127. {qadence-1.10.2 → qadence-1.11.0}/qadence/mitigations/protocols.py +0 -0
  128. {qadence-1.10.2 → qadence-1.11.0}/qadence/mitigations/readout.py +0 -0
  129. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/callbacks/__init__.py +0 -0
  130. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/callbacks/saveload.py +0 -0
  131. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/loss/__init__.py +0 -0
  132. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/loss/loss.py +0 -0
  133. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/parameters.py +0 -0
  134. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/stages.py +0 -0
  135. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/tensors.py +0 -0
  136. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/train_utils/base_trainer.py +0 -0
  137. {qadence-1.10.2 → qadence-1.11.0}/qadence/ml_tools/utils.py +0 -0
  138. {qadence-1.10.2 → qadence-1.11.0}/qadence/model.py +0 -0
  139. {qadence-1.10.2 → qadence-1.11.0}/qadence/noise/__init__.py +0 -0
  140. {qadence-1.10.2 → qadence-1.11.0}/qadence/noise/protocols.py +0 -0
  141. {qadence-1.10.2 → qadence-1.11.0}/qadence/operations/__init__.py +0 -0
  142. {qadence-1.10.2 → qadence-1.11.0}/qadence/operations/analog.py +0 -0
  143. {qadence-1.10.2 → qadence-1.11.0}/qadence/operations/control_ops.py +0 -0
  144. {qadence-1.10.2 → qadence-1.11.0}/qadence/operations/ham_evo.py +0 -0
  145. {qadence-1.10.2 → qadence-1.11.0}/qadence/operations/parametric.py +0 -0
  146. {qadence-1.10.2 → qadence-1.11.0}/qadence/overlap.py +0 -0
  147. {qadence-1.10.2 → qadence-1.11.0}/qadence/parameters.py +0 -0
  148. {qadence-1.10.2 → qadence-1.11.0}/qadence/pasqal_cloud_connection.py +0 -0
  149. {qadence-1.10.2 → qadence-1.11.0}/qadence/protocols.py +0 -0
  150. {qadence-1.10.2 → qadence-1.11.0}/qadence/py.typed +0 -0
  151. {qadence-1.10.2 → qadence-1.11.0}/qadence/qubit_support.py +0 -0
  152. {qadence-1.10.2 → qadence-1.11.0}/qadence/register.py +0 -0
  153. {qadence-1.10.2 → qadence-1.11.0}/qadence/serial_expr_grammar.peg +0 -0
  154. {qadence-1.10.2 → qadence-1.11.0}/qadence/serialization.py +0 -0
  155. {qadence-1.10.2 → qadence-1.11.0}/qadence/states.py +0 -0
  156. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/__init__.py +0 -0
  157. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/apply_fn.py +0 -0
  158. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/block.py +0 -0
  159. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/circuit.py +0 -0
  160. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/digitalize.py +0 -0
  161. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/flatten.py +0 -0
  162. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/invert.py +0 -0
  163. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/noise.py +0 -0
  164. {qadence-1.10.2 → qadence-1.11.0}/qadence/transpile/transpile.py +0 -0
  165. {qadence-1.10.2 → qadence-1.11.0}/setup.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qadence
3
- Version: 1.10.2
3
+ Version: 1.11.0
4
4
  Summary: Pasqal interface for circuit-based quantum computing SDKs
5
- Author-email: Aleksander Wennersteen <aleksander.wennersteen@pasqal.com>, Gert-Jan Both <gert-jan.both@pasqal.com>, Niklas Heim <niklas.heim@pasqal.com>, Mario Dagrada <mario.dagrada@pasqal.com>, Vincent Elfving <vincent.elfving@pasqal.com>, Dominik Seitz <dominik.seitz@pasqal.com>, Roland Guichard <roland.guichard@pasqal.com>, "Joao P. Moutinho" <joao.moutinho@pasqal.com>, Vytautas Abramavicius <vytautas.abramavicius@pasqal.com>, Gergana Velikova <gergana.velikova@pasqal.com>, Eduardo Maschio <eduardo.maschio@pasqal.com>, Smit Chaudhary <smit.chaudhary@pasqal.com>, Ignacio Fernández Graña <ignacio.fernandez-grana@pasqal.com>, Charles Moussa <charles.moussa@pasqal.com>, Giorgio Tosti Balducci <giorgio.tosti-balducci@pasqal.com>, Daniele Cucurachi <daniele.cucurachi@pasqal.com>, Pim Venderbosch <pim.venderbosch@pasqal.com>
5
+ Author-email: Aleksander Wennersteen <aleksander.wennersteen@pasqal.com>, Gert-Jan Both <gert-jan.both@pasqal.com>, Niklas Heim <niklas.heim@pasqal.com>, Mario Dagrada <mario.dagrada@pasqal.com>, Vincent Elfving <vincent.elfving@pasqal.com>, Dominik Seitz <dominik.seitz@pasqal.com>, Roland Guichard <roland.guichard@pasqal.com>, "Joao P. Moutinho" <joao.moutinho@pasqal.com>, Vytautas Abramavicius <vytautas.abramavicius@pasqal.com>, Gergana Velikova <gergana.velikova@pasqal.com>, Eduardo Maschio <eduardo.maschio@pasqal.com>, Smit Chaudhary <smit.chaudhary@pasqal.com>, Ignacio Fernández Graña <ignacio.fernandez-grana@pasqal.com>, Charles Moussa <charles.moussa@pasqal.com>, Giorgio Tosti Balducci <giorgio.tosti-balducci@pasqal.com>, Daniele Cucurachi <daniele.cucurachi@pasqal.com>, Pim Venderbosch <pim.venderbosch@pasqal.com>, Manu Lahariya <manu.lahariya@pasqal.com>
6
6
  License: Apache 2.0
7
7
  License-File: LICENSE
8
8
  Classifier: License :: OSI Approved :: Apache Software License
@@ -23,7 +23,7 @@ Requires-Dist: nevergrad
23
23
  Requires-Dist: numpy
24
24
  Requires-Dist: openfermion
25
25
  Requires-Dist: pasqal-cloud
26
- Requires-Dist: pyqtorch==1.7.0
26
+ Requires-Dist: pyqtorch==1.7.1
27
27
  Requires-Dist: pyyaml
28
28
  Requires-Dist: rich
29
29
  Requires-Dist: scipy
@@ -43,7 +43,7 @@ Requires-Dist: nvidia-pyindex; extra == 'dlprof'
43
43
  Provides-Extra: horqrux
44
44
  Requires-Dist: einops; extra == 'horqrux'
45
45
  Requires-Dist: flax; extra == 'horqrux'
46
- Requires-Dist: horqrux==0.6.2; extra == 'horqrux'
46
+ Requires-Dist: horqrux==0.7.0; extra == 'horqrux'
47
47
  Requires-Dist: jax; extra == 'horqrux'
48
48
  Requires-Dist: jaxopt; extra == 'horqrux'
49
49
  Requires-Dist: optax; extra == 'horqrux'
@@ -55,9 +55,9 @@ Requires-Dist: mlflow; extra == 'mlflow'
55
55
  Provides-Extra: protocols
56
56
  Requires-Dist: qadence-protocols; extra == 'protocols'
57
57
  Provides-Extra: pulser
58
- Requires-Dist: pasqal-cloud==0.12.7; extra == 'pulser'
59
- Requires-Dist: pulser-core==1.2.1; extra == 'pulser'
60
- Requires-Dist: pulser-simulation==1.2.1; extra == 'pulser'
58
+ Requires-Dist: pasqal-cloud==0.13.0; extra == 'pulser'
59
+ Requires-Dist: pulser-core==1.3.0; extra == 'pulser'
60
+ Requires-Dist: pulser-simulation==1.3.0; extra == 'pulser'
61
61
  Provides-Extra: visualization
62
62
  Requires-Dist: graphviz; extra == 'visualization'
63
63
  Description-Content-Type: text/markdown
@@ -202,12 +202,15 @@ Users also report problems running Hatch on Windows, we suggest using WSL2.
202
202
  If you use Qadence for a publication, we kindly ask you to cite our work using the following BibTex entry:
203
203
 
204
204
  ```latex
205
- @article{qadence2024pasqal,
206
- title = {Qadence: a differentiable interface for digital-analog programs.},
207
- author={Dominik Seitz and Niklas Heim and João P. Moutinho and Roland Guichard and Vytautas Abramavicius and Aleksander Wennersteen and Gert-Jan Both and Anton Quelle and Caroline de Groot and Gergana V. Velikova and Vincent E. Elfving and Mario Dagrada},
208
- journal={arXiv:2401.09915},
209
- url = {https://github.com/pasqal-io/qadence},
210
- year = {2024}
205
+ @article{qadence2025,
206
+ author = {Seitz, Dominik and Heim, Niklas and Moutinho, João and Guichard, Roland and Abramavicius, Vytautas and Wennersteen, Aleksander and Both, Gert-Jan and Quelle, Anton and Groot, Caroline and Velikova, Gergana and Elfving, Vincent and Dagrada, Mario},
207
+ year = {2025},
208
+ month = {01},
209
+ pages = {1-14},
210
+ title = {Qadence: a differentiable interface for digital and analog programs},
211
+ volume = {PP},
212
+ journal = {IEEE Software},
213
+ doi = {10.1109/MS.2025.3536607}
211
214
  }
212
215
  ```
213
216
 
@@ -138,12 +138,15 @@ Users also report problems running Hatch on Windows, we suggest using WSL2.
138
138
  If you use Qadence for a publication, we kindly ask you to cite our work using the following BibTex entry:
139
139
 
140
140
  ```latex
141
- @article{qadence2024pasqal,
142
- title = {Qadence: a differentiable interface for digital-analog programs.},
143
- author={Dominik Seitz and Niklas Heim and João P. Moutinho and Roland Guichard and Vytautas Abramavicius and Aleksander Wennersteen and Gert-Jan Both and Anton Quelle and Caroline de Groot and Gergana V. Velikova and Vincent E. Elfving and Mario Dagrada},
144
- journal={arXiv:2401.09915},
145
- url = {https://github.com/pasqal-io/qadence},
146
- year = {2024}
141
+ @article{qadence2025,
142
+ author = {Seitz, Dominik and Heim, Niklas and Moutinho, João and Guichard, Roland and Abramavicius, Vytautas and Wennersteen, Aleksander and Both, Gert-Jan and Quelle, Anton and Groot, Caroline and Velikova, Gergana and Elfving, Vincent and Dagrada, Mario},
143
+ year = {2025},
144
+ month = {01},
145
+ pages = {1-14},
146
+ title = {Qadence: a differentiable interface for digital and analog programs},
147
+ volume = {PP},
148
+ journal = {IEEE Software},
149
+ doi = {10.1109/MS.2025.3536607}
147
150
  }
148
151
  ```
149
152
 
@@ -19,6 +19,7 @@ nav:
19
19
  - Quantum models: content/quantummodels.md
20
20
  - Quantum registers: content/register.md
21
21
  - State initialization: content/state_init.md
22
+ - Noisy Simulation: content/noisy_simulation.md
22
23
  - Arbitrary Hamiltonians: content/hamiltonians.md
23
24
  - Time-dependent generators: content/time_dependent.md
24
25
  - QML Constructors: content/qml_constructors.md
@@ -42,14 +43,20 @@ nav:
42
43
 
43
44
  - Variational quantum algorithms:
44
45
  - tutorials/qml/index.md
45
- - Training: tutorials/qml/ml_tools/trainer.md
46
- - Training Callbacks: tutorials/qml/ml_tools/callbacks.md
47
- - Data and Configurations: tutorials/qml/ml_tools/data_and_config.md
48
46
  - Configuring a QNN: tutorials/qml/config_qnn.md
49
47
  - Quantum circuit learning: tutorials/qml/qcl.md
50
48
  - Solving MaxCut with QAOA: tutorials/qml/qaoa.md
51
49
  - Solving a 1D ODE: tutorials/qml/dqc_1d.md
52
50
 
51
+ - ML Tools:
52
+ - tutorials/qml/ml_tools/intro.md
53
+ - Training: tutorials/qml/ml_tools/trainer.md
54
+ - Data and Configurations: tutorials/qml/ml_tools/data_and_config.md
55
+ - Training Callbacks: tutorials/qml/ml_tools/callbacks.md
56
+ - Accelerator: tutorials/qml/ml_tools/accelerator_doc.md
57
+ - CPU Training: tutorials/qml/ml_tools/CPU.md
58
+ - GPU Training: tutorials/qml/ml_tools/GPU.md
59
+
53
60
  - Advanced Tutorials:
54
61
  - tutorials/advanced_tutorials/index.md
55
62
  - Quantum circuits differentiation: tutorials/advanced_tutorials/differentiability.md
@@ -23,11 +23,12 @@ authors = [
23
23
  { name = "Charles Moussa", email = "charles.moussa@pasqal.com" },
24
24
  { name = "Giorgio Tosti Balducci", email = "giorgio.tosti-balducci@pasqal.com" },
25
25
  { name = "Daniele Cucurachi", email = "daniele.cucurachi@pasqal.com" },
26
- { name = "Pim Venderbosch", email = "pim.venderbosch@pasqal.com" }
26
+ { name = "Pim Venderbosch", email = "pim.venderbosch@pasqal.com" },
27
+ { name = "Manu Lahariya", email = "manu.lahariya@pasqal.com" },
27
28
  ]
28
29
  requires-python = ">=3.9"
29
30
  license = { text = "Apache 2.0" }
30
- version = "1.10.2"
31
+ version = "1.11.0"
31
32
  classifiers = [
32
33
  "License :: OSI Approved :: Apache Software License",
33
34
  "Programming Language :: Python",
@@ -51,7 +52,7 @@ dependencies = [
51
52
  "jsonschema",
52
53
  "nevergrad",
53
54
  "scipy",
54
- "pyqtorch==1.7.0",
55
+ "pyqtorch==1.7.1",
55
56
  "pyyaml",
56
57
  "matplotlib",
57
58
  "Arpeggio==2.0.2",
@@ -64,9 +65,9 @@ allow-ambiguous-features = true
64
65
 
65
66
  [project.optional-dependencies]
66
67
  pulser = [
67
- "pulser-core==1.2.1",
68
- "pulser-simulation==1.2.1",
69
- "pasqal-cloud==0.12.7",
68
+ "pulser-core==1.3.0",
69
+ "pulser-simulation==1.3.0",
70
+ "pasqal-cloud==0.13.0",
70
71
  ]
71
72
  visualization = [
72
73
  "graphviz",
@@ -75,7 +76,7 @@ visualization = [
75
76
  # "scour",
76
77
  ]
77
78
  horqrux = [
78
- "horqrux==0.6.2",
79
+ "horqrux==0.7.0",
79
80
  "jax",
80
81
  "flax",
81
82
  "optax",
@@ -136,7 +137,7 @@ filterwarnings = [
136
137
  [tool.hatch.envs.docs]
137
138
  dependencies = [
138
139
  "mkdocs",
139
- "mkdocs_autorefs<1.3.1",
140
+ "mkdocs_autorefs",
140
141
  "mkdocs-material",
141
142
  "mkdocstrings",
142
143
  "mkdocstrings-python",
@@ -245,7 +245,7 @@ class HorqHamiltonianEvolution(NativeHorqHEvo):
245
245
 
246
246
  self._time_evolution = lambda values: values[self.param_names[0]]
247
247
 
248
- def unitary(self, values: dict[str, Array]) -> Array:
248
+ def _unitary(self, values: dict[str, Array]) -> Array:
249
249
  """The evolved operator given current parameter values for generator and time evolution."""
250
250
  return expm(self._hamiltonian(self, values) * (-1j * self._time_evolution(values)))
251
251
 
@@ -79,20 +79,23 @@ def _fill_identities(
79
79
  torch.Tensor: augmented matrix with dimensions (2**nqubits, 2**nqubits)
80
80
  or a tensor (2**n_qubits) if diag_only
81
81
  """
82
+ full_qubit_support = tuple(sorted(full_qubit_support))
82
83
  qubit_support = tuple(sorted(qubit_support))
83
84
  block_mat = block_mat.to(device)
84
- mat = IMAT.to(device) if qubit_support[0] != full_qubit_support[0] else block_mat
85
+ identity_mat = IMAT.to(device)
85
86
  if diag_only:
86
- mat = torch.diag(mat.squeeze(0))
87
+ block_mat = torch.diag(block_mat.squeeze(0))
88
+ identity_mat = torch.diag(identity_mat.squeeze(0))
89
+ mat = identity_mat if qubit_support[0] != full_qubit_support[0] else block_mat
87
90
  for i in full_qubit_support[1:]:
88
91
  if i == qubit_support[0]:
89
- other = torch.diag(block_mat.squeeze(0)) if diag_only else block_mat
92
+ other = block_mat
90
93
  if endianness == Endianness.LITTLE:
91
94
  mat = torch.kron(other, mat)
92
95
  else:
93
96
  mat = torch.kron(mat.contiguous(), other.contiguous())
94
97
  elif i not in qubit_support:
95
- other = torch.diag(IMAT.squeeze(0).to(device)) if diag_only else IMAT.to(device)
98
+ other = identity_mat
96
99
  if endianness == Endianness.LITTLE:
97
100
  mat = torch.kron(other.contiguous(), mat.contiguous())
98
101
  else:
@@ -263,13 +266,12 @@ def _gate_parameters(b: AbstractBlock, values: dict[str, torch.Tensor]) -> tuple
263
266
 
264
267
  def block_to_diagonal(
265
268
  block: AbstractBlock,
269
+ values: dict[str, TNumber | torch.Tensor] = dict(),
266
270
  qubit_support: tuple | list | None = None,
267
- use_full_support: bool = True,
271
+ use_full_support: bool = False,
268
272
  endianness: Endianness = Endianness.BIG,
269
273
  device: torch.device = None,
270
274
  ) -> torch.Tensor:
271
- if block.is_parametric:
272
- raise TypeError("Sparse observables cant be parametric.")
273
275
  if not block._is_diag_pauli:
274
276
  raise TypeError("Sparse observables can only be used on paulis which are diagonal.")
275
277
  if qubit_support is None:
@@ -281,17 +283,16 @@ def block_to_diagonal(
281
283
  if isinstance(block, (ChainBlock, KronBlock)):
282
284
  v = torch.ones(2**nqubits, dtype=torch.cdouble)
283
285
  for b in block.blocks:
284
- v *= block_to_diagonal(b, qubit_support)
286
+ v *= block_to_diagonal(b, values, qubit_support, device=device)
285
287
  if isinstance(block, AddBlock):
286
288
  t = torch.zeros(2**nqubits, dtype=torch.cdouble)
287
289
  for b in block.blocks:
288
- t += block_to_diagonal(b, qubit_support)
290
+ t += block_to_diagonal(b, values, qubit_support, device=device)
289
291
  v = t
290
292
  elif isinstance(block, ScaleBlock):
291
- _s = evaluate(block.scale, {}, as_torch=True) # type: ignore[attr-defined]
292
- _s = _s.detach() # type: ignore[union-attr]
293
- v = _s * block_to_diagonal(block.block, qubit_support)
294
-
293
+ _s = evaluate(block.scale, values, as_torch=True) # type: ignore[attr-defined]
294
+ _s = _s.detach().squeeze(0) # type: ignore[union-attr]
295
+ v = _s * block_to_diagonal(block.block, values, qubit_support, device=device)
295
296
  elif isinstance(block, PrimitiveBlock):
296
297
  v = _fill_identities(
297
298
  OPERATIONS_DICT[block.name],
@@ -299,6 +300,7 @@ def block_to_diagonal(
299
300
  qubit_support, # type: ignore [arg-type]
300
301
  diag_only=True,
301
302
  endianness=endianness,
303
+ device=device,
302
304
  )
303
305
  return v
304
306
 
@@ -308,7 +310,7 @@ def block_to_tensor(
308
310
  block: AbstractBlock,
309
311
  values: dict[str, TNumber | torch.Tensor] = {},
310
312
  qubit_support: tuple | None = None,
311
- use_full_support: bool = True,
313
+ use_full_support: bool = False,
312
314
  tensor_type: TensorType = TensorType.DENSE,
313
315
  endianness: Endianness = Endianness.BIG,
314
316
  device: torch.device = None,
@@ -338,18 +340,14 @@ def block_to_tensor(
338
340
  print(block_to_tensor(obs, tensor_type="SparseDiagonal"))
339
341
  ```
340
342
  """
343
+ from qadence.blocks import embedding
341
344
 
342
- # FIXME: default use_full_support to False. In general, it would
343
- # be more efficient to do that, and make sure that computations such
344
- # as observables only do the matmul of the size of the qubit support.
345
-
345
+ (ps, embed) = embedding(block)
346
+ values = embed(ps, values)
346
347
  if tensor_type == TensorType.DENSE:
347
- from qadence.blocks import embedding
348
-
349
- (ps, embed) = embedding(block)
350
348
  return _block_to_tensor_embedded(
351
349
  block,
352
- embed(ps, values),
350
+ values,
353
351
  qubit_support,
354
352
  use_full_support,
355
353
  endianness=endianness,
@@ -357,7 +355,7 @@ def block_to_tensor(
357
355
  )
358
356
 
359
357
  elif tensor_type == TensorType.SPARSEDIAGONAL:
360
- t = block_to_diagonal(block, endianness=endianness)
358
+ t = block_to_diagonal(block, values, endianness=endianness)
361
359
  indices, values, size = torch.nonzero(t), t[t != 0], len(t)
362
360
  indices = torch.stack((indices.flatten(), indices.flatten()))
363
361
  return torch.sparse_coo_tensor(indices, values, (size, size))
@@ -368,7 +366,7 @@ def _block_to_tensor_embedded(
368
366
  block: AbstractBlock,
369
367
  values: dict[str, TNumber | torch.Tensor] = {},
370
368
  qubit_support: tuple | None = None,
371
- use_full_support: bool = True,
369
+ use_full_support: bool = False,
372
370
  endianness: Endianness = Endianness.BIG,
373
371
  device: torch.device = None,
374
372
  ) -> torch.Tensor:
@@ -469,14 +467,13 @@ def _block_to_tensor_embedded(
469
467
  )
470
468
 
471
469
  elif isinstance(block, MatrixBlock):
472
- mat = block.matrix.unsqueeze(0)
473
- # FIXME: properly handle identity filling in matrix blocks
474
- # mat = _fill_identities(
475
- # block.matrix.unsqueeze(0),
476
- # block.qubit_support,
477
- # qubit_support,
478
- # endianness=endianness,
479
- # )
470
+ mat = _fill_identities(
471
+ block.matrix.unsqueeze(0),
472
+ block.qubit_support,
473
+ qubit_support,
474
+ endianness=endianness,
475
+ device=device,
476
+ )
480
477
 
481
478
  elif isinstance(block, SWAP):
482
479
  swap_block = _swap_block(block)
@@ -7,6 +7,8 @@ import numpy as np
7
7
  import torch
8
8
  from torch.linalg import eigvals
9
9
 
10
+ from math import log
11
+
10
12
  from qadence.blocks import PrimitiveBlock
11
13
  from qadence.noise import NoiseHandler
12
14
 
@@ -84,6 +86,8 @@ class MatrixBlock(PrimitiveBlock):
84
86
  if not self.is_unitary(matrix):
85
87
  logger.warning("Provided matrix is not unitary.")
86
88
  self.matrix = matrix.clone()
89
+ if int(log(self.matrix.size(1), 2)) != len(qubit_support):
90
+ raise ValueError("Provided matrix does not match the qubit_support length.")
87
91
  super().__init__(qubit_support, noise)
88
92
 
89
93
  @cached_property
@@ -17,6 +17,9 @@ from .hamiltonians import (
17
17
  ObservableConfig,
18
18
  total_magnetization,
19
19
  zz_hamiltonian,
20
+ total_magnetization_config,
21
+ zz_hamiltonian_config,
22
+ ising_hamiltonian_config,
20
23
  )
21
24
 
22
25
  from .rydberg_hea import rydberg_hea, rydberg_hea_layer
@@ -34,9 +37,12 @@ __all__ = [
34
37
  "iia",
35
38
  "hamiltonian_factory",
36
39
  "ising_hamiltonian",
37
- "ObservableConfig",
38
40
  "total_magnetization",
39
41
  "zz_hamiltonian",
42
+ "ObservableConfig",
43
+ "total_magnetization_config",
44
+ "zz_hamiltonian_config",
45
+ "ising_hamiltonian_config",
40
46
  "qft",
41
47
  "daqc_transform",
42
48
  "rydberg_hea",
@@ -7,11 +7,12 @@ from typing import Callable, List, Type, Union
7
7
  import numpy as np
8
8
  from torch import Tensor, double, ones, rand
9
9
  from typing_extensions import Any
10
+ from qadence.parameters import Parameter
10
11
 
11
12
  from qadence.blocks import AbstractBlock, add, block_is_qubit_hamiltonian
12
- from qadence.operations import N, X, Y, Z
13
+ from qadence.operations import N, X, Y, Z, H
13
14
  from qadence.register import Register
14
- from qadence.types import Interaction, ObservableTransform, TArray, TParameter
15
+ from qadence.types import Interaction, TArray, TParameter
15
16
 
16
17
  logger = getLogger(__name__)
17
18
 
@@ -239,7 +240,30 @@ def is_numeric(x: Any) -> bool:
239
240
 
240
241
  @dataclass
241
242
  class ObservableConfig:
242
- detuning: TDetuning
243
+ """ObservableConfig is a configuration class for defining the parameters of an observable Hamiltonian."""
244
+
245
+ interaction: Interaction | Callable | None = None
246
+ """
247
+ The type of interaction.
248
+
249
+ Available options from the Interaction enum are:
250
+ - Interaction.ZZ
251
+ - Interaction.NN
252
+ - Interaction.XY
253
+ - Interaction.XYZ
254
+
255
+ Alternatively, a custom interaction function can be defined.
256
+ Example:
257
+
258
+ def custom_int(i: int, j: int):
259
+ return X(i) @ X(j) + Y(i) @ Y(j)
260
+
261
+ n_qubits = 2
262
+
263
+ observable_config = ObservableConfig(interaction=custom_int, scale = 1.0, shift = 0.0)
264
+ observable = create_observable(register=4, config=observable_config)
265
+ """
266
+ detuning: TDetuning | None = None
243
267
  """
244
268
  Single qubit detuning of the observable Hamiltonian.
245
269
 
@@ -249,8 +273,6 @@ class ObservableConfig:
249
273
  """The scale by which to multiply the output of the observable."""
250
274
  shift: TParameter = 0.0
251
275
  """The shift to add to the output of the observable."""
252
- transformation_type: ObservableTransform = ObservableTransform.NONE # type: ignore[assignment]
253
- """The type of transformation."""
254
276
  trainable_transform: bool | None = None
255
277
  """
256
278
  Whether to have a trainable transformation on the output of the observable.
@@ -261,8 +283,73 @@ class ObservableConfig:
261
283
  """
262
284
 
263
285
  def __post_init__(self) -> None:
286
+ if self.interaction is None and self.detuning is None:
287
+ raise ValueError(
288
+ "Please provide an interaction and/or detuning for the Observable Hamiltonian."
289
+ )
290
+
264
291
  if is_numeric(self.scale) and is_numeric(self.shift):
265
- assert (
266
- self.trainable_transform is None
267
- ), f"If scale and shift are numbers, trainable_transform must be None. \
268
- But got: {self.trainable_transform}"
292
+ assert self.trainable_transform is None, (
293
+ "If scale and shift are numbers, trainable_transform must be None."
294
+ f"But got: {self.trainable_transform}"
295
+ )
296
+
297
+ # trasform the scale and shift into parameters
298
+ if self.trainable_transform is not None:
299
+ self.shift = Parameter(name=self.shift, trainable=self.trainable_transform)
300
+ self.scale = Parameter(name=self.scale, trainable=self.trainable_transform)
301
+ else:
302
+ self.shift = Parameter(self.shift)
303
+ self.scale = Parameter(self.scale)
304
+
305
+
306
+ def total_magnetization_config(
307
+ scale: TParameter = 1.0,
308
+ shift: TParameter = 0.0,
309
+ trainable_transform: bool | None = None,
310
+ ) -> ObservableConfig:
311
+ return ObservableConfig(
312
+ detuning=Z,
313
+ scale=scale,
314
+ shift=shift,
315
+ trainable_transform=trainable_transform,
316
+ )
317
+
318
+
319
+ def zz_hamiltonian_config(
320
+ scale: TParameter = 1.0,
321
+ shift: TParameter = 0.0,
322
+ trainable_transform: bool | None = None,
323
+ ) -> ObservableConfig:
324
+ return ObservableConfig(
325
+ interaction=Interaction.ZZ,
326
+ detuning=Z,
327
+ scale=scale,
328
+ shift=shift,
329
+ trainable_transform=trainable_transform,
330
+ )
331
+
332
+
333
+ def ising_hamiltonian_config(
334
+ scale: TParameter = 1.0,
335
+ shift: TParameter = 0.0,
336
+ trainable_transform: bool | None = None,
337
+ ) -> ObservableConfig:
338
+
339
+ def ZZ_Z_hamiltonian(i: int, j: int) -> AbstractBlock:
340
+ result = Z(i) @ Z(j)
341
+
342
+ if i == 0:
343
+ result += Z(j)
344
+ elif i == 1 and j == 2:
345
+ result += Z(0)
346
+
347
+ return result
348
+
349
+ return ObservableConfig(
350
+ interaction=ZZ_Z_hamiltonian,
351
+ detuning=Z,
352
+ scale=scale,
353
+ shift=shift,
354
+ trainable_transform=trainable_transform,
355
+ )
@@ -92,7 +92,9 @@ def pulse_experiment(
92
92
  )
93
93
  # Convert observable to Numpy types compatible with QuTip simulations.
94
94
  # Matrices are flipped to match QuTip conventions.
95
- converted_observable = [np.flip(block_to_tensor(obs).numpy()) for obs in observable]
95
+ converted_observable = [
96
+ np.flip(block_to_tensor(obs, use_full_support=True).numpy()) for obs in observable
97
+ ]
96
98
  # Create ZNE datasets by looping over batches.
97
99
  for observable in converted_observable:
98
100
  # Get expectation values at the end of the time serie [0,t]
@@ -130,7 +132,9 @@ def noise_level_experiment(
130
132
  )
131
133
  # Convert observable to Numpy types compatible with QuTip simulations.
132
134
  # Matrices are flipped to match QuTip conventions.
133
- converted_observable = [np.flip(block_to_tensor(obs).numpy()) for obs in observable]
135
+ converted_observable = [
136
+ np.flip(block_to_tensor(obs, use_full_support=True).numpy()) for obs in observable
137
+ ]
134
138
  # Create ZNE datasets by looping over batches.
135
139
  for observable in converted_observable:
136
140
  # Get expectation values at the end of the time serie [0,t]
@@ -2,8 +2,9 @@ from __future__ import annotations
2
2
 
3
3
  from .callbacks.saveload import load_checkpoint, load_model, write_checkpoint
4
4
  from .config import AnsatzConfig, FeatureMapConfig, TrainConfig
5
- from .constructors import create_ansatz, create_fm_blocks, observable_from_config
5
+ from .constructors import create_ansatz, create_fm_blocks, create_observable
6
6
  from .data import DictDataLoader, InfiniteTensorDataset, OptimizeResult, to_dataloader
7
+ from .information import InformationContent
7
8
  from .models import QNN
8
9
  from .optimize_step import optimize_step as default_optimize_step
9
10
  from .parameters import get_parameters, num_parameters, set_parameters
@@ -18,7 +19,7 @@ __all__ = [
18
19
  "DictDataLoader",
19
20
  "FeatureMapConfig",
20
21
  "load_checkpoint",
21
- "observable_from_config",
22
+ "create_observable",
22
23
  "QNN",
23
24
  "TrainConfig",
24
25
  "OptimizeResult",