ffsim 0.0.73__tar.gz → 0.0.75__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 (254) hide show
  1. {ffsim-0.0.73 → ffsim-0.0.75}/PKG-INFO +1 -1
  2. ffsim-0.0.75/docs/_static/logo-dark.svg +1 -0
  3. ffsim-0.0.75/docs/_static/logo.svg +1 -0
  4. {ffsim-0.0.73 → ffsim-0.0.75}/docs/conf.py +7 -1
  5. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/qiskit-lucj.ipynb +93 -30
  6. {ffsim-0.0.73 → ffsim-0.0.75}/pyproject.toml +1 -1
  7. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_lib.pyi +3 -0
  8. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/gates/orbital_rotation.py +3 -3
  9. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/linalg/double_factorized_decomposition.py +48 -0
  10. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/linalg/givens.py +4 -75
  11. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/operators/fermion_action.py +7 -1
  12. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/__init__.py +6 -3
  13. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/transpiler_passes/__init__.py +4 -0
  14. ffsim-0.0.75/python/ffsim/qiskit/transpiler_passes/lucj_preset_pass_manager.py +521 -0
  15. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/slater.py +85 -32
  16. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/ucj_spin_balanced.py +126 -0
  17. {ffsim-0.0.73 → ffsim-0.0.75}/src/gates/orbital_rotation.rs +11 -25
  18. {ffsim-0.0.73 → ffsim-0.0.75}/src/lib.rs +2 -0
  19. ffsim-0.0.75/src/linalg/givens.rs +148 -0
  20. ffsim-0.0.75/src/linalg/mod.rs +11 -0
  21. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/linalg/double_factorized_decomposition_test.py +5 -48
  22. ffsim-0.0.75/tests/python/qiskit/transpiler_passes/lucj_preset_pass_manager_test.py +223 -0
  23. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/states/slater_test.py +58 -32
  24. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/ucj_spin_balanced_test.py +32 -0
  25. {ffsim-0.0.73 → ffsim-0.0.75}/uv.lock +1 -1
  26. {ffsim-0.0.73 → ffsim-0.0.75}/.dockerignore +0 -0
  27. {ffsim-0.0.73 → ffsim-0.0.75}/.github/workflows/build-and-release.yml +0 -0
  28. {ffsim-0.0.73 → ffsim-0.0.75}/.github/workflows/check.yml +0 -0
  29. {ffsim-0.0.73 → ffsim-0.0.75}/.github/workflows/docker.yml +0 -0
  30. {ffsim-0.0.73 → ffsim-0.0.75}/.github/workflows/docs-dev.yml +0 -0
  31. {ffsim-0.0.73 → ffsim-0.0.75}/.github/workflows/docs-release.yml +0 -0
  32. {ffsim-0.0.73 → ffsim-0.0.75}/.github/workflows/test-latest-versions.yml +0 -0
  33. {ffsim-0.0.73 → ffsim-0.0.75}/.github/workflows/test-minimum-versions.yml +0 -0
  34. {ffsim-0.0.73 → ffsim-0.0.75}/.gitignore +0 -0
  35. {ffsim-0.0.73 → ffsim-0.0.75}/.pre-commit-config.yaml +0 -0
  36. {ffsim-0.0.73 → ffsim-0.0.75}/CONTRIBUTING.md +0 -0
  37. {ffsim-0.0.73 → ffsim-0.0.75}/Cargo.lock +0 -0
  38. {ffsim-0.0.73 → ffsim-0.0.75}/Cargo.toml +0 -0
  39. {ffsim-0.0.73 → ffsim-0.0.75}/Dockerfile +0 -0
  40. {ffsim-0.0.73 → ffsim-0.0.75}/LICENSE +0 -0
  41. {ffsim-0.0.73 → ffsim-0.0.75}/README.md +0 -0
  42. {ffsim-0.0.73 → ffsim-0.0.75}/compose.yaml +0 -0
  43. {ffsim-0.0.73 → ffsim-0.0.75}/docs/_templates/autosummary/class.rst +0 -0
  44. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/diag-coulomb-hamiltonian.ipynb +0 -0
  45. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/double-factorized.ipynb +0 -0
  46. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/fermion-operator.ipynb +0 -0
  47. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/hamiltonians.ipynb +0 -0
  48. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/index.md +0 -0
  49. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/lucj.ipynb +0 -0
  50. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/orbital-rotation.ipynb +0 -0
  51. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/protocols.ipynb +0 -0
  52. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/qubit-gate-decompositions.ipynb +0 -0
  53. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/state-vectors-and-gates.ipynb +0 -0
  54. {ffsim-0.0.73 → ffsim-0.0.75}/docs/explanations/variational-ansatzes.ipynb +0 -0
  55. {ffsim-0.0.73 → ffsim-0.0.75}/docs/generate_api_docs.py +0 -0
  56. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/compute-expectation-values.ipynb +0 -0
  57. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/entanglement-forging.ipynb +0 -0
  58. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/index.md +0 -0
  59. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/qiskit-circuits-sim.ipynb +0 -0
  60. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/qiskit-merge-orbital-rotations.ipynb +0 -0
  61. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/qiskit-trotter.ipynb +0 -0
  62. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/sample-from-state-vectors.ipynb +0 -0
  63. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/sample-slater.ipynb +0 -0
  64. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/simulate-trotter-hubbard.ipynb +0 -0
  65. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/simulate-trotter-mol-ham.ipynb +0 -0
  66. {ffsim-0.0.73 → ffsim-0.0.75}/docs/how-to-guides/simulate-vqe.ipynb +0 -0
  67. {ffsim-0.0.73 → ffsim-0.0.75}/docs/index.md +0 -0
  68. {ffsim-0.0.73 → ffsim-0.0.75}/docs/install.md +0 -0
  69. {ffsim-0.0.73 → ffsim-0.0.75}/docs/tutorials/double-factorized-trotter.ipynb +0 -0
  70. {ffsim-0.0.73 → ffsim-0.0.75}/docs/tutorials/index.md +0 -0
  71. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/__init__.py +0 -0
  72. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_cistring.py +0 -0
  73. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/__init__.py +0 -0
  74. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/contract/__init__.py +0 -0
  75. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/contract/diag_coulomb.py +0 -0
  76. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/contract/num_op_sum.py +0 -0
  77. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/fermion_operator.py +0 -0
  78. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/gates/__init__.py +0 -0
  79. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/gates/diag_coulomb.py +0 -0
  80. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/gates/num_op_sum.py +0 -0
  81. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/_slow/gates/orbital_rotation.py +0 -0
  82. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/contract/__init__.py +0 -0
  83. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/contract/diag_coulomb.py +0 -0
  84. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/contract/num_op_sum.py +0 -0
  85. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/contract/one_body.py +0 -0
  86. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/contract/two_body.py +0 -0
  87. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/gates/__init__.py +0 -0
  88. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/gates/basic_gates.py +0 -0
  89. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/gates/diag_coulomb.py +0 -0
  90. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/gates/num_op_sum.py +0 -0
  91. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/gates/quad_ham.py +0 -0
  92. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/hamiltonians/__init__.py +0 -0
  93. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/hamiltonians/diagonal_coulomb_hamiltonian.py +0 -0
  94. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/hamiltonians/double_factorized_hamiltonian.py +0 -0
  95. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/hamiltonians/molecular_hamiltonian.py +0 -0
  96. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/hamiltonians/single_factorized_hamiltonian.py +0 -0
  97. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/init_cache.py +0 -0
  98. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/linalg/__init__.py +0 -0
  99. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/linalg/linalg.py +0 -0
  100. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/linalg/predicates.py +0 -0
  101. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/linalg/util.py +0 -0
  102. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/molecular_data.py +0 -0
  103. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/operators/__init__.py +0 -0
  104. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/operators/common_operators.py +0 -0
  105. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/operators/coupled_cluster.py +0 -0
  106. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/operators/fermi_hubbard.py +0 -0
  107. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/operators/fermion_operator.py +0 -0
  108. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/optimize/__init__.py +0 -0
  109. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/optimize/_util.py +0 -0
  110. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/optimize/linear_method.py +0 -0
  111. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/protocols/__init__.py +0 -0
  112. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/protocols/apply_unitary_protocol.py +0 -0
  113. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/protocols/approximate_equality_protocol.py +0 -0
  114. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/protocols/diagonal_protocol.py +0 -0
  115. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/protocols/fermion_operator_protocol.py +0 -0
  116. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/protocols/linear_operator_protocol.py +0 -0
  117. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/protocols/trace_protocol.py +0 -0
  118. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/py.typed +0 -0
  119. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/__init__.py +0 -0
  120. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/diag_coulomb.py +0 -0
  121. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/diag_coulomb_trotter_split_op.py +0 -0
  122. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/double_factorized_trotter.py +0 -0
  123. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/givens_ansatz.py +0 -0
  124. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/num_num_ansatz.py +0 -0
  125. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/num_op_sum.py +0 -0
  126. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/orbital_rotation.py +0 -0
  127. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/slater_determinant.py +0 -0
  128. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/gates/ucj.py +0 -0
  129. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/jordan_wigner.py +0 -0
  130. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/sampler.py +0 -0
  131. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/sim.py +0 -0
  132. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/transpiler_passes/drop_negligible.py +0 -0
  133. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/transpiler_passes/merge_orbital_rotations.py +0 -0
  134. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/transpiler_stages.py +0 -0
  135. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/qiskit/util.py +0 -0
  136. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/random/__init__.py +0 -0
  137. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/random/random.py +0 -0
  138. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/__init__.py +0 -0
  139. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/bitstring.py +0 -0
  140. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/dimensions.py +0 -0
  141. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/product_state_sum.py +0 -0
  142. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/rdm.py +0 -0
  143. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/sample_slater.py +0 -0
  144. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/spin.py +0 -0
  145. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/states.py +0 -0
  146. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/states/wick.py +0 -0
  147. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/testing/__init__.py +0 -0
  148. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/testing/testing.py +0 -0
  149. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/trotter/__init__.py +0 -0
  150. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/trotter/_util.py +0 -0
  151. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/trotter/diagonal_coulomb_split_op.py +0 -0
  152. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/trotter/double_factorized.py +0 -0
  153. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/trotter/qdrift.py +0 -0
  154. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/__init__.py +0 -0
  155. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/givens.py +0 -0
  156. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/hopgate.py +0 -0
  157. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/multireference.py +0 -0
  158. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/num_num.py +0 -0
  159. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/orbital_optimization.py +0 -0
  160. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/uccsd.py +0 -0
  161. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/ucj_angles_spin_balanced.py +0 -0
  162. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/ucj_spin_unbalanced.py +0 -0
  163. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/ucj_spinless.py +0 -0
  164. {ffsim-0.0.73 → ffsim-0.0.75}/python/ffsim/variational/util.py +0 -0
  165. {ffsim-0.0.73 → ffsim-0.0.75}/src/contract/diag_coulomb.rs +0 -0
  166. {ffsim-0.0.73 → ffsim-0.0.75}/src/contract/mod.rs +0 -0
  167. {ffsim-0.0.73 → ffsim-0.0.75}/src/contract/num_op_sum.rs +0 -0
  168. {ffsim-0.0.73 → ffsim-0.0.75}/src/fermion_operator.rs +0 -0
  169. {ffsim-0.0.73 → ffsim-0.0.75}/src/gates/diag_coulomb.rs +0 -0
  170. {ffsim-0.0.73 → ffsim-0.0.75}/src/gates/mod.rs +0 -0
  171. {ffsim-0.0.73 → ffsim-0.0.75}/src/gates/num_op_sum.rs +0 -0
  172. {ffsim-0.0.73 → ffsim-0.0.75}/src/gates/phase_shift.rs +0 -0
  173. {ffsim-0.0.73 → ffsim-0.0.75}/src/jordan_wigner.rs +0 -0
  174. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/__init__.py +0 -0
  175. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/__init__.py +0 -0
  176. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/contract/__init__.py +0 -0
  177. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/contract/diag_coulomb_test.py +0 -0
  178. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/contract/num_op_sum_test.py +0 -0
  179. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/gates/__init__.py +0 -0
  180. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/gates/diag_coulomb_test.py +0 -0
  181. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/gates/num_op_sum_test.py +0 -0
  182. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/_slow/gates/orbital_rotation_test.py +0 -0
  183. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/contract/__init__.py +0 -0
  184. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/contract/diag_coulomb_test.py +0 -0
  185. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/contract/num_op_sum_test.py +0 -0
  186. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/contract/two_body_test.py +0 -0
  187. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/gates/__init__.py +0 -0
  188. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/gates/basic_gates_test.py +0 -0
  189. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/gates/diag_coulomb_test.py +0 -0
  190. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/gates/num_op_sum_test.py +0 -0
  191. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/gates/orbital_rotation_test.py +0 -0
  192. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/gates/quad_ham_test.py +0 -0
  193. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/hamiltonians/__init__.py +0 -0
  194. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/hamiltonians/diagonal_coulomb_hamiltonian_test.py +0 -0
  195. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/hamiltonians/double_factorized_hamiltonian_test.py +0 -0
  196. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/hamiltonians/molecular_hamiltonian_test.py +0 -0
  197. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/hamiltonians/single_factorized_hamiltonian_test.py +0 -0
  198. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/linalg/__init__.py +0 -0
  199. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/linalg/givens_test.py +0 -0
  200. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/linalg/linalg_test.py +0 -0
  201. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/linalg/util_test.py +0 -0
  202. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/molecular_data_test.py +0 -0
  203. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/operators/__init__.py +0 -0
  204. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/operators/common_operators_test.py +0 -0
  205. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/operators/coupled_cluster_test.py +0 -0
  206. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/operators/fermi_hubbard_test.py +0 -0
  207. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/operators/fermion_action_test.py +0 -0
  208. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/operators/fermion_operator_test.py +0 -0
  209. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/optimize/__init__.py +0 -0
  210. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/optimize/linear_method_test.py +0 -0
  211. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/protocols/__init__.py +0 -0
  212. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/protocols/trace_protocol_test.py +0 -0
  213. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/__init__.py +0 -0
  214. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/__init__.py +0 -0
  215. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/diag_coulomb_test.py +0 -0
  216. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/diag_coulomb_trotter_split_op_test.py +0 -0
  217. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/double_factorized_trotter_test.py +0 -0
  218. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/givens_ansatz_test.py +0 -0
  219. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/num_num_ansatz_test.py +0 -0
  220. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/num_op_sum_test.py +0 -0
  221. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/orbital_rotation_test.py +0 -0
  222. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/slater_determinant_test.py +0 -0
  223. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/gates/ucj_test.py +0 -0
  224. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/jordan_wigner_test.py +0 -0
  225. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/sampler_test.py +0 -0
  226. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/sim_test.py +0 -0
  227. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/transpiler_passes/__init__.py +0 -0
  228. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/transpiler_passes/drop_negligible_test.py +0 -0
  229. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/transpiler_passes/merge_orbital_rotations_test.py +0 -0
  230. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/qiskit/util_test.py +0 -0
  231. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/random_test.py +0 -0
  232. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/states/__init__.py +0 -0
  233. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/states/bitstring_test.py +0 -0
  234. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/states/rdm_test.py +0 -0
  235. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/states/sample_slater_test.py +0 -0
  236. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/states/states_test.py +0 -0
  237. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/states/wick_test.py +0 -0
  238. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/test_data/orbital_rotation-0.npy +0 -0
  239. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/test_no_warnings.py +0 -0
  240. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/testing_test.py +0 -0
  241. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/trotter/__init__.py +0 -0
  242. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/trotter/diag_coulomb_split_op_test.py +0 -0
  243. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/trotter/double_factorized_test.py +0 -0
  244. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/trotter/qdrift_test.py +0 -0
  245. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/__init__.py +0 -0
  246. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/givens_test.py +0 -0
  247. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/hopgate_test.py +0 -0
  248. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/multireference_test.py +0 -0
  249. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/num_num_test.py +0 -0
  250. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/orbital_optimization_test.py +0 -0
  251. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/uccsd_test.py +0 -0
  252. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/ucj_angles_spin_balanced_test.py +0 -0
  253. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/ucj_spin_unbalanced_test.py +0 -0
  254. {ffsim-0.0.73 → ffsim-0.0.75}/tests/python/variational/ucj_spinless_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ffsim
