ffsim 0.0.82__tar.gz → 0.0.84__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 (260) hide show
  1. {ffsim-0.0.82 → ffsim-0.0.84}/.gitignore +3 -0
  2. {ffsim-0.0.82 → ffsim-0.0.84}/PKG-INFO +1 -1
  3. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/lucj.ipynb +4 -4
  4. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/orbital-rotation.ipynb +9 -9
  5. {ffsim-0.0.82 → ffsim-0.0.84}/pyproject.toml +1 -1
  6. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/__init__.py +2 -0
  7. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/contract/__init__.py +2 -1
  8. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/contract/two_body.py +111 -1
  9. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/hamiltonians/__init__.py +2 -0
  10. ffsim-0.0.84/python/ffsim/hamiltonians/molecular_hamiltonian.py +984 -0
  11. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/linalg/util.py +159 -0
  12. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/molecular_data.py +4 -1
  13. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/lucj_pass_manager.py +17 -15
  14. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/random/__init__.py +2 -0
  15. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/random/random.py +59 -18
  16. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/rdm.py +7 -16
  17. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/testing/testing.py +46 -45
  18. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/orbital_optimization.py +9 -16
  19. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/contract/two_body_test.py +80 -0
  20. ffsim-0.0.84/tests/python/hamiltonians/molecular_hamiltonian_test.py +549 -0
  21. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/linalg/double_factorized_decomposition_test.py +3 -1
  22. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/linalg/givens_test.py +2 -3
  23. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/linalg/util_test.py +194 -0
  24. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/operators/coupled_cluster_test.py +21 -9
  25. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/operators/fermion_operator_test.py +119 -36
  26. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/lucj_pass_manager_test.py +31 -0
  27. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/random_test.py +35 -0
  28. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/states/rdm_test.py +14 -0
  29. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/states/states_test.py +3 -2
  30. ffsim-0.0.84/uv.lock +3467 -0
  31. ffsim-0.0.82/python/ffsim/hamiltonians/molecular_hamiltonian.py +0 -382
  32. ffsim-0.0.82/tests/python/hamiltonians/molecular_hamiltonian_test.py +0 -360
  33. ffsim-0.0.82/uv.lock +0 -2999
  34. {ffsim-0.0.82 → ffsim-0.0.84}/.cargo/config.toml +0 -0
  35. {ffsim-0.0.82 → ffsim-0.0.84}/.dockerignore +0 -0
  36. {ffsim-0.0.82 → ffsim-0.0.84}/.github/workflows/build-and-release.yml +0 -0
  37. {ffsim-0.0.82 → ffsim-0.0.84}/.github/workflows/check.yml +0 -0
  38. {ffsim-0.0.82 → ffsim-0.0.84}/.github/workflows/docker.yml +0 -0
  39. {ffsim-0.0.82 → ffsim-0.0.84}/.github/workflows/docs-dev.yml +0 -0
  40. {ffsim-0.0.82 → ffsim-0.0.84}/.github/workflows/docs-release.yml +0 -0
  41. {ffsim-0.0.82 → ffsim-0.0.84}/.github/workflows/test-latest-versions.yml +0 -0
  42. {ffsim-0.0.82 → ffsim-0.0.84}/.github/workflows/test-minimum-versions.yml +0 -0
  43. {ffsim-0.0.82 → ffsim-0.0.84}/.pre-commit-config.yaml +0 -0
  44. {ffsim-0.0.82 → ffsim-0.0.84}/CONTRIBUTING.md +0 -0
  45. {ffsim-0.0.82 → ffsim-0.0.84}/Cargo.lock +0 -0
  46. {ffsim-0.0.82 → ffsim-0.0.84}/Cargo.toml +0 -0
  47. {ffsim-0.0.82 → ffsim-0.0.84}/Dockerfile +0 -0
  48. {ffsim-0.0.82 → ffsim-0.0.84}/LICENSE +0 -0
  49. {ffsim-0.0.82 → ffsim-0.0.84}/README.md +0 -0
  50. {ffsim-0.0.82 → ffsim-0.0.84}/compose.yaml +0 -0
  51. {ffsim-0.0.82 → ffsim-0.0.84}/docs/_static/logo-dark.svg +0 -0
  52. {ffsim-0.0.82 → ffsim-0.0.84}/docs/_static/logo.svg +0 -0
  53. {ffsim-0.0.82 → ffsim-0.0.84}/docs/_templates/autosummary/class.rst +0 -0
  54. {ffsim-0.0.82 → ffsim-0.0.84}/docs/conf.py +0 -0
  55. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/diag-coulomb-hamiltonian.ipynb +0 -0
  56. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/double-factorized.ipynb +0 -0
  57. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/fermion-operator.ipynb +0 -0
  58. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/hamiltonians.ipynb +0 -0
  59. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/index.md +0 -0
  60. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/protocols.ipynb +0 -0
  61. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/qubit-gate-decompositions.ipynb +0 -0
  62. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/state-vectors-and-gates.ipynb +0 -0
  63. {ffsim-0.0.82 → ffsim-0.0.84}/docs/explanations/variational-ansatzes.ipynb +0 -0
  64. {ffsim-0.0.82 → ffsim-0.0.84}/docs/generate_api_docs.py +0 -0
  65. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/compress-orbital-rotation.ipynb +0 -0
  66. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/compute-expectation-values.ipynb +0 -0
  67. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/entanglement-forging.ipynb +0 -0
  68. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/index.md +0 -0
  69. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/qiskit-circuits-sim.ipynb +0 -0
  70. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/qiskit-lucj.ipynb +0 -0
  71. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/qiskit-merge-orbital-rotations.ipynb +0 -0
  72. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/qiskit-trotter.ipynb +0 -0
  73. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/sample-from-state-vectors.ipynb +0 -0
  74. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/sample-slater.ipynb +0 -0
  75. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/simulate-trotter-hubbard.ipynb +0 -0
  76. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/simulate-trotter-mol-ham.ipynb +0 -0
  77. {ffsim-0.0.82 → ffsim-0.0.84}/docs/how-to-guides/simulate-vqe.ipynb +0 -0
  78. {ffsim-0.0.82 → ffsim-0.0.84}/docs/index.md +0 -0
  79. {ffsim-0.0.82 → ffsim-0.0.84}/docs/install.md +0 -0
  80. {ffsim-0.0.82 → ffsim-0.0.84}/docs/tutorials/double-factorized-trotter.ipynb +0 -0
  81. {ffsim-0.0.82 → ffsim-0.0.84}/docs/tutorials/index.md +0 -0
  82. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_cistring.py +0 -0
  83. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_lib.pyi +0 -0
  84. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/__init__.py +0 -0
  85. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/contract/__init__.py +0 -0
  86. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/contract/diag_coulomb.py +0 -0
  87. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/contract/num_op_sum.py +0 -0
  88. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/fermion_operator.py +0 -0
  89. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/gates/__init__.py +0 -0
  90. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/gates/diag_coulomb.py +0 -0
  91. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/gates/num_op_sum.py +0 -0
  92. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/_slow/gates/orbital_rotation.py +0 -0
  93. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/contract/diag_coulomb.py +0 -0
  94. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/contract/num_op_sum.py +0 -0
  95. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/contract/one_body.py +0 -0
  96. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/gates/__init__.py +0 -0
  97. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/gates/basic_gates.py +0 -0
  98. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/gates/diag_coulomb.py +0 -0
  99. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/gates/num_op_sum.py +0 -0
  100. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/gates/orbital_rotation.py +0 -0
  101. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/gates/quad_ham.py +0 -0
  102. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/hamiltonians/diagonal_coulomb_hamiltonian.py +0 -0
  103. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/hamiltonians/double_factorized_hamiltonian.py +0 -0
  104. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/hamiltonians/single_factorized_hamiltonian.py +0 -0
  105. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/init_cache.py +0 -0
  106. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/linalg/__init__.py +0 -0
  107. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/linalg/double_factorized_decomposition.py +0 -0
  108. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/linalg/givens.py +0 -0
  109. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/linalg/linalg.py +0 -0
  110. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/linalg/predicates.py +0 -0
  111. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/operators/__init__.py +0 -0
  112. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/operators/common_operators.py +0 -0
  113. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/operators/coupled_cluster.py +0 -0
  114. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/operators/fermi_hubbard.py +0 -0
  115. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/operators/fermion_action.py +0 -0
  116. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/operators/fermion_operator.py +0 -0
  117. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/optimize/__init__.py +0 -0
  118. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/optimize/_util.py +0 -0
  119. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/optimize/linear_method.py +0 -0
  120. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/protocols/__init__.py +0 -0
  121. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/protocols/apply_unitary_protocol.py +0 -0
  122. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/protocols/approximate_equality_protocol.py +0 -0
  123. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/protocols/diagonal_protocol.py +0 -0
  124. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/protocols/fermion_operator_protocol.py +0 -0
  125. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/protocols/linear_operator_protocol.py +0 -0
  126. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/protocols/trace_protocol.py +0 -0
  127. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/py.typed +0 -0
  128. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/__init__.py +0 -0
  129. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/__init__.py +0 -0
  130. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/diag_coulomb.py +0 -0
  131. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/diag_coulomb_trotter_split_op.py +0 -0
  132. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/double_factorized_trotter.py +0 -0
  133. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/givens_ansatz.py +0 -0
  134. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/num_num_ansatz.py +0 -0
  135. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/num_op_sum.py +0 -0
  136. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/orbital_rotation.py +0 -0
  137. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/slater_determinant.py +0 -0
  138. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/gates/ucj.py +0 -0
  139. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/jordan_wigner.py +0 -0
  140. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/sampler.py +0 -0
  141. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/sim.py +0 -0
  142. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/transpiler_passes/__init__.py +0 -0
  143. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/transpiler_passes/drop_negligible.py +0 -0
  144. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/transpiler_passes/merge_orbital_rotations.py +0 -0
  145. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/transpiler_stages.py +0 -0
  146. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/qiskit/util.py +0 -0
  147. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/__init__.py +0 -0
  148. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/bitstring.py +0 -0
  149. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/dimensions.py +0 -0
  150. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/product_state_sum.py +0 -0
  151. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/sample_slater.py +0 -0
  152. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/slater.py +0 -0
  153. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/spin.py +0 -0
  154. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/states.py +0 -0
  155. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/states/wick.py +0 -0
  156. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/testing/__init__.py +0 -0
  157. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/trotter/__init__.py +0 -0
  158. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/trotter/_util.py +0 -0
  159. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/trotter/diagonal_coulomb_split_op.py +0 -0
  160. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/trotter/double_factorized.py +0 -0
  161. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/trotter/qdrift.py +0 -0
  162. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/__init__.py +0 -0
  163. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/givens.py +0 -0
  164. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/hopgate.py +0 -0
  165. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/multireference.py +0 -0
  166. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/num_num.py +0 -0
  167. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/uccsd.py +0 -0
  168. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/ucj_angles_spin_balanced.py +0 -0
  169. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/ucj_spin_balanced.py +0 -0
  170. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/ucj_spin_unbalanced.py +0 -0
  171. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/ucj_spinless.py +0 -0
  172. {ffsim-0.0.82 → ffsim-0.0.84}/python/ffsim/variational/util.py +0 -0
  173. {ffsim-0.0.82 → ffsim-0.0.84}/src/contract/diag_coulomb.rs +0 -0
  174. {ffsim-0.0.82 → ffsim-0.0.84}/src/contract/fermion_operator.rs +0 -0
  175. {ffsim-0.0.82 → ffsim-0.0.84}/src/contract/mod.rs +0 -0
  176. {ffsim-0.0.82 → ffsim-0.0.84}/src/contract/num_op_sum.rs +0 -0
  177. {ffsim-0.0.82 → ffsim-0.0.84}/src/fermion_operator.rs +0 -0
  178. {ffsim-0.0.82 → ffsim-0.0.84}/src/gates/diag_coulomb.rs +0 -0
  179. {ffsim-0.0.82 → ffsim-0.0.84}/src/gates/mod.rs +0 -0
  180. {ffsim-0.0.82 → ffsim-0.0.84}/src/gates/num_op_sum.rs +0 -0
  181. {ffsim-0.0.82 → ffsim-0.0.84}/src/gates/orbital_rotation.rs +0 -0
  182. {ffsim-0.0.82 → ffsim-0.0.84}/src/gates/phase_shift.rs +0 -0
  183. {ffsim-0.0.82 → ffsim-0.0.84}/src/jordan_wigner.rs +0 -0
  184. {ffsim-0.0.82 → ffsim-0.0.84}/src/lib.rs +0 -0
  185. {ffsim-0.0.82 → ffsim-0.0.84}/src/linalg/givens.rs +0 -0
  186. {ffsim-0.0.82 → ffsim-0.0.84}/src/linalg/mod.rs +0 -0
  187. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/__init__.py +0 -0
  188. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/__init__.py +0 -0
  189. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/contract/__init__.py +0 -0
  190. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/contract/diag_coulomb_test.py +0 -0
  191. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/contract/num_op_sum_test.py +0 -0
  192. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/gates/__init__.py +0 -0
  193. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/gates/diag_coulomb_test.py +0 -0
  194. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/gates/num_op_sum_test.py +0 -0
  195. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/_slow/gates/orbital_rotation_test.py +0 -0
  196. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/contract/__init__.py +0 -0
  197. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/contract/diag_coulomb_test.py +0 -0
  198. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/contract/num_op_sum_test.py +0 -0
  199. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/gates/__init__.py +0 -0
  200. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/gates/basic_gates_test.py +0 -0
  201. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/gates/diag_coulomb_test.py +0 -0
  202. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/gates/num_op_sum_test.py +0 -0
  203. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/gates/orbital_rotation_test.py +0 -0
  204. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/gates/quad_ham_test.py +0 -0
  205. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/hamiltonians/__init__.py +0 -0
  206. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/hamiltonians/diagonal_coulomb_hamiltonian_test.py +0 -0
  207. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/hamiltonians/double_factorized_hamiltonian_test.py +0 -0
  208. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/hamiltonians/single_factorized_hamiltonian_test.py +0 -0
  209. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/linalg/__init__.py +0 -0
  210. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/linalg/linalg_test.py +0 -0
  211. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/molecular_data_test.py +0 -0
  212. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/operators/__init__.py +0 -0
  213. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/operators/common_operators_test.py +0 -0
  214. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/operators/fermi_hubbard_test.py +0 -0
  215. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/operators/fermion_action_test.py +0 -0
  216. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/optimize/__init__.py +0 -0
  217. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/optimize/linear_method_test.py +0 -0
  218. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/protocols/__init__.py +0 -0
  219. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/protocols/trace_protocol_test.py +0 -0
  220. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/__init__.py +0 -0
  221. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/__init__.py +0 -0
  222. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/diag_coulomb_test.py +0 -0
  223. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/diag_coulomb_trotter_split_op_test.py +0 -0
  224. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/double_factorized_trotter_test.py +0 -0
  225. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/givens_ansatz_test.py +0 -0
  226. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/num_num_ansatz_test.py +0 -0
  227. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/num_op_sum_test.py +0 -0
  228. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/orbital_rotation_test.py +0 -0
  229. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/slater_determinant_test.py +0 -0
  230. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/gates/ucj_test.py +0 -0
  231. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/jordan_wigner_test.py +0 -0
  232. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/sampler_test.py +0 -0
  233. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/sim_test.py +0 -0
  234. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/transpiler_passes/__init__.py +0 -0
  235. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/transpiler_passes/drop_negligible_test.py +0 -0
  236. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/transpiler_passes/merge_orbital_rotations_test.py +0 -0
  237. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/qiskit/util_test.py +0 -0
  238. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/states/__init__.py +0 -0
  239. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/states/bitstring_test.py +0 -0
  240. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/states/sample_slater_test.py +0 -0
  241. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/states/slater_test.py +0 -0
  242. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/states/wick_test.py +0 -0
  243. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/test_data/orbital_rotation-0.npy +0 -0
  244. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/test_no_warnings.py +0 -0
  245. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/testing_test.py +0 -0
  246. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/trotter/__init__.py +0 -0
  247. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/trotter/diag_coulomb_split_op_test.py +0 -0
  248. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/trotter/double_factorized_test.py +0 -0
  249. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/trotter/qdrift_test.py +0 -0
  250. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/__init__.py +0 -0
  251. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/givens_test.py +0 -0
  252. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/hopgate_test.py +0 -0
  253. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/multireference_test.py +0 -0
  254. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/num_num_test.py +0 -0
  255. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/orbital_optimization_test.py +0 -0
  256. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/uccsd_test.py +0 -0
  257. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/ucj_angles_spin_balanced_test.py +0 -0
  258. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/ucj_spin_balanced_test.py +0 -0
  259. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/ucj_spin_unbalanced_test.py +0 -0
  260. {ffsim-0.0.82 → ffsim-0.0.84}/tests/python/variational/ucj_spinless_test.py +0 -0
