ffsim 0.0.72__tar.gz → 0.0.74__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.
- {ffsim-0.0.72 → ffsim-0.0.74}/.github/workflows/test-latest-versions.yml +3 -3
- {ffsim-0.0.72 → ffsim-0.0.74}/.github/workflows/test-minimum-versions.yml +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/.gitignore +3 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/CONTRIBUTING.md +9 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/PKG-INFO +1 -1
- ffsim-0.0.74/docs/_templates/autosummary/class.rst +44 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/conf.py +13 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/diag-coulomb-hamiltonian.ipynb +16 -16
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/double-factorized.ipynb +9 -9
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/fermion-operator.ipynb +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/hamiltonians.ipynb +18 -18
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/lucj.ipynb +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/orbital-rotation.ipynb +19 -15
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/protocols.ipynb +13 -13
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/qubit-gate-decompositions.ipynb +9 -9
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/variational-ansatzes.ipynb +106 -67
- ffsim-0.0.74/docs/generate_api_docs.py +196 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/compute-expectation-values.ipynb +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/entanglement-forging.ipynb +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/qiskit-circuits-sim.ipynb +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/qiskit-merge-orbital-rotations.ipynb +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/sample-slater.ipynb +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/simulate-trotter-hubbard.ipynb +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/simulate-vqe.ipynb +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/tutorials/double-factorized-trotter.ipynb +5 -5
- {ffsim-0.0.72 → ffsim-0.0.74}/pyproject.toml +117 -7
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/__init__.py +16 -3
- ffsim-0.0.72/python/ffsim/cistring.py → ffsim-0.0.74/python/ffsim/_cistring.py +1 -20
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_lib.pyi +3 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/fermion_operator.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/contract/diag_coulomb.py +7 -5
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/contract/num_op_sum.py +5 -5
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/contract/one_body.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/contract/two_body.py +26 -48
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/gates/__init__.py +4 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/gates/basic_gates.py +40 -40
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/gates/diag_coulomb.py +6 -6
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/gates/num_op_sum.py +6 -5
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/gates/orbital_rotation.py +7 -7
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/gates/quad_ham.py +4 -4
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/hamiltonians/__init__.py +4 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/hamiltonians/diagonal_coulomb_hamiltonian.py +12 -12
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/hamiltonians/double_factorized_hamiltonian.py +16 -16
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/hamiltonians/molecular_hamiltonian.py +16 -24
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/hamiltonians/single_factorized_hamiltonian.py +7 -7
- ffsim-0.0.74/python/ffsim/init_cache.py +41 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/linalg/double_factorized_decomposition.py +113 -59
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/linalg/givens.py +7 -78
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/molecular_data.py +5 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/operators/__init__.py +20 -2
- ffsim-0.0.74/python/ffsim/operators/common_operators.py +190 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/operators/coupled_cluster.py +13 -13
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/operators/fermi_hubbard.py +13 -13
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/operators/fermion_action.py +7 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/optimize/linear_method.py +3 -3
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/protocols/__init__.py +4 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/protocols/apply_unitary_protocol.py +7 -7
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/protocols/linear_operator_protocol.py +5 -5
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/__init__.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/diag_coulomb.py +5 -5
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/diag_coulomb_trotter_split_op.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/double_factorized_trotter.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/num_num_ansatz.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/num_op_sum.py +5 -4
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/orbital_rotation.py +4 -4
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/slater_determinant.py +4 -4
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/ucj.py +4 -4
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/jordan_wigner.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/sampler.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/sim.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/util.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/random/random.py +16 -15
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/__init__.py +10 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/bitstring.py +4 -3
- {ffsim-0.0.72/python/ffsim → ffsim-0.0.74/python/ffsim/states}/dimensions.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/rdm.py +7 -3
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/sample_slater.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/slater.py +5 -6
- {ffsim-0.0.72/python/ffsim → ffsim-0.0.74/python/ffsim/states}/spin.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/states.py +8 -6
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/wick.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/testing/testing.py +12 -11
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/trotter/__init__.py +4 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/trotter/diagonal_coulomb_split_op.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/trotter/double_factorized.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/__init__.py +5 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/orbital_optimization.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/uccsd.py +66 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/ucj_spin_balanced.py +152 -19
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/ucj_spin_unbalanced.py +29 -22
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/ucj_spinless.py +24 -17
- {ffsim-0.0.72 → ffsim-0.0.74}/src/fermion_operator.rs +3 -3
- {ffsim-0.0.72 → ffsim-0.0.74}/src/gates/orbital_rotation.rs +9 -25
- {ffsim-0.0.72 → ffsim-0.0.74}/src/lib.rs +2 -0
- ffsim-0.0.74/src/linalg/givens.rs +148 -0
- ffsim-0.0.74/src/linalg/mod.rs +11 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/contract/diag_coulomb_test.py +5 -5
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/contract/num_op_sum_test.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/gates/diag_coulomb_test.py +7 -7
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/gates/num_op_sum_test.py +2 -2
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/gates/num_op_sum_test.py +1 -1
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/linalg/double_factorized_decomposition_test.py +5 -48
- ffsim-0.0.74/tests/python/operators/common_operators_test.py +117 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/operators/fermion_operator_test.py +9 -9
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/ucj_spin_balanced_test.py +32 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/uv.lock +1 -1
- ffsim-0.0.72/docs/api/ffsim.contract.rst +0 -6
- ffsim-0.0.72/docs/api/ffsim.linalg.rst +0 -6
- ffsim-0.0.72/docs/api/ffsim.optimize.rst +0 -6
- ffsim-0.0.72/docs/api/ffsim.qiskit.rst +0 -7
- ffsim-0.0.72/docs/api/ffsim.random.rst +0 -6
- ffsim-0.0.72/docs/api/ffsim.rst +0 -6
- ffsim-0.0.72/docs/api/ffsim.testing.rst +0 -6
- ffsim-0.0.72/docs/api/index.md +0 -13
- ffsim-0.0.72/python/ffsim/operators/common_operators.py +0 -44
- ffsim-0.0.72/tests/python/operators/common_operators_test.py +0 -36
- ffsim-0.0.72/tox.ini +0 -73
- {ffsim-0.0.72 → ffsim-0.0.74}/.dockerignore +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/.github/workflows/build-and-release.yml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/.github/workflows/check.yml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/.github/workflows/docker.yml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/.github/workflows/docs-dev.yml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/.github/workflows/docs-release.yml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/.pre-commit-config.yaml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/Cargo.lock +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/Cargo.toml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/Dockerfile +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/LICENSE +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/README.md +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/compose.yaml +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/index.md +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/explanations/state-vectors-and-gates.ipynb +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/index.md +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/qiskit-lucj.ipynb +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/qiskit-trotter.ipynb +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/sample-from-state-vectors.ipynb +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/how-to-guides/simulate-trotter-mol-ham.ipynb +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/index.md +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/install.md +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/docs/tutorials/index.md +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/contract/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/contract/diag_coulomb.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/contract/num_op_sum.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/gates/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/gates/diag_coulomb.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/gates/num_op_sum.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/_slow/gates/orbital_rotation.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/contract/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/linalg/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/linalg/linalg.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/linalg/predicates.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/linalg/util.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/operators/fermion_operator.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/optimize/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/optimize/_util.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/protocols/approximate_equality_protocol.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/protocols/diagonal_protocol.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/protocols/fermion_operator_protocol.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/protocols/trace_protocol.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/py.typed +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/gates/givens_ansatz.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/transpiler_passes/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/transpiler_passes/drop_negligible.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/transpiler_passes/merge_orbital_rotations.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/qiskit/transpiler_stages.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/random/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/states/product_state_sum.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/testing/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/trotter/_util.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/trotter/qdrift.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/givens.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/hopgate.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/multireference.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/num_num.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/ucj_angles_spin_balanced.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/python/ffsim/variational/util.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/contract/diag_coulomb.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/contract/mod.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/contract/num_op_sum.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/gates/diag_coulomb.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/gates/mod.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/gates/num_op_sum.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/gates/phase_shift.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/src/jordan_wigner.rs +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/contract/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/gates/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/_slow/gates/orbital_rotation_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/contract/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/contract/diag_coulomb_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/contract/num_op_sum_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/contract/two_body_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/gates/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/gates/basic_gates_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/gates/diag_coulomb_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/gates/orbital_rotation_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/gates/quad_ham_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/hamiltonians/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/hamiltonians/diagonal_coulomb_hamiltonian_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/hamiltonians/double_factorized_hamiltonian_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/hamiltonians/molecular_hamiltonian_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/hamiltonians/single_factorized_hamiltonian_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/linalg/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/linalg/givens_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/linalg/linalg_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/linalg/util_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/molecular_data_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/operators/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/operators/coupled_cluster_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/operators/fermi_hubbard_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/operators/fermion_action_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/optimize/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/optimize/linear_method_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/protocols/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/protocols/trace_protocol_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/diag_coulomb_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/diag_coulomb_trotter_split_op_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/double_factorized_trotter_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/givens_ansatz_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/num_num_ansatz_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/num_op_sum_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/orbital_rotation_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/slater_determinant_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/gates/ucj_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/jordan_wigner_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/sampler_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/sim_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/transpiler_passes/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/transpiler_passes/drop_negligible_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/transpiler_passes/merge_orbital_rotations_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/qiskit/util_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/random_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/states/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/states/bitstring_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/states/rdm_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/states/sample_slater_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/states/slater_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/states/states_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/states/wick_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/test_data/orbital_rotation-0.npy +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/test_no_warnings.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/testing_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/trotter/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/trotter/diag_coulomb_split_op_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/trotter/double_factorized_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/trotter/qdrift_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/__init__.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/givens_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/hopgate_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/multireference_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/num_num_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/orbital_optimization_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/uccsd_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/ucj_angles_spin_balanced_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/ucj_spin_unbalanced_test.py +0 -0
- {ffsim-0.0.72 → ffsim-0.0.74}/tests/python/variational/ucj_spinless_test.py +0 -0
|
@@ -33,7 +33,7 @@ jobs:
|
|
|
33
33
|
pip install tox
|
|
34
34
|
- name: Run tests
|
|
35
35
|
run: |
|
|
36
|
-
tox run -e
|
|
36
|
+
tox run -e test-${{ matrix.python-version }}
|
|
37
37
|
test-linux-arm:
|
|
38
38
|
runs-on: ubuntu-24.04-arm
|
|
39
39
|
strategy:
|
|
@@ -54,7 +54,7 @@ jobs:
|
|
|
54
54
|
pip install tox
|
|
55
55
|
- name: Run tests
|
|
56
56
|
run: |
|
|
57
|
-
tox run -e
|
|
57
|
+
tox run -e test-${{ matrix.python-version }}
|
|
58
58
|
test-macos:
|
|
59
59
|
runs-on: macos-latest
|
|
60
60
|
strategy:
|
|
@@ -72,4 +72,4 @@ jobs:
|
|
|
72
72
|
pip install tox
|
|
73
73
|
- name: Run tests
|
|
74
74
|
run: |
|
|
75
|
-
tox run -e
|
|
75
|
+
tox run -e test-${{ matrix.python-version }}
|
|
@@ -47,11 +47,12 @@ tox run -e <environment name>
|
|
|
47
47
|
|
|
48
48
|
substituting `<environment name>` with the name of the tox environment for the check. The following environments are available:
|
|
49
49
|
|
|
50
|
-
- `
|
|
50
|
+
- `test-3.10`, `test-3.11`, `test-3.12`, `test-3.13`, `test-3.14`: Run tests for a specific Python version
|
|
51
51
|
- `coverage`: Code coverage
|
|
52
52
|
- `type`: Type check
|
|
53
53
|
- `lint`: Lint check
|
|
54
54
|
- `format`: Format check
|
|
55
|
+
- `spell`: Spell check
|
|
55
56
|
- `docs`: Build documentation
|
|
56
57
|
|
|
57
58
|
## Run code checks directly
|
|
@@ -85,9 +86,16 @@ ruff check --fix
|
|
|
85
86
|
ruff format
|
|
86
87
|
```
|
|
87
88
|
|
|
89
|
+
### Run spell check
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
typos
|
|
93
|
+
```
|
|
94
|
+
|
|
88
95
|
### Build documentation
|
|
89
96
|
|
|
90
97
|
```bash
|
|
98
|
+
python docs/generate_api_docs.py
|
|
91
99
|
sphinx-build -b html -W docs/ docs/_build/html
|
|
92
100
|
```
|
|
93
101
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{{ fullname | escape | underline}}
|
|
2
|
+
|
|
3
|
+
.. currentmodule:: {{ module }}
|
|
4
|
+
|
|
5
|
+
.. autoclass:: {{ objname }}
|
|
6
|
+
:show-inheritance:
|
|
7
|
+
|
|
8
|
+
{% block methods %}
|
|
9
|
+
{%- set is_protocol = '__protocol_attrs__' in members and '__protocol_attrs__' not in inherited_members %}
|
|
10
|
+
{%- set ns = namespace(protocol_methods=[]) %}
|
|
11
|
+
{%- if is_protocol %}
|
|
12
|
+
{%- for item in all_methods %}
|
|
13
|
+
{%- if item.startswith('_') and not item.startswith('__') and item.endswith('_') and not item.endswith('__') %}
|
|
14
|
+
{%- set ns.protocol_methods = ns.protocol_methods + [item] %}
|
|
15
|
+
{%- endif %}
|
|
16
|
+
{%- endfor %}
|
|
17
|
+
{%- endif %}
|
|
18
|
+
{% if methods or ns.protocol_methods %}
|
|
19
|
+
.. rubric:: {{ _('Methods') }}
|
|
20
|
+
|
|
21
|
+
.. autosummary::
|
|
22
|
+
{% for item in methods if item not in inherited_members and item != '__init__' %}
|
|
23
|
+
~{{ name }}.{{ item }}
|
|
24
|
+
{%- endfor %}
|
|
25
|
+
{%- for item in ns.protocol_methods if item not in inherited_members %}
|
|
26
|
+
~{{ name }}.{{ item }}
|
|
27
|
+
{%- endfor %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
{%- for item in ns.protocol_methods %}
|
|
30
|
+
|
|
31
|
+
.. automethod:: {{ item }}
|
|
32
|
+
{%- endfor %}
|
|
33
|
+
{% endblock %}
|
|
34
|
+
|
|
35
|
+
{% block attributes %}
|
|
36
|
+
{% if attributes %}
|
|
37
|
+
.. rubric:: {{ _('Attributes') }}
|
|
38
|
+
|
|
39
|
+
.. autosummary::
|
|
40
|
+
{% for item in attributes if item not in inherited_members %}
|
|
41
|
+
~{{ name }}.{{ item }}
|
|
42
|
+
{%- endfor %}
|
|
43
|
+
{% endif %}
|
|
44
|
+
{% endblock %}
|
|
@@ -21,6 +21,7 @@ extensions = [
|
|
|
21
21
|
"sphinx.ext.napoleon",
|
|
22
22
|
"sphinx.ext.autodoc",
|
|
23
23
|
"sphinx.ext.autosummary",
|
|
24
|
+
"sphinx.ext.intersphinx",
|
|
24
25
|
"sphinx.ext.mathjax",
|
|
25
26
|
"sphinx.ext.viewcode",
|
|
26
27
|
"sphinx.ext.extlinks",
|
|
@@ -42,6 +43,18 @@ html_theme_options = {
|
|
|
42
43
|
"sidebar_qiskit_ecosystem_member": True,
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
# autosummary options
|
|
47
|
+
autosummary_generate = True
|
|
48
|
+
templates_path = ["_templates"]
|
|
49
|
+
|
|
50
|
+
# intersphinx options
|
|
51
|
+
intersphinx_mapping = {
|
|
52
|
+
"python": ("https://docs.python.org/3", None),
|
|
53
|
+
"numpy": ("https://numpy.org/doc/stable", None),
|
|
54
|
+
"scipy": ("https://docs.scipy.org/doc/scipy", None),
|
|
55
|
+
"qiskit": ("https://quantum.cloud.ibm.com/docs/api/qiskit", None),
|
|
56
|
+
}
|
|
57
|
+
|
|
45
58
|
# nbsphinx options (for tutorials)
|
|
46
59
|
nbsphinx_timeout = 300
|
|
47
60
|
nbsphinx_execute = "always"
|
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
"A diagonal Coulomb Hamiltonian has the form\n",
|
|
14
14
|
"\n",
|
|
15
15
|
"$$\n",
|
|
16
|
-
" H = \\sum_{\\sigma
|
|
17
|
-
" + \\frac12 \\sum_{\\sigma \\tau
|
|
18
|
-
" n_{\\tau
|
|
16
|
+
" H = \\sum_{\\substack{pq \\\\ \\sigma}} h_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
17
|
+
" + \\frac12 \\sum_{\\substack{pq \\\\ \\sigma \\tau}} J^{\\sigma \\tau}_{pq} n_{p\\sigma}\n",
|
|
18
|
+
" n_{q\\tau} + \\text{constant}\n",
|
|
19
19
|
"$$\n",
|
|
20
20
|
"\n",
|
|
21
|
-
"where $n_{\\sigma
|
|
21
|
+
"where $n_{p\\sigma} = a^\\dagger_{p\\sigma} a_{p\\sigma}$ is the number operator on orbital $p$ with spin $\\sigma$.\n",
|
|
22
22
|
"\n",
|
|
23
23
|
"The Hamiltonian is specified by the following data ($N$ is the number of spatial orbitals):\n",
|
|
24
24
|
"\n",
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
"- The diagonal Coulomb matrices $J^{\\sigma \\tau}$, given as a pair of $N \\times N$ real symmetric matrices specifying the independent coefficients for alpha-alpha and alpha-beta interactions. We require that $J^{\\alpha\\alpha} = J^{\\beta\\beta}$ and $J^{\\alpha\\beta} = J^{\\beta\\alpha}$, so only two matrices are needed.\n",
|
|
27
27
|
"- The constant, which is a real number.\n",
|
|
28
28
|
"\n",
|
|
29
|
-
"Compared to the general [molecular Hamiltonian](hamiltonians.ipynb), the two-body interaction is restricted to density-density form ($n_{\\sigma
|
|
29
|
+
"Compared to the general [molecular Hamiltonian](hamiltonians.ipynb), the two-body interaction is restricted to density-density form ($n_{p\\sigma} n_{q\\tau}$ terms). This restriction means the two-body part is specified by $O(N^2)$ parameters rather than $O(N^4)$, which enables more efficient simulation.\n",
|
|
30
30
|
"\n",
|
|
31
31
|
"## Data representation\n",
|
|
32
32
|
"\n",
|
|
33
|
-
"A diagonal Coulomb Hamiltonian is represented in ffsim using the [DiagonalCoulombHamiltonian](../api/ffsim.rst#ffsim.DiagonalCoulombHamiltonian) class. You can initialize it by passing the one-body tensor, the diagonal Coulomb matrices, and an optional constant."
|
|
33
|
+
"A diagonal Coulomb Hamiltonian is represented in ffsim using the [DiagonalCoulombHamiltonian](../api/stubs/ffsim.DiagonalCoulombHamiltonian.rst#ffsim.DiagonalCoulombHamiltonian) class. You can initialize it by passing the one-body tensor, the diagonal Coulomb matrices, and an optional constant."
|
|
34
34
|
]
|
|
35
35
|
},
|
|
36
36
|
{
|
|
@@ -90,15 +90,15 @@
|
|
|
90
90
|
"The [Fermi-Hubbard model](https://en.wikipedia.org/wiki/Hubbard_model) is a widely studied example of a Hamiltonian with diagonal Coulomb form, since its two-body interaction is an onsite density-density interaction. The two-dimensional Fermi-Hubbard Hamiltonian on a square lattice is given by\n",
|
|
91
91
|
"\n",
|
|
92
92
|
"$$\n",
|
|
93
|
-
" H = -t \\sum_{\\
|
|
94
|
-
" (a^\\dagger_{\\sigma
|
|
95
|
-
" + U \\sum_p n_{\\alpha
|
|
96
|
-
" - \\mu \\sum_p (n_{\\alpha
|
|
93
|
+
" H = -t \\sum_{\\substack{\\langle pq \\rangle \\\\ \\sigma}}\n",
|
|
94
|
+
" (a^\\dagger_{p\\sigma} a_{q\\sigma} + a^\\dagger_{q\\sigma} a_{p\\sigma})\n",
|
|
95
|
+
" + U \\sum_p n_{p\\alpha} n_{p\\beta}\n",
|
|
96
|
+
" - \\mu \\sum_p (n_{p\\alpha} + n_{p\\beta})\n",
|
|
97
97
|
"$$\n",
|
|
98
98
|
"\n",
|
|
99
99
|
"where $t$ is the tunneling amplitude, $U$ is the onsite interaction strength, and $\\mu$ is the chemical potential. The index $\\langle pq \\rangle$ runs over pairs of neighboring orbitals on the lattice.\n",
|
|
100
100
|
"\n",
|
|
101
|
-
"The two-dimensional Fermi-Hubbard Hamiltonian can be constructed as a [FermionOperator](../api/ffsim.rst#ffsim.FermionOperator) using the [fermi_hubbard_2d](../api/ffsim.rst#ffsim.fermi_hubbard_2d) function, and then converted to a `DiagonalCoulombHamiltonian` using the `from_fermion_operator` method."
|
|
101
|
+
"The two-dimensional Fermi-Hubbard Hamiltonian can be constructed as a [FermionOperator](../api/stubs/ffsim.FermionOperator.rst#ffsim.FermionOperator) using the [fermi_hubbard_2d](../api/stubs/ffsim.fermi_hubbard_2d.rst#ffsim.fermi_hubbard_2d) function, and then converted to a `DiagonalCoulombHamiltonian` using the `from_fermion_operator` method."
|
|
102
102
|
]
|
|
103
103
|
},
|
|
104
104
|
{
|
|
@@ -211,21 +211,21 @@
|
|
|
211
211
|
"where\n",
|
|
212
212
|
"\n",
|
|
213
213
|
"$$\n",
|
|
214
|
-
" H_0 = \\sum_{\\sigma
|
|
214
|
+
" H_0 = \\sum_{\\substack{pq \\\\ \\sigma}} h_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
215
215
|
"$$\n",
|
|
216
216
|
"\n",
|
|
217
217
|
"is a quadratic Hamiltonian and\n",
|
|
218
218
|
"\n",
|
|
219
219
|
"$$\n",
|
|
220
|
-
" H_1 = \\frac12 \\sum_{\\sigma \\tau
|
|
220
|
+
" H_1 = \\frac12 \\sum_{\\substack{pq \\\\ \\sigma \\tau}} J^{\\sigma \\tau}_{pq} n_{p\\sigma} n_{q\\tau}\n",
|
|
221
221
|
"$$\n",
|
|
222
222
|
"\n",
|
|
223
223
|
"is a diagonal Coulomb operator. Note,\n",
|
|
224
224
|
"\n",
|
|
225
225
|
"- $H_0$ can be simulated exactly using [orbital rotations](orbital-rotation.ipynb#Application-to-time-evolution-by-a-quadratic-Hamiltonian).\n",
|
|
226
|
-
"- $H_1$ can be simulated exactly using [apply_diag_coulomb_evolution](../api/ffsim.rst#ffsim.apply_diag_coulomb_evolution).\n",
|
|
226
|
+
"- $H_1$ can be simulated exactly using [apply_diag_coulomb_evolution](../api/stubs/ffsim.apply_diag_coulomb_evolution.rst#ffsim.apply_diag_coulomb_evolution).\n",
|
|
227
227
|
"\n",
|
|
228
|
-
"This split-operator approach is implemented in ffsim by the function [simulate_trotter_diag_coulomb_split_op](../api/ffsim.rst#ffsim.simulate_trotter_diag_coulomb_split_op). As with other Trotter functions in ffsim, the `order` parameter controls the order of the Trotter-Suzuki formula: `order=0` is the first-order asymmetric formula (the default), `order=1` is the first-order symmetric (second-order) formula, and so on.\n",
|
|
228
|
+
"This split-operator approach is implemented in ffsim by the function [simulate_trotter_diag_coulomb_split_op](../api/stubs/ffsim.simulate_trotter_diag_coulomb_split_op.rst#ffsim.simulate_trotter_diag_coulomb_split_op). As with other Trotter functions in ffsim, the `order` parameter controls the order of the Trotter-Suzuki formula: `order=0` is the first-order asymmetric formula (the default), `order=1` is the first-order symmetric (second-order) formula, and so on.\n",
|
|
229
229
|
"\n",
|
|
230
230
|
"In the following example, we compare the Trotter-approximated time evolution against the exact time evolution (computed using `expm_multiply`)."
|
|
231
231
|
]
|
|
@@ -299,7 +299,7 @@
|
|
|
299
299
|
"name": "python",
|
|
300
300
|
"nbconvert_exporter": "python",
|
|
301
301
|
"pygments_lexer": "ipython3",
|
|
302
|
-
"version": "3.12
|
|
302
|
+
"version": "3.13.12"
|
|
303
303
|
}
|
|
304
304
|
},
|
|
305
305
|
"nbformat": 4,
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"The molecular Hamiltonian is commonly written in the form\n",
|
|
14
14
|
"\n",
|
|
15
15
|
"$$\n",
|
|
16
|
-
" H = \\sum_{\\sigma
|
|
17
|
-
" + \\frac12 \\sum_{\\sigma \\tau
|
|
18
|
-
" a^\\dagger_{\\sigma
|
|
16
|
+
" H = \\sum_{\\substack{pq \\\\ \\sigma}} h_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
17
|
+
" + \\frac12 \\sum_{\\substack{pqrs \\\\ \\sigma \\tau}} h_{pqrs}\n",
|
|
18
|
+
" a^\\dagger_{p\\sigma} a^\\dagger_{r\\tau} a_{s\\tau} a_{q\\sigma}\n",
|
|
19
19
|
" + \\text{constant}.\n",
|
|
20
20
|
"$$\n",
|
|
21
21
|
"\n",
|
|
22
22
|
"This representation of the Hamiltonian is daunting for quantum simulations because the number of terms in the two-body part scales as $N^4$ where $N$ is the number of spatial orbitals. An alternative representation can be obtained by performing a \"double factorization\" of the two-body tensor $h_{pqrs}$:\n",
|
|
23
23
|
"\n",
|
|
24
24
|
"$$\n",
|
|
25
|
-
" H = \\sum_{\\sigma
|
|
25
|
+
" H = \\sum_{\\substack{pq \\\\ \\sigma}} h'_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
26
26
|
" + \\sum_{k=1}^L \\mathcal{U}_k \\mathcal{J}_k \\mathcal{U}_k^\\dagger\n",
|
|
27
27
|
" + \\text{constant}'.\n",
|
|
28
28
|
"$$\n",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"Here each $\\mathcal{U}_k$ is an [orbital rotation](orbital-rotation.ipynb) and each $\\mathcal{J}_k$ is a so-called diagonal Coulomb operator of the form\n",
|
|
31
31
|
"\n",
|
|
32
32
|
"$$\n",
|
|
33
|
-
" \\mathcal{J} = \\frac12\\sum_{\\sigma \\tau
|
|
33
|
+
" \\mathcal{J} = \\frac12\\sum_{\\substack{ij \\\\ \\sigma \\tau}} \\mathbf{J}_{ij} n_{i\\sigma} n_{j\\tau},\n",
|
|
34
34
|
"$$\n",
|
|
35
35
|
"\n",
|
|
36
|
-
"where $n_{\\sigma
|
|
36
|
+
"where $n_{i\\sigma} = a^\\dagger_{i\\sigma} a_{i\\sigma}$ is the occupation number operator and $\\mathbf{J}_{ij}$ is a real symmetric matrix. The one-body tensor and the constant have been updated to accommodate extra terms that arise from reordering fermionic ladder operators.\n",
|
|
37
37
|
"\n",
|
|
38
38
|
"For an exact factorization, $L$ is proportional to $N^2$. However, the two-body tensor often has low-rank structure, and the decomposition can be truncated while still maintaining an accurate representation. Thus, in practice, $L$ often scales only linearly with $N$, resulting in a much more compact representation that gives rise to more efficient schemes for simulating and measuring the Hamiltonian, which utilize efficient quantum circuits for orbital rotations and time evolution by a diagonal Coulomb operator.\n",
|
|
39
39
|
"\n",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"where\n",
|
|
81
81
|
"\n",
|
|
82
82
|
"$$\n",
|
|
83
|
-
"H_0 = \\sum_{\\sigma
|
|
83
|
+
"H_0 = \\sum_{\\substack{pq \\\\ \\sigma}} h'_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
84
84
|
"$$\n",
|
|
85
85
|
"\n",
|
|
86
86
|
"and for $k = 1, \\ldots, L$,\n",
|
|
@@ -92,9 +92,9 @@
|
|
|
92
92
|
"We have that\n",
|
|
93
93
|
"\n",
|
|
94
94
|
"- $H_0$ is a quadratic Hamiltonian and can be simulated as described on [this page](orbital-rotation.ipynb#Application-to-time-evolution-by-a-quadratic-Hamiltonian), and\n",
|
|
95
|
-
"- $H_k$ is a diagonal Coulomb operator (up to an orbital rotation) for $k = 1, \\ldots, L$, and ffsim includes the function [apply_diag_coulomb_evolution](../api/ffsim.rst#ffsim.apply_diag_coulomb_evolution) for simulating time evolution by such an operator.\n",
|
|
95
|
+
"- $H_k$ is a diagonal Coulomb operator (up to an orbital rotation) for $k = 1, \\ldots, L$, and ffsim includes the function [apply_diag_coulomb_evolution](../api/stubs/ffsim.apply_diag_coulomb_evolution.rst#ffsim.apply_diag_coulomb_evolution) for simulating time evolution by such an operator.\n",
|
|
96
96
|
"\n",
|
|
97
|
-
"Given the ability to simulate each of the individual terms, we can implement Trotter-Suzuki formulas for time evolution by the entire Hamiltonian. This is implemented in ffsim by the function [simulate_trotter_double_factorized](../api/ffsim.rst#ffsim.simulate_trotter_double_factorized), which implements higher-order Trotter-Suzuki formulas in addition to the first-order asymmetric formula mentioned previously. The first-order asymmetric formula corresponds to setting the argument `order=0`, which is the default. `order=1` corresponds to the first-order symmetric (commonly known as the second-order) formula, `order=2` corresponds to the second-order symmetric (fourth-order) formula, and so on."
|
|
97
|
+
"Given the ability to simulate each of the individual terms, we can implement Trotter-Suzuki formulas for time evolution by the entire Hamiltonian. This is implemented in ffsim by the function [simulate_trotter_double_factorized](../api/stubs/ffsim.simulate_trotter_double_factorized.rst#ffsim.simulate_trotter_double_factorized), which implements higher-order Trotter-Suzuki formulas in addition to the first-order asymmetric formula mentioned previously. The first-order asymmetric formula corresponds to setting the argument `order=0`, which is the default. `order=1` corresponds to the first-order symmetric (commonly known as the second-order) formula, `order=2` corresponds to the second-order symmetric (fourth-order) formula, and so on."
|
|
98
98
|
]
|
|
99
99
|
}
|
|
100
100
|
],
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"The FermionOperator class is used to represent a linear combination of products of fermionic creation and annihilation operators. For example:\n",
|
|
14
14
|
"\n",
|
|
15
15
|
"$$\n",
|
|
16
|
-
"0.5 a_{\\alpha
|
|
17
|
-
"+ (1 + i) a_{\\beta
|
|
16
|
+
"0.5 a_{0\\alpha}^\\dagger a_{3\\alpha} - 0.25 a_{3\\alpha}^\\dagger a_{0\\alpha}\n",
|
|
17
|
+
"+ (1 + i) a_{1\\beta}^\\dagger a_{5\\beta} a_{4\\alpha}^\\dagger.\n",
|
|
18
18
|
"$$\n",
|
|
19
19
|
"\n",
|
|
20
20
|
"Such operators are represented programmatically as a dictionary (hash table) that maps each term to its associated coefficient. An individual term is represented as a tuple of fermionic actions. Each action is described by three pieces of information:\n",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"ffsim includes [several classes](#hamiltonian-classes) for representing Hamiltonians in different forms. To take a concrete example, we'll use the molecular Hamiltonian of the form\n",
|
|
14
14
|
"\n",
|
|
15
15
|
"$$\n",
|
|
16
|
-
"H = \\sum_{\\sigma
|
|
17
|
-
" + \\frac12 \\sum_{\\sigma \\tau
|
|
18
|
-
" a^\\dagger_{\\sigma
|
|
16
|
+
"H = \\sum_{\\substack{pq \\\\ \\sigma}} h_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
17
|
+
" + \\frac12 \\sum_{\\substack{pqrs \\\\ \\sigma \\tau}} h_{pqrs}\n",
|
|
18
|
+
" a^\\dagger_{p\\sigma} a^\\dagger_{r\\tau} a_{s\\tau} a_{q\\sigma}\n",
|
|
19
19
|
" + \\text{constant}.\n",
|
|
20
20
|
"$$\n",
|
|
21
21
|
"\n",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"cell_type": "markdown",
|
|
54
54
|
"metadata": {},
|
|
55
55
|
"source": [
|
|
56
|
-
"The molecular Hamiltonian is represented in ffsim using the [MolecularHamiltonian](../api/ffsim.rst#ffsim.MolecularHamiltonian) class. You initialize the class by passing the three pieces of information (the constant is optional and defaults to zero if not specified):"
|
|
56
|
+
"The molecular Hamiltonian is represented in ffsim using the [MolecularHamiltonian](../api/stubs/ffsim.MolecularHamiltonian.rst#ffsim.MolecularHamiltonian) class. You initialize the class by passing the three pieces of information (the constant is optional and defaults to zero if not specified):"
|
|
57
57
|
]
|
|
58
58
|
},
|
|
59
59
|
{
|
|
@@ -199,12 +199,12 @@
|
|
|
199
199
|
"\n",
|
|
200
200
|
"### MolecularHamiltonian\n",
|
|
201
201
|
"\n",
|
|
202
|
-
"The [MolecularHamiltonian](../api/ffsim.rst#ffsim.MolecularHamiltonian) class stores the Hamiltonian in the standard second-quantized form with a one-body tensor, two-body tensor, and constant:\n",
|
|
202
|
+
"The [MolecularHamiltonian](../api/stubs/ffsim.MolecularHamiltonian.rst#ffsim.MolecularHamiltonian) class stores the Hamiltonian in the standard second-quantized form with a one-body tensor, two-body tensor, and constant:\n",
|
|
203
203
|
"\n",
|
|
204
204
|
"$$\n",
|
|
205
|
-
"H = \\sum_{\\sigma
|
|
206
|
-
" + \\frac12 \\sum_{\\sigma \\tau
|
|
207
|
-
" a^\\dagger_{\\sigma
|
|
205
|
+
"H = \\sum_{\\substack{pq \\\\ \\sigma}} h_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
206
|
+
" + \\frac12 \\sum_{\\substack{pqrs \\\\ \\sigma \\tau}} h_{pqrs}\n",
|
|
207
|
+
" a^\\dagger_{p\\sigma} a^\\dagger_{r\\tau} a_{s\\tau} a_{q\\sigma}\n",
|
|
208
208
|
" + \\text{constant}.\n",
|
|
209
209
|
"$$\n",
|
|
210
210
|
"\n",
|
|
@@ -221,16 +221,16 @@
|
|
|
221
221
|
"source": [
|
|
222
222
|
"### DoubleFactorizedHamiltonian\n",
|
|
223
223
|
"\n",
|
|
224
|
-
"The [DoubleFactorizedHamiltonian](../api/ffsim.rst#ffsim.DoubleFactorizedHamiltonian) class stores the Hamiltonian in the double-factorized representation, which decomposes the two-body tensor into a sum of diagonal Coulomb operators acting in rotated orbital bases:\n",
|
|
224
|
+
"The [DoubleFactorizedHamiltonian](../api/stubs/ffsim.DoubleFactorizedHamiltonian.rst#ffsim.DoubleFactorizedHamiltonian) class stores the Hamiltonian in the double-factorized representation, which decomposes the two-body tensor into a sum of diagonal Coulomb operators acting in rotated orbital bases:\n",
|
|
225
225
|
"\n",
|
|
226
226
|
"$$\n",
|
|
227
|
-
"H = \\sum_{\\sigma
|
|
228
|
-
" + \\frac12 \\sum_t \\sum_{\\sigma\\tau
|
|
229
|
-
" J^{(t)}_{ij} n^{(t)}_{\\sigma
|
|
227
|
+
"H = \\sum_{\\substack{pq \\\\ \\sigma}} \\kappa_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
228
|
+
" + \\frac12 \\sum_t \\sum_{\\substack{ij \\\\ \\sigma\\tau}}\n",
|
|
229
|
+
" J^{(t)}_{ij} n^{(t)}_{i\\sigma} n^{(t)}_{j\\tau}\n",
|
|
230
230
|
" + \\text{constant}'\n",
|
|
231
231
|
"$$\n",
|
|
232
232
|
"\n",
|
|
233
|
-
"where $n^{(t)}_{\\sigma
|
|
233
|
+
"where $n^{(t)}_{i\\sigma} = \\sum_{pq} U^{(t)}_{pi} a^\\dagger_{p\\sigma} a_{q\\sigma} U^{(t)*}_{qi}$ is the number operator in the rotated basis defined by the unitary matrix $U^{(t)}$.\n",
|
|
234
234
|
"\n",
|
|
235
235
|
"The data stored by this class consists of:\n",
|
|
236
236
|
"\n",
|
|
@@ -249,15 +249,15 @@
|
|
|
249
249
|
"source": [
|
|
250
250
|
"### DiagonalCoulombHamiltonian\n",
|
|
251
251
|
"\n",
|
|
252
|
-
"The [DiagonalCoulombHamiltonian](../api/ffsim.rst#ffsim.DiagonalCoulombHamiltonian) class stores a Hamiltonian whose two-body interaction is diagonal in the computational basis:\n",
|
|
252
|
+
"The [DiagonalCoulombHamiltonian](../api/stubs/ffsim.DiagonalCoulombHamiltonian.rst#ffsim.DiagonalCoulombHamiltonian) class stores a Hamiltonian whose two-body interaction is diagonal in the computational basis:\n",
|
|
253
253
|
"\n",
|
|
254
254
|
"$$\n",
|
|
255
|
-
"H = \\sum_{\\sigma
|
|
256
|
-
" + \\frac12 \\sum_{\\sigma \\tau
|
|
257
|
-
" n_{\\tau
|
|
255
|
+
"H = \\sum_{\\substack{pq \\\\ \\sigma}} h_{pq} a^\\dagger_{p\\sigma} a_{q\\sigma}\n",
|
|
256
|
+
" + \\frac12 \\sum_{\\substack{pq \\\\ \\sigma \\tau}} J^{\\sigma \\tau}_{pq} n_{p\\sigma}\n",
|
|
257
|
+
" n_{q\\tau} + \\text{constant}\n",
|
|
258
258
|
"$$\n",
|
|
259
259
|
"\n",
|
|
260
|
-
"where $n_{\\sigma
|
|
260
|
+
"where $n_{p\\sigma} = a_{p\\sigma}^\\dagger a_{p\\sigma}$ is the number operator.\n",
|
|
261
261
|
"\n",
|
|
262
262
|
"The data stored by this class consists of:\n",
|
|
263
263
|
"\n",
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"\n",
|
|
34
34
|
"ffsim implements two variants of the UCJ ansatz, a \"spin-balanced\" ansatz, which is appropriate to apply to a closed-shell reference state, and a \"spin-unbalanced\" ansatz, which is appropriate to apply to an open-shell initial reference state.\n",
|
|
35
35
|
"\n",
|
|
36
|
-
"In the spin-balanced ansatz, $\\mathbf{J}^{\\alpha\\alpha} = \\mathbf{J}^{\\beta\\beta}$ and $\\mathbf{J}^{\\alpha\\beta} = \\mathbf{J}^{\\beta\\alpha}$. As a result, each diagonal Coulomb operator is described by 2 matrices, $\\mathbf{J}^{\\alpha\\alpha}$ and $\\mathbf{J}^{\\alpha\\beta}$, and both of these matrices are symmetric. The spin-balanced UCJ ansatz is represented by the [UCJOpSpinBalanced](../api/ffsim.rst#ffsim.UCJOpSpinBalanced) class.\n",
|
|
36
|
+
"In the spin-balanced ansatz, $\\mathbf{J}^{\\alpha\\alpha} = \\mathbf{J}^{\\beta\\beta}$ and $\\mathbf{J}^{\\alpha\\beta} = \\mathbf{J}^{\\beta\\alpha}$. As a result, each diagonal Coulomb operator is described by 2 matrices, $\\mathbf{J}^{\\alpha\\alpha}$ and $\\mathbf{J}^{\\alpha\\beta}$, and both of these matrices are symmetric. The spin-balanced UCJ ansatz is represented by the [UCJOpSpinBalanced](../api/stubs/ffsim.UCJOpSpinBalanced.rst#ffsim.UCJOpSpinBalanced) class.\n",
|
|
37
37
|
"\n",
|
|
38
|
-
"In the spin-unbalanced ansatz, $\\mathbf{J}^{\\alpha\\alpha}$ and $\\mathbf{J}^{\\beta\\beta}$ are allowed to differ, and $\\mathbf{J}^{\\alpha\\beta}$ is no longer required to be symmetric. Since $\\mathbf{J}^{\\alpha\\beta}_{ij} = \\mathbf{J}^{\\beta\\alpha}_{ji}$, we don't need to store $\\mathbf{J}^{\\beta\\alpha}$ separately. Therefore, each diagonal Coulomb operator is described by 3 matrices, $\\mathbf{J}^{\\alpha\\alpha}$, $\\mathbf{J}^{\\alpha\\beta}$, and $\\mathbf{J}^{\\beta\\beta}$, and of these matrices, $\\mathbf{J}^{\\alpha\\alpha}$ and $\\mathbf{J}^{\\beta\\beta}$ are symmetric. The spin-unbalanced UCJ ansatz is represented by the [UCJOpSpinUnbalanced](../api/ffsim.rst#ffsim.UCJOpSpinUnbalanced) class.\n",
|
|
38
|
+
"In the spin-unbalanced ansatz, $\\mathbf{J}^{\\alpha\\alpha}$ and $\\mathbf{J}^{\\beta\\beta}$ are allowed to differ, and $\\mathbf{J}^{\\alpha\\beta}$ is no longer required to be symmetric. Since $\\mathbf{J}^{\\alpha\\beta}_{ij} = \\mathbf{J}^{\\beta\\alpha}_{ji}$, we don't need to store $\\mathbf{J}^{\\beta\\alpha}$ separately. Therefore, each diagonal Coulomb operator is described by 3 matrices, $\\mathbf{J}^{\\alpha\\alpha}$, $\\mathbf{J}^{\\alpha\\beta}$, and $\\mathbf{J}^{\\beta\\beta}$, and of these matrices, $\\mathbf{J}^{\\alpha\\alpha}$ and $\\mathbf{J}^{\\beta\\beta}$ are symmetric. The spin-unbalanced UCJ ansatz is represented by the [UCJOpSpinUnbalanced](../api/stubs/ffsim.UCJOpSpinUnbalanced.rst#ffsim.UCJOpSpinUnbalanced) class.\n",
|
|
39
39
|
"\n",
|
|
40
40
|
"## The local UCJ (LUCJ) ansatz\n",
|
|
41
41
|
"\n",
|
|
@@ -10,15 +10,15 @@
|
|
|
10
10
|
"\n",
|
|
11
11
|
"## Definition of orbital rotation\n",
|
|
12
12
|
"\n",
|
|
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_{\\sigma
|
|
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
16
|
"\\begin{align*}\n",
|
|
17
|
-
" \\mathcal{U} a^\\dagger_{\\sigma
|
|
17
|
+
" \\mathcal{U} a^\\dagger_{i\\sigma} \\mathcal{U}^\\dagger = \\sum_j \\mathbf{U}_{ji} a^\\dagger_{j\\sigma}.\n",
|
|
18
18
|
"\\end{align*}\n",
|
|
19
19
|
"$$\n",
|
|
20
20
|
"\n",
|
|
21
|
-
"That is, $a^\\dagger_{\\sigma
|
|
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",
|
|
22
22
|
"\n",
|
|
23
23
|
"### Explicit expression\n",
|
|
24
24
|
"\n",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"$$\n",
|
|
28
28
|
"\\begin{align*}\n",
|
|
29
29
|
" \\mathcal{U} = \\prod_{\\sigma}\n",
|
|
30
|
-
" \\exp\\left[\\sum_{ij} \\log\\left(\\mathbf{U}\\right)_{ij} a^\\dagger_{\\sigma
|
|
30
|
+
" \\exp\\left[\\sum_{ij} \\log\\left(\\mathbf{U}\\right)_{ij} a^\\dagger_{i\\sigma} a_{j\\sigma}\\right]\n",
|
|
31
31
|
"\\end{align*}.\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",
|
|
@@ -51,9 +51,9 @@
|
|
|
51
51
|
"\n",
|
|
52
52
|
"$$\n",
|
|
53
53
|
"\\begin{align*}\n",
|
|
54
|
-
" \\mathcal{U} a^\\dagger_{\\sigma
|
|
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
|
-
" \\exp\\left[\\sum_{ij} \\log\\left(\\mathbf{U}^{\\sigma}\\right)_{ij} a^\\dagger_{\\sigma
|
|
56
|
+
" \\exp\\left[\\sum_{ij} \\log\\left(\\mathbf{U}^{\\sigma}\\right)_{ij} a^\\dagger_{i\\sigma} a_{j\\sigma}\\right].\n",
|
|
57
57
|
"\\end{align*}\n",
|
|
58
58
|
"$$\n",
|
|
59
59
|
"\n",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"A quadratic Hamiltonian is an operator of the form (here we restrict the definition to Hamiltonians with particle number and spin Z symmetry)\n",
|
|
63
63
|
"\n",
|
|
64
64
|
"$$\n",
|
|
65
|
-
" \\mathcal{M} = \\sum_{\\sigma
|
|
65
|
+
" \\mathcal{M} = \\sum_{\\substack{ij \\\\ \\sigma}} \\mathbf{M}_{ij} a^\\dagger_{i\\sigma} a_{j\\sigma}\n",
|
|
66
66
|
"$$\n",
|
|
67
67
|
"\n",
|
|
68
68
|
"where $\\mathbf{M}$ is a Hermitian matrix. Time evolution by this Hamiltonian is given by the operator $e^{-i \\mathcal{M} t}$, where $t$ is the evolution time. Orbital rotations can be used to implement time evolution by a quadratic Hamiltonian using two different methods.\n",
|
|
@@ -72,10 +72,10 @@
|
|
|
72
72
|
"A quadratic Hamiltonian can always be rewritten as\n",
|
|
73
73
|
"\n",
|
|
74
74
|
"$$\n",
|
|
75
|
-
" \\mathcal{M} = \\mathcal{U} \\left(\\sum_{\\sigma
|
|
75
|
+
" \\mathcal{M} = \\mathcal{U} \\left(\\sum_{i \\sigma} \\lambda_i n_{i\\sigma}\\right)\\mathcal{U}^\\dagger\n",
|
|
76
76
|
"$$\n",
|
|
77
77
|
"\n",
|
|
78
|
-
"where the $\\set{\\lambda_i}$ are real numbers called orbital energies, $\\mathcal{U}$ is an orbital rotation, and $n_{\\sigma
|
|
78
|
+
"where the $\\set{\\lambda_i}$ are real numbers called orbital energies, $\\mathcal{U}$ is an orbital rotation, and $n_{i\\sigma} = a^\\dagger_{i\\sigma} a_{i\\sigma}$ is the occupation number operator. The $\\set{\\lambda_i}$ and the unitary matrix $\\mathbf{U}$ describing the orbital rotation are obtained from an eigendecomposition of $\\mathbf{M}$:\n",
|
|
79
79
|
"\n",
|
|
80
80
|
"$$\n",
|
|
81
81
|
" \\mathbf{M}_{ij} = \\sum_k \\lambda_k \\mathbf{U}_{ik} \\mathbf{U}_{jk}^*.\n",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"\n",
|
|
86
86
|
"- Compute the orbital energies $\\set{\\lambda_i}$ and the orbital rotation matrix $\\mathbf{U}$ by performing an eigendecomposition of $\\mathbf{M}$.\n",
|
|
87
87
|
"- Perform the orbital rotation $\\mathcal{U}^\\dagger$, which corresponds to the matrix $\\mathbf{U}^\\dagger$.\n",
|
|
88
|
-
"- Perform time evolution by the operator $\\sum_{\\sigma
|
|
88
|
+
"- Perform time evolution by the operator $\\sum_{i \\sigma} \\lambda_i n_{i\\sigma}$.\n",
|
|
89
89
|
"- Perform the orbital rotation $\\mathcal{U}^\\dagger$, which corresponds to the matrix $\\mathbf{U}$.\n",
|
|
90
90
|
"\n",
|
|
91
91
|
"### Method 2: Implement directly as an orbital rotation\n",
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"cell_type": "markdown",
|
|
136
136
|
"metadata": {},
|
|
137
137
|
"source": [
|
|
138
|
-
"The [apply_quad_ham_evolution](../api/ffsim.rst#ffsim.apply_quad_ham_evolution) function implements time evolution by a quadratic Hamiltonian. Internally, it implements the evolution directly as an orbital rotation (Method 2)."
|
|
138
|
+
"The [apply_quad_ham_evolution](../api/stubs/ffsim.apply_quad_ham_evolution.rst#ffsim.apply_quad_ham_evolution) function implements time evolution by a quadratic Hamiltonian. Internally, it implements the evolution directly as an orbital rotation (Method 2)."
|
|
139
139
|
]
|
|
140
140
|
},
|
|
141
141
|
{
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"source": [
|
|
156
156
|
"## Quantum circuit implementation\n",
|
|
157
157
|
"\n",
|
|
158
|
-
"An orbital rotation can be implemented as a quantum circuit by decomposing it into [Givens rotations](../api/ffsim.rst#ffsim.apply_givens_rotation). Under the [Jordan-Wigner transformation](https://en.wikipedia.org/wiki/Jordan%E2%80%93Wigner_transformation), the circuit can be implemented as a dense brickwork pattern of two-qubit rotations, followed by a single layer of single-qubit phase gates. The following code cell constructs and displays a Qiskit circuit for implementing an orbital rotation. Notice that the circuit consists of two independent sub-circuits acting on each spin sector."
|
|
158
|
+
"An orbital rotation can be implemented as a quantum circuit by decomposing it into [Givens rotations](../api/stubs/ffsim.apply_givens_rotation.rst#ffsim.apply_givens_rotation). Under the [Jordan-Wigner transformation](https://en.wikipedia.org/wiki/Jordan%E2%80%93Wigner_transformation), the circuit can be implemented as a dense brickwork pattern of two-qubit rotations, followed by a single layer of single-qubit phase gates. The following code cell constructs and displays a Qiskit circuit for implementing an orbital rotation. Notice that the circuit consists of two independent sub-circuits acting on each spin sector."
|
|
159
159
|
]
|
|
160
160
|
},
|
|
161
161
|
{
|
|
@@ -196,7 +196,11 @@
|
|
|
196
196
|
{
|
|
197
197
|
"cell_type": "markdown",
|
|
198
198
|
"metadata": {},
|
|
199
|
-
"source":
|
|
199
|
+
"source": [
|
|
200
|
+
"When an orbital rotation is applied to a single electronic configuration (in the qubit picture, a computational basis state), the quantum circuit implementation can be optimized to use fewer gates, resulting in a \"diamond\" pattern of gates rather than a dense \"brickwork\" pattern. For additional information, see [Jiang et al. (2018)](https://arxiv.org/abs/1711.05395).\n",
|
|
201
|
+
"\n",
|
|
202
|
+
"The following code cell constructs and displays an example of the optimized circuit."
|
|
203
|
+
]
|
|
200
204
|
},
|
|
201
205
|
{
|
|
202
206
|
"cell_type": "code",
|
|
@@ -245,10 +249,10 @@
|
|
|
245
249
|
"name": "python",
|
|
246
250
|
"nbconvert_exporter": "python",
|
|
247
251
|
"pygments_lexer": "ipython3",
|
|
248
|
-
"version": "3.12
|
|
252
|
+
"version": "3.13.12"
|
|
249
253
|
},
|
|
250
254
|
"orig_nbformat": 4
|
|
251
255
|
},
|
|
252
256
|
"nbformat": 4,
|
|
253
257
|
"nbformat_minor": 2
|
|
254
|
-
}
|
|
258
|
+
}
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"\n",
|
|
20
20
|
"| Protocol | Method | Function | Description |\n",
|
|
21
21
|
"|---|---|---|---|\n",
|
|
22
|
-
"| [SupportsApplyUnitary](../api/ffsim.rst#ffsim.SupportsApplyUnitary) | `_apply_unitary_` | [ffsim.apply_unitary](../api/ffsim.rst#ffsim.apply_unitary) | Apply a unitary transformation to a state vector. |\n",
|
|
23
|
-
"| [SupportsLinearOperator](../api/ffsim.rst#ffsim.SupportsLinearOperator) | `_linear_operator_` | [ffsim.linear_operator](../api/ffsim.rst#ffsim.linear_operator) | Convert to a [SciPy LinearOperator](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.LinearOperator.html). |\n",
|
|
24
|
-
"| [SupportsFermionOperator](../api/ffsim.rst#ffsim.SupportsFermionOperator) | `_fermion_operator_` | [ffsim.fermion_operator](../api/ffsim.rst#ffsim.fermion_operator) | Convert to a [FermionOperator](../api/ffsim.rst#ffsim.FermionOperator). |\n",
|
|
25
|
-
"| [SupportsTrace](../api/ffsim.rst#ffsim.SupportsTrace) | `_trace_` | [ffsim.trace](../api/ffsim.rst#ffsim.trace) | Compute the trace of a linear operator. |\n",
|
|
26
|
-
"| [SupportsDiagonal](../api/ffsim.rst#ffsim.SupportsDiagonal) | `_diag_` | [ffsim.diag](../api/ffsim.rst#ffsim.diag) | Return the diagonal entries of a linear operator.|\n",
|
|
27
|
-
"| [SupportsApproximateEquality](../api/ffsim.rst#ffsim.SupportsApproximateEquality) | `_approx_eq_` | [ffsim.approx_eq](../api/ffsim.rst#ffsim.approx_eq) | Compare objects with numerical tolerance. |"
|
|
22
|
+
"| [SupportsApplyUnitary](../api/stubs/ffsim.SupportsApplyUnitary.rst#ffsim.SupportsApplyUnitary) | `_apply_unitary_` | [ffsim.apply_unitary](../api/stubs/ffsim.apply_unitary.rst#ffsim.apply_unitary) | Apply a unitary transformation to a state vector. |\n",
|
|
23
|
+
"| [SupportsLinearOperator](../api/stubs/ffsim.SupportsLinearOperator.rst#ffsim.SupportsLinearOperator) | `_linear_operator_` | [ffsim.linear_operator](../api/stubs/ffsim.linear_operator.rst#ffsim.linear_operator) | Convert to a [SciPy LinearOperator](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.LinearOperator.html). |\n",
|
|
24
|
+
"| [SupportsFermionOperator](../api/stubs/ffsim.SupportsFermionOperator.rst#ffsim.SupportsFermionOperator) | `_fermion_operator_` | [ffsim.fermion_operator](../api/stubs/ffsim.fermion_operator.rst#ffsim.fermion_operator) | Convert to a [FermionOperator](../api/stubs/ffsim.FermionOperator.rst#ffsim.FermionOperator). |\n",
|
|
25
|
+
"| [SupportsTrace](../api/stubs/ffsim.SupportsTrace.rst#ffsim.SupportsTrace) | `_trace_` | [ffsim.trace](../api/stubs/ffsim.trace.rst#ffsim.trace) | Compute the trace of a linear operator. |\n",
|
|
26
|
+
"| [SupportsDiagonal](../api/stubs/ffsim.SupportsDiagonal.rst#ffsim.SupportsDiagonal) | `_diag_` | [ffsim.diag](../api/stubs/ffsim.diag.rst#ffsim.diag) | Return the diagonal entries of a linear operator.|\n",
|
|
27
|
+
"| [SupportsApproximateEquality](../api/stubs/ffsim.SupportsApproximateEquality.rst#ffsim.SupportsApproximateEquality) | `_approx_eq_` | [ffsim.approx_eq](../api/stubs/ffsim.approx_eq.rst#ffsim.approx_eq) | Compare objects with numerical tolerance. |"
|
|
28
28
|
]
|
|
29
29
|
},
|
|
30
30
|
{
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"\n",
|
|
64
64
|
"The function `ffsim.apply_unitary(vec, obj, norb, nelec, copy=True)` dispatches to this method.\n",
|
|
65
65
|
"\n",
|
|
66
|
-
"Classes that implement this protocol include the variational ansatz operators such as [UCJOpSpinBalanced](../api/ffsim.rst#ffsim.UCJOpSpinBalanced) and the UCCSD operator classes."
|
|
66
|
+
"Classes that implement this protocol include the variational ansatz operators such as [UCJOpSpinBalanced](../api/stubs/ffsim.UCJOpSpinBalanced.rst#ffsim.UCJOpSpinBalanced) and the UCCSD operator classes."
|
|
67
67
|
]
|
|
68
68
|
},
|
|
69
69
|
{
|
|
@@ -126,9 +126,9 @@
|
|
|
126
126
|
" ...\n",
|
|
127
127
|
"```\n",
|
|
128
128
|
"\n",
|
|
129
|
-
"The function `ffsim.linear_operator(obj, norb, nelec)` dispatches to this method. It also has special handling for [FermionOperator](../api/ffsim.rst#ffsim.FermionOperator) instances, which are converted to a `LinearOperator` directly.\n",
|
|
129
|
+
"The function `ffsim.linear_operator(obj, norb, nelec)` dispatches to this method. It also has special handling for [FermionOperator](../api/stubs/ffsim.FermionOperator.rst#ffsim.FermionOperator) instances, which are converted to a `LinearOperator` directly.\n",
|
|
130
130
|
"\n",
|
|
131
|
-
"The `LinearOperator` representation enables matrix-vector multiplication, eigenvalue computation, and time evolution. The Hamiltonian classes ([MolecularHamiltonian](../api/ffsim.rst#ffsim.MolecularHamiltonian), [DiagonalCoulombHamiltonian](../api/ffsim.rst#ffsim.DiagonalCoulombHamiltonian), [DoubleFactorizedHamiltonian](../api/ffsim.rst#ffsim.DoubleFactorizedHamiltonian), [SingleFactorizedHamiltonian](../api/ffsim.rst#ffsim.SingleFactorizedHamiltonian)) all implement this protocol."
|
|
131
|
+
"The `LinearOperator` representation enables matrix-vector multiplication, eigenvalue computation, and time evolution. The Hamiltonian classes ([MolecularHamiltonian](../api/stubs/ffsim.MolecularHamiltonian.rst#ffsim.MolecularHamiltonian), [DiagonalCoulombHamiltonian](../api/stubs/ffsim.DiagonalCoulombHamiltonian.rst#ffsim.DiagonalCoulombHamiltonian), [DoubleFactorizedHamiltonian](../api/stubs/ffsim.DoubleFactorizedHamiltonian.rst#ffsim.DoubleFactorizedHamiltonian), [SingleFactorizedHamiltonian](../api/stubs/ffsim.SingleFactorizedHamiltonian.rst#ffsim.SingleFactorizedHamiltonian)) all implement this protocol."
|
|
132
132
|
]
|
|
133
133
|
},
|
|
134
134
|
{
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
"source": [
|
|
168
168
|
"## SupportsFermionOperator\n",
|
|
169
169
|
"\n",
|
|
170
|
-
"The `SupportsFermionOperator` protocol is for objects that can be converted to a [FermionOperator](../api/ffsim.rst#ffsim.FermionOperator), which is ffsim's symbolic representation of a [fermionic operator](../explanations/fermion-operator.ipynb) as a linear combination of products of creation and annihilation operators. A class implements this protocol by defining the `_fermion_operator_` method, which has the signature\n",
|
|
170
|
+
"The `SupportsFermionOperator` protocol is for objects that can be converted to a [FermionOperator](../api/stubs/ffsim.FermionOperator.rst#ffsim.FermionOperator), which is ffsim's symbolic representation of a [fermionic operator](../explanations/fermion-operator.ipynb) as a linear combination of products of creation and annihilation operators. A class implements this protocol by defining the `_fermion_operator_` method, which has the signature\n",
|
|
171
171
|
"\n",
|
|
172
172
|
"```python\n",
|
|
173
173
|
"def _fermion_operator_(self) -> FermionOperator:\n",
|
|
@@ -217,7 +217,7 @@
|
|
|
217
217
|
"\n",
|
|
218
218
|
"The function `ffsim.diag(obj, norb, nelec)` dispatches to this method.\n",
|
|
219
219
|
"\n",
|
|
220
|
-
"The diagonal is useful for constructing preconditioners in iterative eigensolvers like Davidson's method. The Hamiltonian classes ([MolecularHamiltonian](../api/ffsim.rst#ffsim.MolecularHamiltonian), [DiagonalCoulombHamiltonian](../api/ffsim.rst#ffsim.DiagonalCoulombHamiltonian), [DoubleFactorizedHamiltonian](../api/ffsim.rst#ffsim.DoubleFactorizedHamiltonian)) implement this protocol."
|
|
220
|
+
"The diagonal is useful for constructing preconditioners in iterative eigensolvers like Davidson's method. The Hamiltonian classes ([MolecularHamiltonian](../api/stubs/ffsim.MolecularHamiltonian.rst#ffsim.MolecularHamiltonian), [DiagonalCoulombHamiltonian](../api/stubs/ffsim.DiagonalCoulombHamiltonian.rst#ffsim.DiagonalCoulombHamiltonian), [DoubleFactorizedHamiltonian](../api/stubs/ffsim.DoubleFactorizedHamiltonian.rst#ffsim.DoubleFactorizedHamiltonian)) implement this protocol."
|
|
221
221
|
]
|
|
222
222
|
},
|
|
223
223
|
{
|
|
@@ -263,7 +263,7 @@
|
|
|
263
263
|
" ...\n",
|
|
264
264
|
"```\n",
|
|
265
265
|
"\n",
|
|
266
|
-
"The function `ffsim.trace(obj, norb, nelec)` dispatches to this method. This function first checks for the `_trace_` method and uses that if it exists. If the `_trace_` method does not exist, it then checks for a `_diag_` method, since the trace can be computed by summing the diagonal. Thus, classes that implement the [SupportsDiagonal](../api/ffsim.rst#ffsim.SupportsDiagonal) protocol automatically implement [SupportsTrace](../api/ffsim.rst#ffsim.SupportsTrace) as well.\n",
|
|
266
|
+
"The function `ffsim.trace(obj, norb, nelec)` dispatches to this method. This function first checks for the `_trace_` method and uses that if it exists. If the `_trace_` method does not exist, it then checks for a `_diag_` method, since the trace can be computed by summing the diagonal. Thus, classes that implement the [SupportsDiagonal](../api/stubs/ffsim.SupportsDiagonal.rst#ffsim.SupportsDiagonal) protocol automatically implement [SupportsTrace](../api/stubs/ffsim.SupportsTrace.rst#ffsim.SupportsTrace) as well.\n",
|
|
267
267
|
"\n",
|
|
268
268
|
"One practical use of the trace is to pass it to `scipy.sparse.linalg.expm_multiply` for Hamiltonian time evolution, which uses the trace to improve its performance. Without it, SciPy issues a warning."
|
|
269
269
|
]
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
"\n",
|
|
346
346
|
"The function `ffsim.approx_eq(obj, other, rtol=1e-5, atol=1e-8)` dispatches to this method. It tries `obj._approx_eq_(other)` first, then `other._approx_eq_(obj)`, and falls back to `obj == other`. The tolerance parameters `rtol` and `atol` follow the same convention as `numpy.allclose`.\n",
|
|
347
347
|
"\n",
|
|
348
|
-
"This protocol is widely implemented across ffsim: Hamiltonians, ansatz operators, and [FermionOperator](../api/ffsim.rst#ffsim.FermionOperator) all support it."
|
|
348
|
+
"This protocol is widely implemented across ffsim: Hamiltonians, ansatz operators, and [FermionOperator](../api/stubs/ffsim.FermionOperator.rst#ffsim.FermionOperator) all support it."
|
|
349
349
|
]
|
|
350
350
|
},
|
|
351
351
|
{
|