3
- Version: 0.0.73
3
+ Version: 0.0.75
4
4
  Classifier: License :: OSI Approved :: Apache Software License
5
5
  Classifier: Programming Language :: Python
6
6
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72"><circle cx="36" cy="36" r="36" style="fill:#111"/><path d="M34.001 30.005c-.355 0-.508 0-.508-.254 0-.152.051-.305.102-.61 1.016-4.42 2.134-7.112 4.674-7.112.406 0 .812.102.812.407s-.254.254-.812.508c-.66.305-1.067 1.016-1.067 1.93 0 1.423 1.016 2.134 2.286 2.134 1.32 0 2.49-.864 2.49-2.743s-1.169-3.404-4.37-3.404c-4.927 0-7.67 3.505-9.347 8.382-.254.762-.305.762-1.016.762l-2.947.001c-.56 0-.813.254-.813.813q0 .762.762.762h2.946c.305 0 .407 0 .407.203 0 .102-.05.254-.102.508l-3.2 11.124c-1.423 4.98-2.337 6.605-4.37 6.605-.66 0-.914-.204-.914-.458 0-.406.458-.152 1.22-.66a2.22 2.22 0 0 0 1.016-1.88c0-1.32-.915-2.083-2.286-2.083-1.524 0-2.642 1.22-2.642 2.795 0 2.234 1.676 3.403 3.81 3.403 3.86 0 6.248-2.59 9.042-8.33 1.474-3.1 2.591-6.25 3.81-10.568l.051-.05c0-.153.407-.61.66-.61h7.198c.305 0 .407.001.407.204 0 .102-.05.254-.102.508l-3.2 11.124c-1.423 4.98-2.337 6.605-4.37 6.605-.66 0-.914-.204-.914-.458 0-.406.458-.152 1.22-.66a2.22 2.22 0 0 0 1.016-1.88c0-1.32-.915-2.083-2.286-2.083-1.524 0-2.642 1.22-2.642 2.795 0 2.234 1.676 3.403 3.81 3.403 3.86 0 6.248-2.59 9.042-8.33 1.474-3.1 2.591-6.25 3.81-10.568l.051-.05c0-.153.407-.61.66-.61h3.303c.558 0 .812-.254.812-.813q0-.762-.762-.762h-3.047c-.355 0-.508 0-.508-.254 0-.152.051-.305.102-.61 1.016-4.42 2.134-7.112 4.674-7.112.406 0 .812.102.812.407s-.254.254-.812.508c-.66.305-1.067 1.016-1.067 1.93 0 1.423 1.016 2.134 2.286 2.134 1.32 0 2.49-.864 2.49-2.743s-1.169-3.404-4.37-3.404c-4.927 0-7.67 3.505-9.347 8.382-.254.762-.305.762-1.016.762z" style="fill:#aaa"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72"><circle cx="36" cy="36" r="36" style="fill:#fff"/><path d="M34.001 30.005c-.355 0-.508 0-.508-.254 0-.152.051-.305.102-.61 1.016-4.42 2.134-7.112 4.674-7.112.406 0 .812.102.812.407s-.254.254-.812.508c-.66.305-1.067 1.016-1.067 1.93 0 1.423 1.016 2.134 2.286 2.134 1.32 0 2.49-.864 2.49-2.743s-1.169-3.404-4.37-3.404c-4.927 0-7.67 3.505-9.347 8.382-.254.762-.305.762-1.016.762l-2.947.001c-.56 0-.813.254-.813.813q0 .762.762.762h2.946c.305 0 .407 0 .407.203 0 .102-.05.254-.102.508l-3.2 11.124c-1.423 4.98-2.337 6.605-4.37 6.605-.66 0-.914-.204-.914-.458 0-.406.458-.152 1.22-.66a2.22 2.22 0 0 0 1.016-1.88c0-1.32-.915-2.083-2.286-2.083-1.524 0-2.642 1.22-2.642 2.795 0 2.234 1.676 3.403 3.81 3.403 3.86 0 6.248-2.59 9.042-8.33 1.474-3.1 2.591-6.25 3.81-10.568l.051-.05c0-.153.407-.61.66-.61h7.198c.305 0 .407.001.407.204 0 .102-.05.254-.102.508l-3.2 11.124c-1.423 4.98-2.337 6.605-4.37 6.605-.66 0-.914-.204-.914-.458 0-.406.458-.152 1.22-.66a2.22 2.22 0 0 0 1.016-1.88c0-1.32-.915-2.083-2.286-2.083-1.524 0-2.642 1.22-2.642 2.795 0 2.234 1.676 3.403 3.81 3.403 3.86 0 6.248-2.59 9.042-8.33 1.474-3.1 2.591-6.25 3.81-10.568l.051-.05c0-.153.407-.61.66-.61h3.303c.558 0 .812-.254.812-.813q0-.762-.762-.762h-3.047c-.355 0-.508 0-.508-.254 0-.152.051-.305.102-.61 1.016-4.42 2.134-7.112 4.674-7.112.406 0 .812.102.812.407s-.254.254-.812.508c-.66.305-1.067 1.016-1.067 1.93 0 1.423 1.016 2.134 2.286 2.134 1.32 0 2.49-.864 2.49-2.743s-1.169-3.404-4.37-3.404c-4.927 0-7.67 3.505-9.347 8.382-.254.762-.305.762-1.016.762z" style="fill:#000"/></svg>
@@ -41,8 +41,14 @@ html_theme_options = {
41
41
  "source_branch": "main",
42
42
  "source_directory": "docs/",
43
43
  "sidebar_qiskit_ecosystem_member": True,
44
+ "light_logo": "logo.svg",
45
+ "dark_logo": "logo-dark.svg",
44
46
  }