@@ -134,6 +134,9 @@ dmypy.json
134
134
  # VS Code
135
135
  .vscode/
136
136
 
137
+ # macOS
138
+ .DS_Store
139
+
137
140
  # cibuildwheel
138
141
  wheelhouse/
139
142
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ffsim
3
- Version: 0.0.82
3
+ Version: 0.0.84
4
4
  Classifier: License :: OSI Approved :: Apache Software License
5
5
  Classifier: Programming Language :: Python
6
6
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -48,10 +48,10 @@
48
48
  "With this setup, orbitals with the same spin are connected with a line topology, while orbitals with different spins are connected when they share the same spatial orbital. This yields the following index constraints on the $\\mathbf{J}$ matrices:\n",
49
49
  "\n",
50
50
  "$$\n",
51
- "\\begin{align*}\n",
51
+ "\\begin{aligned}\n",
52
52
  "\\mathbf{J}^{\\alpha\\alpha} &: \\set{(p, p+1) \\; , \\; p = 0, \\ldots, N-2} \\\\\n",
53
53
  "\\mathbf{J}^{\\alpha\\beta} &: \\set{(p, p) \\;, \\; p = 0, \\ldots, N-1}\n",
54
- "\\end{align*}\n",
54
+ "\\end{aligned}\n",
55
55
  "$$\n",
