Computing <S^2> for wavefunction containers#457
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for computing the expectation value ⟨S²⟩ on wavefunction containers using spin-dependent 1- and 2-RDMs (chemist/QDK Γ(p,q,r,s)=⟨a†ₚ a†ᵣ aₛ a_q⟩ convention), along with a comprehensive new C++ test suite validating the observable across hand-constructed RDMs and SCF→(CAS/SCI) workflows.
Changes:
- Implemented
WavefunctionContainer::compute_s_squared()and exposed it viaWavefunction::compute_s_squared(). - Documented the new API in
wavefunction.hpp. - Added
test_s_squared.cppwith analytical-state tests and end-to-end SCF+MACIS CAS/SCI tests.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
cpp/src/qdk/chemistry/data/wavefunction.cpp |
Implements ⟨S²⟩ evaluation from spin-dependent RDM blocks. |
cpp/include/qdk/chemistry/data/wavefunction.hpp |
Declares the new API and adds Doxygen documentation. |
cpp/tests/test_s_squared.cpp |
Adds analytical and integration tests to validate ⟨S²⟩ correctness. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
📊 Coverage Summary
Detailed Coverage ReportsC++ Coverage DetailsPython Coverage DetailsPybind11 Coverage Details |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| int norbs = static_cast<int>(one_rdm_aa.rows()); | ||
| double one_rdm_trace = one_rdm_aa.trace() + one_rdm_bb.trace(); | ||
|
|
| if (!has_one_rdm_spin_dependent() || !has_two_rdm_spin_dependent()) { | ||
| throw std::runtime_error( | ||
| "Spin-dependent one- and two-body RDMs must be set to compute <S^2>"); | ||
| } |
| int norbs = static_cast<int>(one_rdm_aa.rows()); | ||
| double one_rdm_trace = one_rdm_aa.trace() + one_rdm_bb.trace(); | ||
|
|
||
| // sum_{ij} Gamma(i,j,j,i): O(n^2) | ||
| auto sum_ijji = [norbs](const Eigen::VectorXd& vec) -> double { | ||
| double sum = 0.0; | ||
| for (int i = 0; i < norbs; ++i) { | ||
| for (int j = 0; j < norbs; ++j) { | ||
| int idx = i * norbs * norbs * norbs + j * norbs * norbs + j * norbs + i; | ||
| sum += vec[idx]; | ||
| } | ||
| } | ||
| return sum; | ||
| }; | ||
|
|
||
| // sum_{ij} Gamma(i,i,j,j): O(n^2) | ||
| auto sum_iijj = [norbs](const Eigen::VectorXd& vec) -> double { | ||
| double sum = 0.0; | ||
| for (int i = 0; i < norbs; ++i) { | ||
| for (int j = 0; j < norbs; ++j) { | ||
| int idx = i * norbs * norbs * norbs + i * norbs * norbs + j * norbs + j; | ||
| sum += vec[idx]; | ||
| } | ||
| } | ||
| return sum; |
| /** | ||
| * @brief Compute the expectation value of the total spin-squared operator | ||
| * from the RDMs. | ||
| * | ||
| * @return The expectation value \f$\langle S^2 \rangle\f$ | ||
| * @throws std::runtime_error if the orbital basis declares no spin (S_z) axis | ||
| * (spin-blocked active-space RDMs cannot be generated) | ||
| */ |
| /** | ||
| * @brief Compute the expectation value of the total spin-squared operator | ||
| * from the RDMs. | ||
| * | ||
| * @return The expectation value \f$\langle S^2 \rangle\f$ | ||
| * @throws std::runtime_error if the orbital basis declares no spin (S_z) axis | ||
| * (spin-blocked active-space RDMs cannot be generated) | ||
| */ |
Added a function to compute <S^2> for arbitrary wavefunction containers using 1- and 2-RDMs consistent with the chemist's convention: Gamma(p,q,r,s) = <p^\dagger r^\dagger s q>.
Added some CASCI and SCI tests to verify correctness.