45
47
 
48
+ # HTML static files
49
+ html_static_path = ["_static"]
50
+ html_favicon = "_static/logo.svg"
51
+
46
52
  # autosummary options
47
53
  autosummary_generate = True
48
54
  templates_path = ["_templates"]
@@ -52,7 +58,7 @@ intersphinx_mapping = {
52
58
  "python": ("https://docs.python.org/3", None),
53
59
  "numpy": ("https://numpy.org/doc/stable", None),
54
60
  "scipy": ("https://docs.scipy.org/doc/scipy", None),
55
- "qiskit": ("https://docs.quantum.ibm.com/api/qiskit", None),
61
+ "qiskit": ("https://quantum.cloud.ibm.com/docs/api/qiskit", None),
56
62
  }
57
63
 
58
64
  # nbsphinx options (for tutorials)
@@ -12,18 +12,23 @@
12
12
  },
13
13
  {
14
14
  "cell_type": "code",
15
- "execution_count": 1,
15
+ "execution_count": 5,
16
16
  "id": "8301b83e",
17
17
  "metadata": {},
18
18
  "outputs": [],
19
19
  "source": [
20
+ "import warnings\n",
21
+ "\n",
20
22
  "import pyscf\n",
21
23
  "import pyscf.cc\n",
22
24
  "from qiskit.circuit import QuantumCircuit, QuantumRegister\n",
23
25
  "from qiskit.providers.fake_provider import GenericBackendV2\n",
24
- "from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n",
26
+ "from qiskit.transpiler import CouplingMap\n",
27
+ "\n",
28
+ "import ffsim\n",
29
+ "from ffsim.qiskit import generate_lucj_pass_manager\n",
25
30
  "\n",
26
- "import ffsim"
31
+ "warnings.formatwarning = lambda msg, *args, **kwargs: f\"Warning: {msg}\\n\""
27
32
  ]
28
33
  },