56
56
  "\n",
57
57
  "In other words, if the $\\mathbf{J}$ matrices are nonzero only at the specified indices in the upper triangle, then the $e^{i \\mathcal{J}_k}$ term can be implemented on a square topology without using any swap gates, in constant depth. Of course, imposing such constraints on the ansatz makes it less expressive, so more ansatz repetitions may be required.\n"
@@ -121,10 +121,10 @@
121
121
  "\n",
122
122
  "The LUCJ ansatz specifies connectivity constraints described by index sets $S_{\\alpha \\alpha}$ and $S_{\\alpha \\beta}$. For example, for square lattice connectivity, the sets are\n",
123
123
  "$$\n",
124
- "\\begin{align*}\n",
124
+ "\\begin{aligned}\n",
125
125
  "S_{\\alpha \\alpha} &= \\set{(p, p+1) \\; , \\; p = 0, \\ldots, N-2} \\\\\n",
126
126
  "S_{\\alpha \\beta} &= \\set{(p, p) \\;, \\; p = 0, \\ldots, N-1}\n",
127
- "\\end{align*}\n",
127
+ "\\end{aligned}\n",
128
128
  "$$\n",
129
129
  "The index sets specify which diagonal Coulomb interactions are permitted, corresponding to which entries of the $Z^{(k)}$ matrices are allowed to be nonzero. Because the expression for the $t_2$-amplitudes does not distinguish separate $Z^{(k)}$ matrices for same-spin and opposite-spin interactions, we use a heuristic in which, during the optimization, entries of the $Z^{(k)}$ matrices with indices that appear in either set are allowed to be nonzero. As a result, some interactions still need to be discarded when constructing the LUCJ ansatz, but fewer than if no constraints were considered at all.\n",