29
34
  {
@@ -33,12 +38,12 @@
33
38
  "source": [
34
39
  "## LUCJ circuit for a closed-shell molecule\n",
35
40
  "\n",
36
- "For a closed-shell system, use the spin-balanced LUCJ ansatz. This example creates an LUCJ circuit for a nitrogen molecule in the 6-31g basis."
41
+ "For a closed-shell system, use the spin-balanced LUCJ ansatz. This example creates an LUCJ circuit for a nitrogen molecule in the 6-31g basis and transpiled it for generic backend with square connectivity."
37
42
  ]
38
43
  },
39
44
  {
40
45
  "cell_type": "code",
41
- "execution_count": 2,
46
+ "execution_count": 6,
42
47
  "id": "2a3c1abb",
43
48
  "metadata": {},
44
49
  "outputs": [
@@ -46,24 +51,38 @@
46
51
  "name": "stdout",
47
52
  "output_type": "stream",
48
53
  "text": [
49
- "converged SCF energy = -108.835236570775\n",
54
+ "converged SCF energy = -108.835236570774\n",
50
55
  "norb = 16\n",
51
56
  "nelec = (5, 5)\n",
52
- "E(CCSD) = -109.0398256929734 E_corr = -0.2045891221988311\n"
57
+ "E(CCSD) = -109.0398256929733 E_corr = -0.20458912219883\n"
58
+ ]
59
+ },
60
+ {
61
+ "name": "stderr",
62
+ "output_type": "stream",
63
+ "text": [
64
+ "Warning: Backend cannot accommodate pairs_ab=[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15)].\n",
65
+ "Removing interaction (15, 15) from the end.\n",
66
+ "Warning: Backend cannot accommodate pairs_ab=[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14)].\n",
67
+ "Removing interaction (14, 14) from the end.\n",
68
+ "Warning: Backend cannot accommodate pairs_ab=[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13)].\n",
69
+ "Removing interaction (13, 13) from the end.\n",
70
+ "Warning: Backend cannot accommodate pairs_ab=[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12)].\n",
71
+ "Removing interaction (12, 12) from the end.\n"
53
72
  ]
54
73
  },
55
74
  {
56
75
  "data": {
57
76
  "text/plain": [
58
77
  "OrderedDict([('xx_plus_yy', 590),\n",
59
- " ('cp', 92),\n",
78
+ " ('cp', 84),\n",
60
79
  " ('p', 64),\n",
61
80
  " ('measure', 32),\n",
62
81
  " ('x', 10),\n",
63
82
  " ('barrier', 1)])"
64
83
  ]
65
84
  },
66
- "execution_count": 2,
85
+ "execution_count": 6,
67
86
  "metadata": {},
68
87
  "output_type": "execute_result"
69
88
  }
@@ -96,10 +115,33 @@
96
115
  "\n",
97
116
  "# Use 2 ansatz layers\n",
98
117
  "n_reps = 2\n",
99
- "# Use interactions implementable on a square lattice\n",
118
+ "# Define interactions\n",
100
119
  "pairs_aa = [(p, p + 1) for p in range(norb - 1)]\n",
101
- "pairs_ab = [(p, p) for p in range(norb)]\n",
120
+ "pairs_ab = (\n",
121
+ " None # Use generate_lucj_pass_manager() to find alpha-beta interactions later\n",
122
+ ")\n",
123
+ "\n",
124
+ "# Create a generic backend with square connectivity\n",
125
+ "cmap_square = CouplingMap.from_grid(num_rows=12, num_columns=10)\n",
126
+ "backend = GenericBackendV2(\n",
127
+ " num_qubits=cmap_square.size(),\n",
128
+ " basis_gates=[\"cp\", \"xx_plus_yy\", \"p\", \"x\", \"swap\"],\n",
129
+ " coupling_map=cmap_square,\n",
130
+ ")\n",
131
+ "\n",
132
+ "# Generate a LUCJ-specific configured Qiskit preset pass manager\n",
133
+ "# and get pairs_ab, implementable on a square coupling map.\n",
134
+ "# The pass manager is confifgured with pre-init passes suggested by\n",
135
+ "# ffsim (ffsim.qiskit.PRE_INIT) and an error-aware LUCJ-friendly layout\n",
136
+ "pass_manager, pairs_ab = generate_lucj_pass_manager(\n",
137
+ " backend=backend,\n",
138
+ " norb=norb,\n",
139
+ " connectivity=\"square\",\n",
140
+ " interaction_pairs=(pairs_aa, pairs_ab),\n",
141
+ " optimization_level=3,\n",
142
+ ")\n",
102
143
  "\n",
144
+ "# Use the backend implementable pairs_ab to construct the ucj_op\n",
103
145
  "ucj_op = ffsim.UCJOpSpinBalanced.from_t_amplitudes(\n",
104
146
  " ccsd.t2,\n",
105
147
  " t1=ccsd.t1,\n",
@@ -120,16 +162,22 @@
120
162
  "circuit.append(ffsim.qiskit.UCJOpSpinBalancedJW(ucj_op), qubits)\n",
121
163
  "circuit.measure_all()\n",
122
164
  "\n",
123
- "# Create a generic backend and transpile the circuit to it\n",
124
- "backend = GenericBackendV2(2 * norb, basis_gates=[\"cp\", \"xx_plus_yy\", \"p\", \"x\"])\n",
125
- "pass_manager = generate_preset_pass_manager(optimization_level=3, backend=backend)\n",
126
- "# Set the pre-initialization stage of the pass manager with passes suggested by ffsim\n",
127
- "pass_manager.pre_init = ffsim.qiskit.PRE_INIT\n",
165
+ "# Transpile the circuit with configured pass manager\n",
128
166
  "transpiled = pass_manager.run(circuit)\n",
129
167
  "\n",
130
168
  "transpiled.count_ops()"
131
169
  ]