130
130
  "\n",
@@ -13,9 +13,9 @@
13
13
  "An orbital rotation is described by an $N \\times N$ unitary matrix $\\mathbf{U}$ (here $N$ is the number spatial orbitals), and we denote the corresponding operator as $\\mathcal{U}$. This operator has the following action on the fermionic creation operators $\\set{a^\\dagger_{i\\sigma}}$:\n",
14
14
  "\n",
15
15
  "$$\n",
16
- "\\begin{align*}\n",
16
+ "\\begin{aligned}\n",
17
17
  " \\mathcal{U} a^\\dagger_{i\\sigma} \\mathcal{U}^\\dagger = \\sum_j \\mathbf{U}_{ji} a^\\dagger_{j\\sigma}.\n",
18
- "\\end{align*}\n",
18
+ "\\end{aligned}\n",
19
19
  "$$\n",
20
20
  "\n",
21
21
  "That is, $a^\\dagger_{i\\sigma}$ is mapped to a new operator $b^\\dagger_{i\\sigma}$ where $b^\\dagger_{i\\sigma}$ is a linear combination of the operators $\\set{a^\\dagger_{i\\sigma}}$ with coefficients given by the $i$-th column of $\\mathbf{U}$. The fact that $\\mathbf{U}$ is unitary can be used, together with the fermionic anticommutation relations, to show that the $\\set{b^\\dagger_{i\\sigma}}$ also satisfy the fermionic anticommutation relations. Thus, the $b^\\dagger_{i\\sigma}$ are creation operators in a rotated basis of orbitals.\n",