132
170
  },
171
+ {
172
+ "cell_type": "markdown",
173
+ "id": "371b82fb",
174
+ "metadata": {},
175
+ "source": [
176
+ "As we initially set `pairs_ab=None`, the `generate_lucj_pass_manager()` starts with a default one. For square lattice, it is `[(0, 0), (1, 1), (2, 2), ..., (norb-1, norb-1)]`. However, if the hardware connectivity does not accommodate all starting pairs, then pairs are dropped from the end of the list until a valid layout is found, and a warning is raised. In the example above, last four pairs, from `(15, 15)` to `(12, 12)`, are dropped with a warning message showing the dropped pairs.\n",
177
+ "\n",
178
+ "Note that you can use a different `pairs_ab` during the `ucj_op` construction instead of the one returned by `generate_lucj_pass_manager`, but doing so may incur a higher SWAP overhead."
179
+ ]
180
+ },
133
181
  {
134
182
  "cell_type": "markdown",
135
183
  "id": "42f81ad1",
@@ -142,7 +190,7 @@
142
190
  },
143
191
  {
144
192
  "cell_type": "code",
145
- "execution_count": 3,
193
+ "execution_count": 7,
146
194
  "id": "9cbafb1d",
147
195
  "metadata": {},
148
196
  "outputs": [
@@ -151,27 +199,27 @@
151
199
  "output_type": "stream",
152
200
  "text": [
153
201
  "SCF not converged.\n",
154
- "SCF energy = -75.3484557072958\n",
202
+ "SCF energy = -75.3484557085522\n",
155
203
  "norb = 11\n",
156
204
  "nelec = (5, 4)\n",
157
205
  "\n",
158
206
  "WARN: RCCSD method does not support ROHF method. ROHF object is converted to UHF object and UCCSD method is called.\n",
159
207
  "\n",
160
- "E(UCCSD) = -75.4561973912185 E_corr = -0.1077416839226371\n"
208
+ "E(UCCSD) = -75.45619739099324 E_corr = -0.1077416824410066\n"
161
209
  ]
162
210
  },
163
211
  {
164
212
  "data": {
165
213
  "text/plain": [
166
- "OrderedDict([('xx_plus_yy', 716),\n",
214
+ "OrderedDict([('xx_plus_yy', 715),\n",
215
+ " ('cp', 136),\n",
167
216
  " ('p', 132),\n",
168
- " ('cp', 128),\n",
169
217
  " ('measure', 22),\n",
170
218
  " ('x', 9),\n",
171
219
  " ('barrier', 1)])"
172
220
  ]
173
221
  },
174
- "execution_count": 3,
222
+ "execution_count": 7,
175
223
  "metadata": {},
176
224
  "output_type": "execute_result"
177
225
  }
@@ -201,8 +249,19 @@
201
249
  "n_reps = (4, 2)\n",
202
250
  "# Use interactions implementable on a square lattice\n",
203
251
  "pairs_aa = [(p, p + 1) for p in range(norb - 1)]\n",
204
- "pairs_ab = [(p, p) for p in range(norb)]\n",
205
- "pairs_bb = [(p, p + 1) for p in range(norb - 1)]\n",
252
+ "pairs_ab = [(p, p) for p in range(norb)] # Update it later; can be ``None`` also\n",
253
+ "pairs_bb = [(p, p + 1) for p in range(norb - 1)] # Can be ``None`` as well\n",
254
+ "\n",
255
+ "# Generate the configured preset pass manager and implementable pairs_ab\n",
256
+ "pass_manager, pairs_ab = generate_lucj_pass_manager(\n",
257
+ " backend=backend,\n",
258
+ " norb=norb,\n",
259
+ " connectivity=\"square\",\n",
260
+ " interaction_pairs=(pairs_aa, pairs_ab, pairs_bb),\n",
261
+ " optimization_level=3,\n",
262
+ ")\n",
263
+ "\n",
264
+ "# Use the backend implementable pairs_ab to construct the ucj_op\n",
206
265
  "ucj_op = ffsim.UCJOpSpinUnbalanced.from_t_amplitudes(\n",
207
266
  " ccsd.t2,\n",
208
267
  " t1=ccsd.t1,\n",
@@ -223,20 +282,24 @@
223
282
  "circuit.append(ffsim.qiskit.UCJOpSpinUnbalancedJW(ucj_op), qubits)\n",
224
283
  "circuit.measure_all()\n",
225
284
  "\n",
226
- "# Create a generic backend and transpile the circuit to it\n",
227
- "backend = GenericBackendV2(2 * norb, basis_gates=[\"cp\", \"xx_plus_yy\", \"p\", \"x\"])\n",
228
- "pass_manager = generate_preset_pass_manager(optimization_level=3, backend=backend)\n",
229
- "# Set the pre-initialization stage of the pass manager with passes suggested by ffsim\n",
230
- "pass_manager.pre_init = ffsim.qiskit.PRE_INIT\n",
285
+ "# Transpile the circuit with configured pass manager\n",
231
286
  "transpiled = pass_manager.run(circuit)\n",
232
287
  "\n",
233
288
  "transpiled.count_ops()"
234
289
  ]