@@ -25,10 +25,10 @@
25
25
  "It is a theorem that $\\mathcal{U}$ can be written explicitly as\n",
26
26
  "\n",
27
27
  "$$\n",
28
- "\\begin{align*}\n",
28
+ "\\begin{aligned}\n",
29
29
  " \\mathcal{U} = \\prod_{\\sigma}\n",
30
- " \\exp\\left[\\sum_{ij} \\log\\left(\\mathbf{U}\\right)_{ij} a^\\dagger_{i\\sigma} a_{j\\sigma}\\right]\n",
31
- "\\end{align*}.\n",
30
+ " \\exp\\left[\\sum_{ij} \\log\\left(\\mathbf{U}\\right)_{ij} a^\\dagger_{i\\sigma} a_{j\\sigma}\\right] .\n",
31
+ "\\end{aligned}\n",
32
32
  "$$\n",
33
33
  "Sometimes, it is useful to specify the orbital rotation via the antihermitian matrix $\\mathbf{K} = \\log(\\mathbf{U})$ rather than $\\mathbf{U}$ itself. However, ffsim generally represents orbital rotations using the unitary matrix $\\mathbf{U}$.\n",
34
34
  "\n",
@@ -37,10 +37,10 @@
37
37
  "The mapping $\\mathbf{U} \\mapsto \\mathcal{U}$ satisfies the important homomorphism property:\n",
38
38
  "\n",
39
39
  "$$\n",
40
- "\\begin{align*}\n",
40
+ "\\begin{aligned}\n",
41
41
  " \\mathbf{U}^\\dagger &\\mapsto \\mathcal{U}^\\dagger, \\\\\n",
42
42
  " \\mathbf{U}_1 \\mathbf{U}_2 &\\mapsto \\mathcal{U}_1 \\mathcal{U}_2\n",
43
- "\\end{align*}\n",
43
+ "\\end{aligned}\n",
44
44
  "$$\n",
45
45
  "\n",
46
46
  "for any unitary matrices $\\mathbf{U}$, $\\mathbf{U}_1$, and $\\mathbf{U}_2$.\n",
@@ -50,11 +50,11 @@
50
50
  "The definitions given above assume that the same orbital rotation applies to both the spin-up and spin-down orbitals. However, it is possible for each spin sector to have an independent orbital rotation, in which case a pair of unitary matrices $(\\mathbf{U}^\\alpha, \\mathbf{U}^\\beta)$ needs to be specified. Letting $\\mathbf{K}^\\sigma = \\log(\\mathbf{U}^\\sigma)$, the definitions above then become\n",
51
51
  "\n",
52
52
  "$$\n",
53
- "\\begin{align*}\n",
53
+ "\\begin{aligned}\n",
54
54
  " \\mathcal{U} a^\\dagger_{i\\sigma} \\mathcal{U}^\\dagger &= \\sum_j \\mathbf{U}^{\\sigma}_{ji} a^\\dagger_{j\\sigma}, \\\\\n",
55
55
  " \\mathcal{U} &= \\prod_{\\sigma}\n",
56
56
  " \\exp\\left[\\sum_{ij} \\log\\left(\\mathbf{U}^{\\sigma}\\right)_{ij} a^\\dagger_{i\\sigma} a_{j\\sigma}\\right].\n",
57
- "\\end{align*}\n",
57
+ "\\end{aligned}\n",
58
58
  "$$\n",
59
59
  "\n",
60
60
  "## Application to time evolution by a quadratic Hamiltonian\n",
@@ -5,7 +5,7 @@ build-backend = "maturin"
5
5
  [project]
6
6
  name = "ffsim"
7
7
  requires-python = ">=3.11"
8
- version = "0.0.82"
8
+ version = "0.0.84"
9
9
  description = "Faster simulation of fermionic quantum circuits."
10
10
  readme = "README.md"
11
11
  license = { file = "LICENSE" }
@@ -31,6 +31,7 @@ from ffsim.hamiltonians import (
31
31
  DoubleFactorizedHamiltonian,
32
32
  MolecularHamiltonian,
33
33
  MolecularHamiltonianSpinless,
34
+ MolecularHamiltonianUnrestricted,
34
35
  SingleFactorizedHamiltonian,
35
36
  )