290
+ },
291
+ {
292
+ "cell_type": "markdown",
293
+ "id": "93963ffd",
294
+ "metadata": {},
295
+ "source": [
296
+ "As `norb=11` in this example, `pairs_ab = [(0, 0), ..., (10, 10)]`, which the backend can accommodate. Therefore, this example does not raise warnings about dropped pairs."
297
+ ]
235
298
  }
236
299
  ],
237
300
  "metadata": {
238
301
  "kernelspec": {
239
- "display_name": ".venv",
302
+ "display_name": "ffsim",
240
303
  "language": "python",
241
304
  "name": "python3"
242
305
  },
@@ -5,7 +5,7 @@ build-backend = "maturin"
5
5
  [project]
6
6
  name = "ffsim"
7
7
  requires-python = ">=3.10"
8
- version = "0.0.73"
8
+ version = "0.0.75"
9
9
  description = "Faster simulation of fermionic quantum circuits."
10
10
  readme = "README.md"
11
11
  license = { file = "LICENSE" }
@@ -39,6 +39,9 @@ def apply_phase_shift_in_place(
39
39
  def apply_givens_rotation_in_place(
40
40
  vec: np.ndarray, c: float, s: complex, slice1: np.ndarray, slice2: np.ndarray
41
41
  ) -> None: ...
42
+ def givens_decomposition(
43
+ mat: np.ndarray,
44
+ ) -> tuple[list[tuple[float, complex, int, int]], np.ndarray]: ...
42
45
  def apply_num_op_sum_evolution_in_place(
43
46
  vec: np.ndarray,
44
47
  phases: np.ndarray,
@@ -20,7 +20,7 @@ import numpy as np
20
20
  from pyscf.fci import cistring
21
21
 
22
22
  from ffsim._lib import apply_givens_rotation_in_place, apply_phase_shift_in_place
23
- from ffsim.linalg import GivensRotation, givens_decomposition
23
+ from ffsim.linalg import givens_decomposition
24
24
 
25
25
 
26
26
  @overload
@@ -157,8 +157,8 @@ def _apply_orbital_rotation_spinful(
157
157
  def _get_givens_decomposition(
158
158
  mat: np.ndarray | tuple[np.ndarray | None, np.ndarray | None],
159
159
  ) -> tuple[
160
- tuple[list[GivensRotation], np.ndarray] | None,
161
- tuple[list[GivensRotation], np.ndarray] | None,
160
+ tuple[list[tuple[float, complex, int, int]], np.ndarray] | None,
161
+ tuple[list[tuple[float, complex, int, int]], np.ndarray] | None,
162
162
  ]:
163
163
  if isinstance(mat, np.ndarray) and mat.ndim == 2:
164
164
  decomp = givens_decomposition(mat)
@@ -1131,3 +1131,51 @@ def _double_factorized_t2_alpha_beta_explicit(
1131
1131
 
1132
1132
  def _quadrature(mat: np.ndarray, sign: int):
1133
1133
  return 0.5 * (1 - sign * 1j) * (mat + sign * 1j * mat.T.conj())
1134
+
1135
+
1136
+ def reconstruct_t2(
1137
+ diag_coulomb_mats: np.ndarray, orbital_rotations: np.ndarray, nocc: int
1138
+ ) -> np.ndarray:
1139
+ """Reconstruct t2 amplitudes from double factorization tensors."""
1140
+ return (
1141
+ 1j
1142
+ * contract(
1143
+ "kpq,kap,kip,kbq,kjq->ijab",
1144
+ diag_coulomb_mats,
1145
+ orbital_rotations,
1146
+ orbital_rotations.conj(),
1147
+ orbital_rotations,
1148
+ orbital_rotations.conj(),
1149
+ )[:nocc, :nocc, nocc:, nocc:]
1150
+ )
1151
+
1152
+
1153
+ def reconstruct_t2_alpha_beta(
1154
+ diag_coulomb_mats: np.ndarray,
1155
+ orbital_rotations: np.ndarray,
1156
+ norb: int,
1157
+ nocc_a: int,
1158
+ nocc_b: int,
1159
+ ) -> np.ndarray:
1160
+ """Reconstruct alpha-beta t2 amplitudes from double factorization tensors."""
1161
+ n_terms = diag_coulomb_mats.shape[0]
1162
+ expanded_diag_coulomb_mats = np.zeros((n_terms, 2 * norb, 2 * norb))
1163
+ expanded_orbital_rotations = np.zeros((n_terms, 2 * norb, 2 * norb), dtype=complex)
1164
+ for k in range(n_terms):
1165
+ (mat_aa, mat_ab, mat_bb) = diag_coulomb_mats[k]
1166
+ expanded_diag_coulomb_mats[k] = np.block([[mat_aa, mat_ab], [mat_ab.T, mat_bb]])
1167
+ orbital_rotation_a, orbital_rotation_b = orbital_rotations[k]
1168
+ expanded_orbital_rotations[k] = scipy.linalg.block_diag(
1169
+ orbital_rotation_a, orbital_rotation_b
1170
+ )
1171
+ return (
1172
+ 1j
1173
+ * contract(
1174
+ "kpq,kap,kip,kbq,kjq->ijab",
1175
+ expanded_diag_coulomb_mats,
1176
+ expanded_orbital_rotations,
1177
+ expanded_orbital_rotations.conj(),
1178
+ expanded_orbital_rotations,
1179
+ expanded_orbital_rotations.conj(),
1180
+ )[:nocc_a, norb : norb + nocc_b, nocc_a:norb, norb + nocc_b :]
1181
+ )
@@ -17,7 +17,8 @@ from typing import NamedTuple
17
17
 
18
18
  import numpy as np
19
19
  from scipy.linalg.blas import zrotg as zrotg_
20
- from scipy.linalg.lapack import zrot
20
+
21
+ from ffsim import _lib
21
22
 
22
23
 
23
24
  class GivensRotation(NamedTuple):
@@ -92,7 +93,7 @@ def zrotg(a: complex, b: complex, tol=1e-12) -> tuple[float, complex]:
92
93
 
93
94
  def givens_decomposition(
94
95
  mat: np.ndarray,
95
- ) -> tuple[list[GivensRotation], np.ndarray]:
96
+ ) -> tuple[list[tuple[float, complex, int, int]], np.ndarray]:
96
97
  r"""Givens rotation decomposition of a unitary matrix.
97
98
 
98
99
  The Givens rotation decomposition of an :math:`n \times n` unitary matrix :math:`U`
@@ -145,76 +146,4 @@ def givens_decomposition(
145
146
 
146
147
  .. _Clements et al., "Optimal design for universal multiport interferometers" (2016): https://doi.org/10.1364/OPTICA.3.001460
147
148
  """ # noqa: E501
148
- n, _ = mat.shape
149
- current_matrix = mat.astype(complex, copy=True)
150
- left_rotations = []
151
- right_rotations = []
152
-
153
- # compute left and right Givens rotations
154
- for i in range(n - 1):
155
- if i % 2 == 0:
156
- # rotate columns by right multiplication
157
- for j in range(i + 1):
158
- target_index = i - j
159
- row = n - j - 1
160
- if not cmath.isclose(current_matrix[row, target_index], 0.0):
161
- # zero out element at target index in given row
162
- c, s = zrotg(
163
- current_matrix[row, target_index + 1],
164
- current_matrix[row, target_index],
165
- )
166
- right_rotations.append(
167
- GivensRotation(c, s, target_index + 1, target_index)
168
- )
169
- (
170
- current_matrix[:, target_index + 1],
171
- current_matrix[:, target_index],
172
- ) = zrot(
173
- current_matrix[:, target_index + 1],
174
- current_matrix[:, target_index],
175
- c,
176
- s,
177
- )
178
- else:
179
- # rotate rows by left multiplication
180
- for j in range(i + 1):
181
- target_index = n - i + j - 1
182
- col = j
183
- if not cmath.isclose(current_matrix[target_index, col], 0.0):
184
- # zero out element at target index in given column
185
- c, s = zrotg(
186
- current_matrix[target_index - 1, col],
187
- current_matrix[target_index, col],
188
- )
189
- left_rotations.append(
190
- GivensRotation(c, s, target_index - 1, target_index)
191
- )
192
- (
193
- current_matrix[target_index - 1],
194
- current_matrix[target_index],
195
- ) = zrot(
196
- current_matrix[target_index - 1],
197
- current_matrix[target_index],
198
- c,
199
- s,
200
- )
201
-
202
- # convert left rotations to right rotations
203
- for c, s, i, j in reversed(left_rotations):
204
- c, s = zrotg(c * current_matrix[j, j], s.conjugate() * current_matrix[i, i])
205
- right_rotations.append(
206
- # clamp c between -1 and 1 to account for floating point error
207
- GivensRotation(min(1.0, max(-1.0, c)), -s.conjugate(), i, j)
208
- )
209
-
210
- givens_mat = np.array([[c, -s], [s.conjugate(), c]])
211
- givens_mat[:, 0] *= current_matrix[i, i]
212
- givens_mat[:, 1] *= current_matrix[j, j]
213
- c, s = zrotg(givens_mat[1, 1], givens_mat[1, 0])
214
- new_givens_mat = np.array([[c, s], [-s.conjugate(), c]])
215
- phase_matrix = givens_mat @ new_givens_mat
216
- current_matrix[i, i] = phase_matrix[0, 0]
217
- current_matrix[j, j] = phase_matrix[1, 1]
218
-
219
- # return decomposition
220
- return right_rotations, np.diagonal(current_matrix)
149
+ return _lib.givens_decomposition(np.asarray(mat, dtype=complex))
@@ -14,7 +14,13 @@ from typing import NamedTuple
14
14
 
15
15
 
16
16
  class FermionAction(NamedTuple):
17
- """A fermionic action."""
17
+ """A fermionic action.
18
+
19
+ Args:
20
+ action: ``False`` = destroy (annihilate), ``True`` = create
21
+ spin: ``False`` = alpha (spin up), ``True`` = beta (spin down)
22
+ orb: Index of the orbital to act on
23
+ """
18
24
 
19
25
  action: bool # False = destroy (annihilate), True = create
20
26
  spin: bool # False = alpha, True = beta
@@ -35,7 +35,11 @@ from ffsim.qiskit.gates import (
35
35
  from ffsim.qiskit.jordan_wigner import jordan_wigner
36
36
  from ffsim.qiskit.sampler import FfsimSampler
37
37
  from ffsim.qiskit.sim import final_state_vector
38
- from ffsim.qiskit.transpiler_passes import DropNegligible, MergeOrbitalRotations
38
+ from ffsim.qiskit.transpiler_passes import (
39
+ DropNegligible,
40
+ MergeOrbitalRotations,
41
+ generate_lucj_pass_manager,
42
+ )
39
43
  from ffsim.qiskit.transpiler_stages import pre_init_passes
40
44
  from ffsim.qiskit.util import ffsim_vec_to_qiskit_vec, qiskit_vec_to_ffsim_vec
41
45
 
@@ -45,8 +49,6 @@ PRE_INIT = PassManager(list(pre_init_passes()))
45
49
  See :func:`pre_init_passes` for a description of the transpiler passes included in this
46
50
  pass manager.
47
51
  """
48
-
49
-
50
52
  __all__ = [
51
53
  "PRE_INIT",
52
54
  "DiagCoulombEvolutionJW",
@@ -72,6 +74,7 @@ __all__ = [
72
74
  "UCJOpSpinlessJW",
73
75
  "ffsim_vec_to_qiskit_vec",
74
76
  "final_state_vector",
77
+ "generate_lucj_pass_manager",
75
78
  "jordan_wigner",
76
79
  "pre_init_passes",
77
80
  "qiskit_vec_to_ffsim_vec",
@@ -11,9 +11,13 @@
11
11
  """Qiskit transpiler passes for fermionic quantum circuits."""
12
12
 
13
13
  from ffsim.qiskit.transpiler_passes.drop_negligible import DropNegligible
14
+ from ffsim.qiskit.transpiler_passes.lucj_preset_pass_manager import (
15
+ generate_lucj_pass_manager,
16
+ )
14
17
  from ffsim.qiskit.transpiler_passes.merge_orbital_rotations import MergeOrbitalRotations
15
18
 
16
19
  __all__ = [
17
20
  "DropNegligible",
18
21
  "MergeOrbitalRotations",
22
+ "generate_lucj_pass_manager",
19
23
  ]