36
37
  from ffsim.init_cache import init_cache
@@ -133,6 +134,7 @@ __all__ = [
133
134
  "MolecularData",
134
135
  "MolecularHamiltonian",
135
136
  "MolecularHamiltonianSpinless",
137
+ "MolecularHamiltonianUnrestricted",
136
138
  "NumNumAnsatzOpSpinBalanced",
137
139
  "ProductStateSum",
138
140
  "ReducedDensityMatrix",
@@ -13,7 +13,7 @@
13
13
  from ffsim.contract.diag_coulomb import contract_diag_coulomb, diag_coulomb_linop
14
14
  from ffsim.contract.num_op_sum import contract_num_op_sum, num_op_sum_linop
15
15
  from ffsim.contract.one_body import contract_one_body, one_body_linop
16
- from ffsim.contract.two_body import two_body_linop
16
+ from ffsim.contract.two_body import two_body_linop, two_body_linop_unrestricted
17
17
 
18
18
  __all__ = [
19
19
  "contract_diag_coulomb",
@@ -23,4 +23,5 @@ __all__ = [
23
23
  "num_op_sum_linop",
24
24
  "one_body_linop",
25
25
  "two_body_linop",
26
+ "two_body_linop_unrestricted",
26
27
  ]
@@ -25,6 +25,12 @@ from pyscf.fci.direct_spin1 import (
25
25
  from pyscf.fci.direct_spin1 import (
26
26
  contract_2e as contract_2e_spin1,
27
27
  )
28
+ from pyscf.fci.direct_uhf import (
29
+ absorb_h1e as absorb_h1e_uhf,
30
+ )
31
+ from pyscf.fci.direct_uhf import (
32
+ contract_2e as contract_2e_uhf,
33
+ )
28
34
  from scipy.sparse.linalg import LinearOperator
29
35
 
30
36
  from ffsim import states
@@ -139,7 +145,6 @@ def _two_body_linop_complex(
139
145
 
140
146
  def rmatvec(vec: np.ndarray):
141
147
  result = contract_2e_nosym(
142
- # TODO come up with a way to test this transpose
143
148
  two_body_tensor.transpose(1, 0, 3, 2).conj(),
144
149
  vec,
145
150
  norb,
@@ -154,3 +159,108 @@ def _two_body_linop_complex(
154
159
  return LinearOperator(
155
160
  shape=(dim_, dim_), matvec=matvec, rmatvec=rmatvec, dtype=complex
156
161
  )
162
+
163
+
164
+ def two_body_linop_unrestricted(
165
+ two_body_tensors: np.ndarray,
166
+ norb: int,
167
+ nelec: tuple[int, int],
168
+ one_body_tensors: np.ndarray | None = None,
169
+ constant: float = 0,
170
+ ) -> LinearOperator:
171
+ r"""Convert spin-unrestricted two-body tensors to a linear operator.
172
+
173
+ The operator has the form
174
+
175
+ .. math::
176
+
177
+ \frac12 \sum_{pqrs} h^{\alpha\alpha}_{pqrs}
178
+ a^\dagger_{p\alpha} a^\dagger_{r\alpha} a_{s\alpha} a_{q\alpha}
179
+ + \sum_{pqrs} h^{\alpha\beta}_{pqrs}
180
+ a^\dagger_{p\alpha} a^\dagger_{r\beta} a_{s\beta} a_{q\alpha}
181
+ + \frac12 \sum_{pqrs} h^{\beta\beta}_{pqrs}
182
+ a^\dagger_{p\beta} a^\dagger_{r\beta} a_{s\beta} a_{q\beta}
183
+
184
+ where :math:`h^{\alpha\alpha}`, :math:`h^{\alpha\beta}`, and
185
+ :math:`h^{\beta\beta}` are tensors of coefficients in chemist ordering, whose spin
186
+ labels refer to the two *pairs* of indices: in :math:`h^{\alpha\beta}_{pqrs}`, the
187
+ indices :math:`pq` belong to spin alpha and the indices :math:`rs` belong to spin
188
+ beta. The alpha-beta term appears with coefficient 1 rather than :math:`\frac12`
189
+ because the beta-alpha term, whose tensor is
190
+ :math:`h^{\beta\alpha}_{pqrs} = h^{\alpha\beta}_{rspq}`, contributes the other half.
191
+ Consequently, the alpha-beta tensor need not be symmetric under exchanging its two
192
+ index pairs. See :class:`~ffsim.MolecularHamiltonianUnrestricted`.
193
+
194
+ Each tensor is assumed to be symmetric within each of its index pairs, that is,
195
+ :math:`h_{pqrs} = h_{qprs} = h_{pqsr}`.
196
+
197
+ Args:
198
+ two_body_tensors: The two-body tensors
199
+ :math:`(h^{\alpha\alpha}, h^{\alpha\beta}, h^{\beta\beta})`, as a single
200
+ Numpy array of shape ``(3, norb, norb, norb, norb)``.
201
+ norb: The number of spatial orbitals.
202
+ nelec: The number of alpha and beta electrons.
203
+ one_body_tensors: Optional one-body tensors
204
+ :math:`(h^{\alpha}, h^{\beta})`, as a single Numpy array of shape
205
+ ``(2, norb, norb)``, to absorb into the two-body operator.
206
+ constant: Optional constant to add to the operator.
207
+
208
+ Returns:
209
+ A LinearOperator that implements the action of the two-body tensors.
210
+
211
+ Raises:
212
+ NotImplementedError: The tensors have a complex data type. PySCF does not
213
+ provide a spin-unrestricted FCI contraction for complex integrals.
214
+ """
215
+ if np.iscomplexobj(two_body_tensors) or (
216
+ one_body_tensors is not None and np.iscomplexobj(one_body_tensors)
217
+ ):
218
+ raise NotImplementedError(
219
+ "The unrestricted two-body linear operator is not implemented for complex "
220
+ "tensors."
221
+ )
222
+ if one_body_tensors is None:
223
+ one_body_tensors = np.zeros((2, norb, norb))
224
+
225
+ n_alpha, n_beta = nelec
226
+ linkstr_index_a = gen_linkstr_index_trilidx(range(norb), n_alpha)
227
+ linkstr_index_b = gen_linkstr_index_trilidx(range(norb), n_beta)
228
+ link_index = (linkstr_index_a, linkstr_index_b)
229
+ absorbed_tensors = absorb_h1e_uhf(
230
+ tuple(np.ascontiguousarray(mat) for mat in one_body_tensors),
231
+ tuple(np.ascontiguousarray(tensor) for tensor in two_body_tensors),
232
+ norb,
233
+ nelec,
234
+ 0.5,
235
+ )
236
+
237
+ def matvec(vec: np.ndarray):
238
+ # Unlike direct_spin1.contract_2e, direct_uhf.contract_2e does not handle
239
+ # complex vectors, so the real and imaginary parts are contracted separately.
240
+ if np.iscomplexobj(vec):
241
+ result = contract_2e_uhf(
242
+ absorbed_tensors,
243
+ np.ascontiguousarray(vec.real),
244
+ norb,
245
+ nelec,
246
+ link_index=link_index,
247
+ ).astype(complex)
248
+ result.imag = contract_2e_uhf(
249
+ absorbed_tensors,
250
+ np.ascontiguousarray(vec.imag),
251
+ norb,
252
+ nelec,
253
+ link_index=link_index,
254
+ )
255
+ else:
256
+ result = contract_2e_uhf(
257
+ absorbed_tensors, vec, norb, nelec, link_index=link_index
258
+ )
259
+ if constant:
260
+ result += constant * vec
261
+ return result
262
+
263
+ dim_ = states.dim(norb, nelec)
264
+ return LinearOperator(
265
+ shape=(dim_, dim_), matvec=matvec, rmatvec=matvec, dtype=complex
266
+ )
@@ -18,6 +18,7 @@ from ffsim.hamiltonians.double_factorized_hamiltonian import DoubleFactorizedHam
18
18
  from ffsim.hamiltonians.molecular_hamiltonian import (
19
19
  MolecularHamiltonian,
20
20
  MolecularHamiltonianSpinless,
21
+ MolecularHamiltonianUnrestricted,
21
22
  )
22
23
  from ffsim.hamiltonians.single_factorized_hamiltonian import SingleFactorizedHamiltonian
23
24
 
@@ -26,5 +27,6 @@ __all__ = [
26
27
  "DoubleFactorizedHamiltonian",
27
28
  "MolecularHamiltonian",
28
29
  "MolecularHamiltonianSpinless",
30
+ "MolecularHamiltonianUnrestricted",
29
31
  "SingleFactorizedHamiltonian",
30
32
  ]