34#include "ONVBasis/SpinResolvedONV.hpp"
35#include "ONVBasis/SpinResolvedONVBasis.hpp"
36#include "ONVBasis/SpinResolvedSelectedONVBasis.hpp"
37#include "ONVBasis/SpinUnresolvedSelectedONVBasis.hpp"
38#include "Partition/DiscreteDomainPartition.hpp"
39#include "Partition/ONVPartition.hpp"
40#include "Partition/SpinResolvedElectronPartition.hpp"
41#include "Partition/SpinUnresolvedElectronPartition.hpp"
45#include <boost/algorithm/string.hpp>
46#include <boost/dynamic_bitset.hpp>
58template <
typename _Scalar,
typename _ONVBasis>
88 onv_basis {onv_basis},
172 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
176 std::ifstream input_file_stream {GAMESSUS_filename};
177 if (!input_file_stream.good()) {
178 throw std::runtime_error(
"LinearExpansionReader(std::string): The provided GAMESS file is illegible. Maybe you specified a wrong path?");
181 std::ifstream input_file_stream_count {GAMESSUS_filename};
189 while (std::getline(input_file_stream, line)) {
190 std::getline(input_file_stream_count, buffer);
193 if (line.find(
"ALPHA") != std::string::npos && line.find(
"BETA") != std::string::npos && line.find(
"COEFFICIENT") != std::string::npos) {
196 std::getline(input_file_stream, line);
197 std::getline(input_file_stream_count, buffer);
202 size_t space_size = 0;
204 while (std::getline(input_file_stream_count, buffer)) {
205 if (buffer.length() != 0 | buffer[0] !=
'\n') {
213 std::getline(input_file_stream, line);
216 std::vector<std::string> splitted_line;
217 boost::split(splitted_line, line, boost::is_any_of(
"|"));
221 std::string trimmed_alpha = boost::algorithm::trim_copy(splitted_line[0]);
224 std::string trimmed_beta = boost::algorithm::trim_copy(splitted_line[1]);
227 size_t index_count = 0;
228 coefficients(index_count) = std::stod(splitted_line[2]);
232 std::string reversed_alpha {trimmed_alpha.rbegin(), trimmed_alpha.rend()};
233 std::string reversed_beta {trimmed_beta.rbegin(), trimmed_beta.rend()};
235 boost::dynamic_bitset<> alpha_transfer {reversed_alpha};
236 boost::dynamic_bitset<> beta_transfer {reversed_beta};
238 size_t K = alpha_transfer.size();
239 size_t N_alpha = alpha_transfer.count();
240 size_t N_beta = beta_transfer.count();
242 SpinResolvedSelectedONVBasis onv_basis {K, N_alpha, N_beta};
243 onv_basis.expandWith(SpinResolvedONV::FromString(reversed_alpha, reversed_beta));
248 while (std::getline(input_file_stream, line)) {
251 boost::split(splitted_line, line, boost::is_any_of(
"|"));
255 trimmed_alpha = boost::algorithm::trim_copy(splitted_line[0]);
256 if (trimmed_alpha.length() != K) {
257 throw std::invalid_argument(
"LinearExpansionReader(std::string): One of the provided alpha ONVs does not have the correct number of orbitals.");
259 reversed_alpha = std::string(trimmed_alpha.rbegin(), trimmed_alpha.rend());
262 trimmed_beta = boost::algorithm::trim_copy(splitted_line[1]);
263 if (trimmed_beta.length() != K) {
264 throw std::invalid_argument(
"LinearExpansionReader(std::string): One of the provided beta ONVs does not have the correct number of orbitals.");
266 reversed_beta = std::string(trimmed_beta.rbegin(), trimmed_beta.rend());
270 coefficients(index_count) = std::stod(splitted_line[2]);
271 onv_basis.expandWith(SpinResolvedONV::FromString(reversed_alpha, reversed_beta));
288 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
292 auto S_r = r_spinor_basis.
overlap();
293 S_r.transform(r_spinor_basis.
expansion().inverse());
295 auto S_u = u_spinor_basis.
overlap();
296 S_u.transform(u_spinor_basis.
expansion().inverse());
298 if (!(S_r.parameters().isApprox(S_u.alpha().parameters(), 1.0e-08)) || !(S_r.parameters().isApprox(S_u.beta().parameters(), 1.0e-08))) {
299 throw std::invalid_argument(
"LinearExpansion::FromONVProjection(const SpinResolvedONV&, const RSpinOrbitalBasis<double, GTOShell>&, const USpinOrbitalBasis<double, GTOShell>&): The given spinor bases are not expressed using the same scalar orbital basis.");
304 const auto& C_restricted = r_spinor_basis.
expansion();
306 const auto C_unrestricted = u_spinor_basis.
expansion();
310 const auto K = onv.numberOfSpatialOrbitals(
Spin::alpha);
311 const auto N_alpha = onv.numberOfElectrons(
Spin::alpha);
312 const auto N_beta = onv.numberOfElectrons(
Spin::beta);
313 const SpinResolvedONVBasis onv_basis {K, N_alpha, N_beta};
319 onv_basis.forEach([&onv, &C_unrestricted, &C_restricted, &S_r, &
coefficients, &onv_basis](
const SpinUnresolvedONV& alpha_onv,
const size_t I_alpha,
const SpinUnresolvedONV& beta_onv,
const size_t I_beta) {
320 const SpinResolvedONV onv_on {alpha_onv, beta_onv};
322 const auto coefficient = onv.calculateProjection(onv_on, C_unrestricted, C_restricted, S_r.parameters());
323 const auto address = onv_basis.compoundAddress(I_alpha, I_beta);
341 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
345 auto S_on = spinor_basis_on.
overlap();
346 S_on.transform(spinor_basis_on.
expansion().inverse());
348 auto S_of = spinor_basis_of.
overlap();
349 S_of.transform(spinor_basis_of.
expansion().inverse());
351 if (!(S_on.parameters().isApprox(S_of.parameters(), 1.0e-08))) {
352 throw std::invalid_argument(
"LinearExpansion::FromONVProjection(const SpinUnresolvedONV&, const RSpinOrbitalBasis<double, GTOShell>&, const GSpinorBasis<double, GTOShell>&): The given spinor bases are not expressed using the same scalar orbital basis.");
357 const auto& C_on = spinor_basis_on.
expansion();
358 const auto& C_of = spinor_basis_of.
expansion();
362 const auto M = onv_of.numberOfSpinors();
363 const auto N = onv_of.numberOfElectrons();
364 const SpinUnresolvedONVBasis onv_basis {M, N};
369 onv_basis.forEach([&onv_of, &C_on, &C_of, &S_on, &
coefficients](
const SpinUnresolvedONV& onv_on,
const size_t I) {
370 coefficients(I) = onv_of.calculateProjection(onv_on, C_of, C_on, S_on.parameters());
413 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
416 const auto K = onv_basis.numberOfOrbitals();
418 throw std::invalid_argument(
"LinearExpansion::basisTransform(const RTransformation<double>&): The number of spatial orbitals does not match the dimension of the transformation matrix.");
426 L.triangularView<Eigen::StrictlyLower>() = lu_decomposition[0];
437 const SpinUnresolvedONVBasis& alpha_onv_basis = onv_basis.alpha();
438 const SpinUnresolvedONVBasis& beta_onv_basis = onv_basis.beta();
440 auto dim_alpha = alpha_onv_basis.
dimension();
441 auto dim_beta = beta_onv_basis.dimension();
442 auto N_alpha = alpha_onv_basis.numberOfElectrons();
443 auto N_beta = beta_onv_basis.numberOfElectrons();
455 for (
size_t m = 0; m < K; m++) {
460 SpinUnresolvedONV
alpha = alpha_onv_basis.constructONVFromAddress(0);
461 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
462 if (!
alpha.isOccupied(m)) {
463 for (
size_t e1 = 0; e1 < N_alpha; e1++) {
464 size_t p =
alpha.occupationIndexOf(e1);
467 size_t address = I_alpha - alpha_onv_basis.vertexWeight(p, e1 + 1);
472 alpha_onv_basis.shiftUntilNextUnoccupiedOrbital<1>(
alpha, address, q, e2, sign);
475 alpha_onv_basis.shiftUntilNextUnoccupiedOrbital<1>(
alpha, address, q, e2, sign);
478 address += alpha_onv_basis.vertexWeight(q, e2);
480 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
481 correction_coefficients(I_alpha * dim_beta + I_beta) += sign * t(p, m) * current_coefficients(address * dim_beta + I_beta);
486 size_t address = I_alpha - alpha_onv_basis.vertexWeight(p, e1 + 1);
491 alpha_onv_basis.shiftUntilPreviousUnoccupiedOrbital<1>(
alpha, address, q, e2, sign);
494 alpha_onv_basis.shiftUntilPreviousUnoccupiedOrbital<1>(
alpha, address, q, e2, sign);
497 address += alpha_onv_basis.vertexWeight(q, e2 + 2);
498 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
499 correction_coefficients(I_alpha * dim_beta + I_beta) += sign * t(p, m) * current_coefficients(address * dim_beta + I_beta);
505 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
506 correction_coefficients(I_alpha * dim_beta + I_beta) += (t(m, m) - 1) * current_coefficients(I_alpha * dim_beta + I_beta);
511 if (I_alpha < dim_alpha - 1) {
512 alpha_onv_basis.transformONVToNextPermutation(
alpha);
516 current_coefficients += correction_coefficients;
517 correction_coefficients.setZero();
520 SpinUnresolvedONV
beta = beta_onv_basis.constructONVFromAddress(0);
522 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
523 if (!
beta.isOccupied(m)) {
524 for (
size_t e1 = 0; e1 < N_beta; e1++) {
525 size_t p =
beta.occupationIndexOf(e1);
528 size_t address = I_beta - beta_onv_basis.vertexWeight(p, e1 + 1);
533 beta_onv_basis.shiftUntilNextUnoccupiedOrbital<1>(
beta, address, q, e2, sign);
536 beta_onv_basis.shiftUntilNextUnoccupiedOrbital<1>(
beta, address, q, e2, sign);
539 address += beta_onv_basis.vertexWeight(q, e2);
541 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
542 correction_coefficients(I_alpha * dim_beta + I_beta) += sign * t(p, m) * current_coefficients(I_alpha * dim_beta + address);
547 size_t address = I_beta - beta_onv_basis.vertexWeight(p, e1 + 1);
553 beta_onv_basis.shiftUntilPreviousUnoccupiedOrbital<1>(
beta, address, q, e2, sign);
556 beta_onv_basis.shiftUntilPreviousUnoccupiedOrbital<1>(
beta, address, q, e2, sign);
559 address += beta_onv_basis.vertexWeight(q, e2 + 2);
561 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
562 correction_coefficients(I_alpha * dim_beta + I_beta) += sign * t(p, m) * current_coefficients(I_alpha * dim_beta + address);
568 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
569 correction_coefficients(I_alpha * dim_beta + I_beta) += (t(m, m) - 1) * current_coefficients(I_alpha * dim_beta + I_beta);
573 if (I_beta < dim_beta - 1) {
574 beta_onv_basis.transformONVToNextPermutation(
beta);
578 current_coefficients += correction_coefficients;
579 correction_coefficients.setZero();
581 this->m_coefficients = current_coefficients;
594 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
598 const auto M = this->onv_basis.numberOfOrbitals();
599 const auto N = this->onv_basis.numberOfElectrons();
600 const auto dim = onv_basis.dimension();
604 SpinUnresolvedONV onv = onv_basis.constructONVFromAddress(0);
605 for (
size_t J = 0; J < dim; J++) {
608 for (
size_t e1 = 0; e1 < N; e1++) {
611 ONVPath<SpinUnresolvedONVBasis> onv_path {onv_basis, onv};
615 const auto q = onv.occupationIndexOf(e1);
619 D(q, q) += c_J * c_J;
622 onv_path.annihilate(q, e1);
625 while (!onv_path.isFinished() && onv_path.isOrbitalIndexValid()) {
628 onv_path.leftTranslateDiagonalArcUntilVerticalArc();
631 const auto I = onv_path.addressAfterCreation();
636 const auto p = onv_path.orbitalIndex();
638 const double value = c_I * c_J;
640 D(p, q) += onv_path.sign() * value;
641 D(q, p) += onv_path.sign() * value;
644 onv_path.leftTranslateVerticalArc();
650 onv_basis.transformONVToNextPermutation(onv);
668 template <
typename Z = ONVBasis>
672 std::vector<size_t> ket_indices_reversed = ket_indices;
673 std::reverse(ket_indices_reversed.begin(), ket_indices_reversed.end());
679 const auto dim = this->onv_basis.dimension();
682 auto bra = this->onv_basis.constructONVFromAddress(0);
687 if (!bra.annihilateAll(bra_indices, sign_bra)) {
691 this->onv_basis.transformONVToNextPermutation(bra);
701 auto ket = this->onv_basis.constructONVFromAddress(0);
706 if (!ket.annihilateAll(ket_indices_reversed, sign_ket)) {
709 this->onv_basis.transformONVToNextPermutation(ket);
726 ket.createAll(ket_indices_reversed);
727 this->onv_basis.transformONVToNextPermutation(ket);
736 bra.createAll(bra_indices);
737 this->onv_basis.transformONVToNextPermutation(bra);
756 template <
typename Z = ONVBasis>
760 std::vector<size_t> ket_indices_reversed = ket_indices;
761 std::reverse(ket_indices_reversed.begin(), ket_indices_reversed.end());
767 const auto dim = this->onv_basis.dimension();
771 auto bra = this->onv_basis.onvWithIndex(I);
775 if (!bra.annihilateAll(bra_indices, sign_bra)) {
780 bra = this->onv_basis.onvWithIndex(I);
790 auto ket = this->onv_basis.onvWithIndex(J);
794 if (!ket.annihilateAll(ket_indices_reversed, sign_ket)) {
798 ket = this->onv_basis.onvWithIndex(J);
814 ket.createAll(ket_indices_reversed);
816 ket = this->onv_basis.onvWithIndex(J);
825 bra = this->onv_basis.onvWithIndex(I);
842 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
846 size_t K = this->onv_basis.alpha().numberOfOrbitals();
851 SpinUnresolvedONVBasis onv_basis_alpha = onv_basis.alpha();
852 SpinUnresolvedONVBasis onv_basis_beta = onv_basis.beta();
854 auto dim_alpha = onv_basis_alpha.dimension();
855 auto dim_beta = onv_basis_beta.dimension();
858 SpinUnresolvedONV spin_string_alpha = onv_basis_alpha.constructONVFromAddress(0);
859 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
860 for (
size_t p = 0; p < K; p++) {
862 if (spin_string_alpha.annihilate(p, sign_p)) {
863 double diagonal_contribution = 0;
867 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
868 double c_I_alpha_I_beta = this->
coefficient(I_alpha * dim_beta + I_beta);
869 diagonal_contribution += std::pow(c_I_alpha_I_beta, 2);
871 D_aa(p, p) += diagonal_contribution;
874 for (
size_t q = 0; q < p; q++) {
875 int sign_pq = sign_p;
876 if (spin_string_alpha.create(q, sign_pq)) {
877 size_t J_alpha = onv_basis_alpha.addressOf(spin_string_alpha);
879 double off_diagonal_contribution = 0;
880 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
881 double c_I_alpha_I_beta = this->
coefficient(I_alpha * dim_beta + I_beta);
882 double c_J_alpha_I_beta = this->
coefficient(J_alpha * dim_beta + I_beta);
883 off_diagonal_contribution += c_I_alpha_I_beta * c_J_alpha_I_beta;
886 D_aa(p, q) += sign_pq * off_diagonal_contribution;
887 D_aa(q, p) += sign_pq * off_diagonal_contribution;
889 spin_string_alpha.annihilate(q);
894 spin_string_alpha.create(p);
899 if (I_alpha < dim_alpha - 1) {
900 onv_basis_alpha.transformONVToNextPermutation(spin_string_alpha);
907 SpinUnresolvedONV spin_string_beta = onv_basis_beta.constructONVFromAddress(0);
908 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
909 for (
size_t p = 0; p < K; p++) {
911 if (spin_string_beta.annihilate(p, sign_p)) {
912 double diagonal_contribution = 0;
916 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
917 double c_I_alpha_I_beta = this->
coefficient(I_alpha * dim_beta + I_beta);
918 diagonal_contribution += std::pow(c_I_alpha_I_beta, 2);
921 D_bb(p, p) += diagonal_contribution;
924 for (
size_t q = 0; q < p; q++) {
925 int sign_pq = sign_p;
926 if (spin_string_beta.create(q, sign_pq)) {
927 size_t J_beta = onv_basis_beta.addressOf(spin_string_beta);
929 double off_diagonal_contribution = 0;
930 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
931 double c_I_alpha_I_beta = this->
coefficient(I_alpha * dim_beta + I_beta);
932 double c_I_alpha_J_beta = this->
coefficient(I_alpha * dim_beta + J_beta);
933 off_diagonal_contribution += c_I_alpha_I_beta * c_I_alpha_J_beta;
935 D_bb(p, q) += sign_pq * off_diagonal_contribution;
936 D_bb(q, p) += sign_pq * off_diagonal_contribution;
938 spin_string_beta.annihilate(q);
943 spin_string_beta.create(p);
948 if (I_beta < dim_beta - 1) {
949 onv_basis_beta.transformONVToNextPermutation(spin_string_beta);
962 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
967 SpinUnresolvedONVBasis onv_basis_alpha = onv_basis.alpha();
968 SpinUnresolvedONVBasis onv_basis_beta = onv_basis.beta();
970 auto dim_alpha = onv_basis_alpha.dimension();
971 auto dim_beta = onv_basis_beta.dimension();
974 size_t K = this->onv_basis.alpha().numberOfOrbitals();
981 SpinUnresolvedONV spin_string_alpha_aaaa = onv_basis_alpha.constructONVFromAddress(0);
982 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
984 for (
size_t p = 0; p < K; p++) {
987 if (spin_string_alpha_aaaa.annihilate(p, sign_p)) {
989 for (
size_t r = 0; r < K; r++) {
990 int sign_pr = sign_p;
992 if (spin_string_alpha_aaaa.annihilate(r, sign_pr)) {
994 for (
size_t s = 0; s < K; s++) {
995 int sign_prs = sign_pr;
997 if (spin_string_alpha_aaaa.create(s, sign_prs)) {
999 for (
size_t q = 0; q < K; q++) {
1000 int sign_prsq = sign_prs;
1002 if (spin_string_alpha_aaaa.create(q, sign_prsq)) {
1003 size_t J_alpha = onv_basis_alpha.addressOf(spin_string_alpha_aaaa);
1005 double contribution = 0.0;
1006 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
1007 double c_I_alpha_I_beta = this->
coefficient(I_alpha * dim_beta + I_beta);
1008 double c_J_alpha_I_beta = this->
coefficient(J_alpha * dim_beta + I_beta);
1009 contribution += c_I_alpha_I_beta * c_J_alpha_I_beta;
1013 d_aaaa(p, q, r, s) += sign_prsq * contribution;
1015 spin_string_alpha_aaaa.annihilate(q);
1019 spin_string_alpha_aaaa.annihilate(s);
1023 spin_string_alpha_aaaa.create(r);
1027 spin_string_alpha_aaaa.create(p);
1031 if (I_alpha < dim_alpha - 1) {
1032 onv_basis_alpha.transformONVToNextPermutation(spin_string_alpha_aaaa);
1039 SpinUnresolvedONV spin_string_alpha_aabb = onv_basis_alpha.constructONVFromAddress(0);
1040 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
1042 for (
size_t p = 0; p < K; p++) {
1045 if (spin_string_alpha_aabb.annihilate(p, sign_p)) {
1047 for (
size_t q = 0; q < K; q++) {
1048 int sign_pq = sign_p;
1050 if (spin_string_alpha_aabb.create(q, sign_pq)) {
1051 size_t J_alpha = onv_basis_alpha.addressOf(spin_string_alpha_aabb);
1054 SpinUnresolvedONV spin_string_beta_aabb = onv_basis_beta.constructONVFromAddress(0);
1055 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
1057 for (
size_t r = 0; r < K; r++) {
1060 if (spin_string_beta_aabb.annihilate(r, sign_r)) {
1062 for (
size_t s = 0; s < K; s++) {
1063 int sign_rs = sign_r;
1065 if (spin_string_beta_aabb.create(s, sign_rs)) {
1066 size_t J_beta = onv_basis_beta.addressOf(spin_string_beta_aabb);
1068 double c_I_alpha_I_beta = this->
coefficient(I_alpha * dim_beta + I_beta);
1069 double c_J_alpha_J_beta = this->
coefficient(J_alpha * dim_beta + J_beta);
1070 d_aabb(p, q, r, s) += sign_pq * sign_rs * c_I_alpha_I_beta * c_J_alpha_J_beta;
1072 spin_string_beta_aabb.annihilate(s);
1077 spin_string_beta_aabb.create(r);
1082 if (I_beta < dim_beta - 1) {
1083 onv_basis_beta.transformONVToNextPermutation(spin_string_beta_aabb);
1088 spin_string_alpha_aabb.annihilate(q);
1092 spin_string_alpha_aabb.create(p);
1096 if (I_alpha < dim_alpha - 1) {
1097 onv_basis_alpha.transformONVToNextPermutation(spin_string_alpha_aabb);
1105 Eigen::array<int, 4> axes {2, 3, 0, 1};
1110 SpinUnresolvedONV spin_string_beta_bbbb = onv_basis_beta.constructONVFromAddress(0);
1111 for (
size_t I_beta = 0; I_beta < dim_beta; I_beta++) {
1113 for (
size_t p = 0; p < K; p++) {
1116 if (spin_string_beta_bbbb.annihilate(p, sign_p)) {
1118 for (
size_t r = 0; r < K; r++) {
1119 int sign_pr = sign_p;
1121 if (spin_string_beta_bbbb.annihilate(r, sign_pr)) {
1123 for (
size_t s = 0; s < K; s++) {
1124 int sign_prs = sign_pr;
1126 if (spin_string_beta_bbbb.create(s, sign_prs)) {
1128 for (
size_t q = 0; q < K; q++) {
1129 int sign_prsq = sign_prs;
1131 if (spin_string_beta_bbbb.create(q, sign_prsq)) {
1132 size_t J_beta = onv_basis_beta.addressOf(spin_string_beta_bbbb);
1134 double contribution = 0.0;
1135 for (
size_t I_alpha = 0; I_alpha < dim_alpha; I_alpha++) {
1136 double c_I_alpha_I_beta = this->
coefficient(I_alpha * dim_beta + I_beta);
1137 double c_I_alpha_J_beta = this->
coefficient(I_alpha * dim_beta + J_beta);
1138 contribution += c_I_alpha_I_beta * c_I_alpha_J_beta;
1142 d_bbbb(p, q, r, s) += sign_prsq * contribution;
1144 spin_string_beta_bbbb.annihilate(q);
1148 spin_string_beta_bbbb.annihilate(s);
1152 spin_string_beta_bbbb.create(r);
1156 spin_string_beta_bbbb.create(p);
1160 if (I_beta < dim_beta - 1) {
1161 onv_basis_beta.transformONVToNextPermutation(spin_string_beta_bbbb);
1175 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1184 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1197 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1201 const auto K = this->onv_basis.numberOfSpatialOrbitals();
1202 const auto dimension = this->onv_basis.dimension();
1206 const auto onv_basis_proxy = this->onv_basis.proxy();
1207 SpinUnresolvedONV onv = onv_basis_proxy.constructONVFromAddress(0);
1208 for (
size_t I = 0; I < dimension; I++) {
1210 for (
size_t e1 = 0; e1 < onv_basis_proxy.numberOfElectrons(); e1++) {
1211 const size_t p = onv.occupationIndexOf(e1);
1214 D(p, p) += 2 * std::pow(c_I, 2);
1217 if (I < dimension - 1) {
1218 onv_basis_proxy.transformONVToNextPermutation(onv);
1231 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1239 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1248 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1252 const auto K = this->onv_basis.numberOfSpatialOrbitals();
1253 const auto dimension = this->onv_basis.dimension();
1262 const auto onv_basis_proxy = this->onv_basis.proxy();
1263 SpinUnresolvedONV onv = onv_basis_proxy.constructONVFromAddress(0);
1264 for (
size_t I = 0; I < dimension; I++) {
1265 for (
size_t p = 0; p < K; p++) {
1266 if (onv.annihilate(p)) {
1269 const double c_I_2 = std::pow(c_I, 2);
1271 d_aabb(p, p, p, p) += c_I_2;
1273 for (
size_t q = 0; q < p; q++) {
1274 if (onv.create(q)) {
1275 const size_t J = onv_basis_proxy.addressOf(onv);
1278 d_aabb(p, q, p, q) += c_I * c_J;
1279 d_aabb(q, p, q, p) += c_I * c_J;
1285 d_aaaa(p, p, q, q) += c_I_2;
1286 d_aaaa(q, q, p, p) += c_I_2;
1288 d_aaaa(p, q, q, p) -= c_I_2;
1289 d_aaaa(q, p, p, q) -= c_I_2;
1291 d_aabb(p, p, q, q) += c_I_2;
1292 d_aabb(q, q, p, p) += c_I_2;
1299 if (I < dimension - 1) {
1300 onv_basis_proxy.transformONVToNextPermutation(onv);
1318 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1321 size_t K = this->onv_basis.numberOfOrbitals();
1322 size_t dim = onv_basis.dimension();
1328 for (
size_t I = 0; I < dim; I++) {
1329 SpinResolvedONV configuration_I = this->onv_basis.onvWithIndex(I);
1330 SpinUnresolvedONV alpha_I = configuration_I.onv(
Spin::alpha);
1331 SpinUnresolvedONV beta_I = configuration_I.onv(
Spin::beta);
1337 for (
size_t p = 0; p < K; p++) {
1339 if (alpha_I.isOccupied(p)) {
1340 D_aa(p, p) += std::pow(c_I, 2);
1343 if (beta_I.isOccupied(p)) {
1344 D_bb(p, p) += std::pow(c_I, 2);
1350 for (
size_t J = I + 1; J < dim; J++) {
1352 SpinResolvedONV configuration_J = this->onv_basis.onvWithIndex(J);
1353 SpinUnresolvedONV alpha_J = configuration_J.onv(
Spin::alpha);
1354 SpinUnresolvedONV beta_J = configuration_J.onv(
Spin::beta);
1360 if ((alpha_I.countNumberOfExcitations(alpha_J) == 1) && (beta_I.countNumberOfExcitations(beta_J) == 0)) {
1363 size_t p = alpha_I.findDifferentOccupations(alpha_J)[0];
1364 size_t q = alpha_J.findDifferentOccupations(alpha_I)[0];
1367 int sign = alpha_I.operatorPhaseFactor(p) * alpha_J.operatorPhaseFactor(q);
1368 D_aa(p, q) += sign * c_I * c_J;
1369 D_aa(q, p) += sign * c_I * c_J;
1374 if ((alpha_I.countNumberOfExcitations(alpha_J) == 0) && (beta_I.countNumberOfExcitations(beta_J) == 1)) {
1377 size_t p = beta_I.findDifferentOccupations(beta_J)[0];
1378 size_t q = beta_J.findDifferentOccupations(beta_I)[0];
1381 int sign = beta_I.operatorPhaseFactor(p) * beta_J.operatorPhaseFactor(q);
1382 D_bb(p, q) += sign * c_I * c_J;
1383 D_bb(q, p) += sign * c_I * c_J;
1398 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1401 size_t K = this->onv_basis.numberOfOrbitals();
1402 size_t dim = onv_basis.dimension();
1409 for (
size_t I = 0; I < dim; I++) {
1411 SpinResolvedONV configuration_I = this->onv_basis.onvWithIndex(I);
1412 SpinUnresolvedONV alpha_I = configuration_I.onv(
Spin::alpha);
1413 SpinUnresolvedONV beta_I = configuration_I.onv(
Spin::beta);
1417 for (
size_t p = 0; p < K; p++) {
1420 if (alpha_I.isOccupied(p)) {
1421 for (
size_t q = 0; q < K; q++) {
1422 if (beta_I.isOccupied(q)) {
1423 d_aabb(p, p, q, q) += std::pow(c_I, 2);
1427 if (alpha_I.isOccupied(q)) {
1428 d_aaaa(p, p, q, q) += std::pow(c_I, 2);
1429 d_aaaa(p, q, q, p) -= std::pow(c_I, 2);
1437 if (beta_I.isOccupied(p)) {
1438 for (
size_t q = 0; q < K; q++) {
1439 if (alpha_I.isOccupied(q)) {
1440 d_bbaa(p, p, q, q) += std::pow(c_I, 2);
1444 if (beta_I.isOccupied(q)) {
1445 d_bbbb(p, p, q, q) += std::pow(c_I, 2);
1446 d_bbbb(p, q, q, p) -= std::pow(c_I, 2);
1454 for (
size_t J = I + 1; J < dim; J++) {
1456 SpinResolvedONV configuration_J = this->onv_basis.onvWithIndex(J);
1457 SpinUnresolvedONV alpha_J = configuration_J.onv(
Spin::alpha);
1458 SpinUnresolvedONV beta_J = configuration_J.onv(
Spin::beta);
1463 if ((alpha_I.countNumberOfExcitations(alpha_J) == 1) && (beta_I.countNumberOfExcitations(beta_J) == 0)) {
1466 size_t p = alpha_I.findDifferentOccupations(alpha_J)[0];
1467 size_t q = alpha_J.findDifferentOccupations(alpha_I)[0];
1470 int sign = alpha_I.operatorPhaseFactor(p) * alpha_J.operatorPhaseFactor(q);
1473 for (
size_t r = 0; r < K; r++) {
1475 if (alpha_I.isOccupied(r) && alpha_J.isOccupied(r)) {
1476 if ((p != r) && (q != r)) {
1478 d_aaaa(p, q, r, r) += sign * c_I * c_J;
1479 d_aaaa(r, q, p, r) -= sign * c_I * c_J;
1480 d_aaaa(p, r, r, q) -= sign * c_I * c_J;
1481 d_aaaa(r, r, p, q) += sign * c_I * c_J;
1483 d_aaaa(q, p, r, r) += sign * c_I * c_J;
1484 d_aaaa(q, r, r, p) -= sign * c_I * c_J;
1485 d_aaaa(r, p, q, r) -= sign * c_I * c_J;
1486 d_aaaa(r, r, q, p) += sign * c_I * c_J;
1490 if (beta_I.isOccupied(r)) {
1493 d_aabb(p, q, r, r) += sign * c_I * c_J;
1494 d_aabb(q, p, r, r) += sign * c_I * c_J;
1496 d_bbaa(r, r, p, q) += sign * c_I * c_J;
1497 d_bbaa(r, r, q, p) += sign * c_I * c_J;
1504 if ((alpha_I.countNumberOfExcitations(alpha_J) == 0) && (beta_I.countNumberOfExcitations(beta_J) == 1)) {
1507 size_t p = beta_I.findDifferentOccupations(beta_J)[0];
1508 size_t q = beta_J.findDifferentOccupations(beta_I)[0];
1511 int sign = beta_I.operatorPhaseFactor(p) * beta_J.operatorPhaseFactor(q);
1514 for (
size_t r = 0; r < K; r++) {
1516 if (beta_I.isOccupied(r) && beta_J.isOccupied(r)) {
1517 if ((p != r) && (q != r)) {
1519 d_bbbb(p, q, r, r) += sign * c_I * c_J;
1520 d_bbbb(r, q, p, r) -= sign * c_I * c_J;
1521 d_bbbb(p, r, r, q) -= sign * c_I * c_J;
1522 d_bbbb(r, r, p, q) += sign * c_I * c_J;
1524 d_bbbb(q, p, r, r) += sign * c_I * c_J;
1525 d_bbbb(q, r, r, p) -= sign * c_I * c_J;
1526 d_bbbb(r, p, q, r) -= sign * c_I * c_J;
1527 d_bbbb(r, r, q, p) += sign * c_I * c_J;
1531 if (alpha_I.isOccupied(r)) {
1534 d_bbaa(p, q, r, r) += sign * c_I * c_J;
1535 d_bbaa(q, p, r, r) += sign * c_I * c_J;
1537 d_aabb(r, r, p, q) += sign * c_I * c_J;
1538 d_aabb(r, r, q, p) += sign * c_I * c_J;
1545 if ((alpha_I.countNumberOfExcitations(alpha_J) == 1) && (beta_I.countNumberOfExcitations(beta_J) == 1)) {
1548 size_t p = alpha_I.findDifferentOccupations(alpha_J)[0];
1549 size_t q = alpha_J.findDifferentOccupations(alpha_I)[0];
1551 size_t r = beta_I.findDifferentOccupations(beta_J)[0];
1552 size_t s = beta_J.findDifferentOccupations(beta_I)[0];
1555 int sign = alpha_I.operatorPhaseFactor(p) * alpha_J.operatorPhaseFactor(q) * beta_I.operatorPhaseFactor(r) * beta_J.operatorPhaseFactor(s);
1556 d_aabb(p, q, r, s) += sign * c_I * c_J;
1557 d_aabb(q, p, s, r) += sign * c_I * c_J;
1559 d_bbaa(r, s, p, q) += sign * c_I * c_J;
1560 d_bbaa(s, r, q, p) += sign * c_I * c_J;
1565 if ((alpha_I.countNumberOfExcitations(alpha_J) == 2) && (beta_I.countNumberOfExcitations(beta_J) == 0)) {
1568 std::vector<size_t> occupied_indices_I = alpha_I.findDifferentOccupations(alpha_J);
1569 size_t p = occupied_indices_I[0];
1570 size_t r = occupied_indices_I[1];
1572 std::vector<size_t> occupied_indices_J = alpha_J.findDifferentOccupations(alpha_I);
1573 size_t q = occupied_indices_J[0];
1574 size_t s = occupied_indices_J[1];
1578 int sign = alpha_I.operatorPhaseFactor(p) * alpha_I.operatorPhaseFactor(r) * alpha_J.operatorPhaseFactor(q) * alpha_J.operatorPhaseFactor(s);
1579 d_aaaa(p, q, r, s) += sign * c_I * c_J;
1580 d_aaaa(p, s, r, q) -= sign * c_I * c_J;
1581 d_aaaa(r, q, p, s) -= sign * c_I * c_J;
1582 d_aaaa(r, s, p, q) += sign * c_I * c_J;
1584 d_aaaa(q, p, s, r) += sign * c_I * c_J;
1585 d_aaaa(s, p, q, r) -= sign * c_I * c_J;
1586 d_aaaa(q, r, s, p) -= sign * c_I * c_J;
1587 d_aaaa(s, r, q, p) += sign * c_I * c_J;
1592 if ((alpha_I.countNumberOfExcitations(alpha_J) == 0) && (beta_I.countNumberOfExcitations(beta_J) == 2)) {
1595 std::vector<size_t> occupied_indices_I = beta_I.findDifferentOccupations(beta_J);
1596 size_t p = occupied_indices_I[0];
1597 size_t r = occupied_indices_I[1];
1599 std::vector<size_t> occupied_indices_J = beta_J.findDifferentOccupations(beta_I);
1600 size_t q = occupied_indices_J[0];
1601 size_t s = occupied_indices_J[1];
1605 int sign = beta_I.operatorPhaseFactor(p) * beta_I.operatorPhaseFactor(r) * beta_J.operatorPhaseFactor(q) * beta_J.operatorPhaseFactor(s);
1606 d_bbbb(p, q, r, s) += sign * c_I * c_J;
1607 d_bbbb(p, s, r, q) -= sign * c_I * c_J;
1608 d_bbbb(r, q, p, s) -= sign * c_I * c_J;
1609 d_bbbb(r, s, p, q) += sign * c_I * c_J;
1611 d_bbbb(q, p, s, r) += sign * c_I * c_J;
1612 d_bbbb(s, p, q, r) -= sign * c_I * c_J;
1613 d_bbbb(q, r, s, p) -= sign * c_I * c_J;
1614 d_bbbb(s, r, q, p) += sign * c_I * c_J;
1630 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1639 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1648 template <
typename Z = ONVBasis>
1652 const auto M = this->onv_basis.numberOfOrbitals();
1653 const auto dim = this->onv_basis.dimension();
1657 for (
size_t I = 0; I < dim; I++) {
1658 const auto& onv_I = this->onv_basis.onvWithIndex(I);
1662 const auto& occupied_indices_I = onv_I.occupiedIndices();
1663 for (
const auto& p : occupied_indices_I) {
1667 for (
size_t J = I + 1; J < dim; J++) {
1669 const auto& onv_J = this->onv_basis.onvWithIndex(J);
1673 if (onv_I.countNumberOfExcitations(onv_J) == 1) {
1674 const auto p = onv_I.findDifferentOccupations(onv_J)[0];
1675 const auto q = onv_J.findDifferentOccupations(onv_I)[0];
1677 const auto sign =
static_cast<double>(onv_I.operatorPhaseFactor(p) * onv_J.operatorPhaseFactor(q));
1678 const auto value = sign *
GQCP::conj(c_I) * c_J;
1696 template <
typename Z = ONVBasis>
1700 const auto M = this->onv_basis.numberOfOrbitals();
1701 const auto dim = this->onv_basis.dimension();
1706 for (
size_t I = 0; I < dim; I++) {
1707 const auto& onv_I = this->onv_basis.onvWithIndex(I);
1710 const auto& occupied_indices_I = onv_I.occupiedIndices();
1711 for (
const auto& p : occupied_indices_I) {
1712 for (
const auto& q : occupied_indices_I) {
1715 d(p, p, q, q) += value;
1716 d(p, q, q, p) -= value;
1722 for (
size_t J = I + 1; J < dim; J++) {
1723 const auto& onv_J = this->onv_basis.onvWithIndex(J);
1727 if (onv_I.countNumberOfExcitations(onv_J) == 1) {
1730 const auto p = onv_I.findDifferentOccupations(onv_J)[0];
1731 const auto q = onv_J.findDifferentOccupations(onv_I)[0];
1734 const auto sign =
static_cast<double>(onv_I.operatorPhaseFactor(p) * onv_J.operatorPhaseFactor(q));
1736 for (
size_t r = 0; r < M; r++) {
1737 if (onv_I.isOccupied(r) && onv_J.isOccupied(r)) {
1738 if ((p != r) && (q != r)) {
1739 const auto value = sign *
GQCP::conj(c_I) * c_J;
1741 d(p, q, r, r) += value;
1742 d(p, r, r, q) -= value;
1743 d(r, r, p, q) += value;
1744 d(r, q, p, r) -= value;
1756 else if (onv_I.countNumberOfExcitations(onv_J) == 2) {
1759 auto occupied_in_I = onv_I.findDifferentOccupations(onv_J);
1760 const auto p = occupied_in_I[0];
1761 const auto r = occupied_in_I[1];
1763 auto occupied_in_J = onv_J.findDifferentOccupations(onv_I);
1764 const auto q = occupied_in_J[0];
1765 const auto s = occupied_in_J[1];
1769 const auto sign =
static_cast<double>(onv_I.operatorPhaseFactor(p) * onv_I.operatorPhaseFactor(r) * onv_J.operatorPhaseFactor(q) * onv_J.operatorPhaseFactor(s));
1770 const auto value = sign *
GQCP::conj(c_I) * c_J;
1772 d(p, q, r, s) += value;
1773 d(p, s, r, q) -= value;
1774 d(r, s, p, q) += value;
1775 d(r, q, p, s) -= value;
1801 template <
typename Z = ONVBasis>
1804 if (system_onvs.size() != environment_onvs.size()) {
1805 throw std::invalid_argument(
"LinearExpansion::tensorizeCoefficients(std::vector<ONV>& system_onvs, std::vector<ONV>& environment_onvs) const: The amount of system ONVs should be exactly the same as the amount of environment ONVs.");
1809 const auto unique_onvs = [](
const std::vector<typename ONVBasis::ONV>& onvs) {
1811 std::vector<typename ONVBasis::ONV> onv_collection;
1812 for (
const auto& onv : onvs) {
1815 for (
const auto& unique_onv : onv_collection) {
1816 if (onv.asString() == unique_onv.asString()) {
1822 onv_collection.push_back(onv);
1825 return onv_collection;
1828 const auto system_onv_collection = unique_onvs(system_onvs);
1829 const auto environment_onv_collection = unique_onvs(environment_onvs);
1832 const auto onv_index = [](
const typename ONVBasis::ONV onv, std::vector<typename ONVBasis::ONV> onv_collection) {
1833 for (
int i = 0; i < onv_collection.size(); ++i) {
1834 if (onv == onv_collection[i]) {
1844 for (
size_t ij = 0; ij < system_onvs.size(); ++ij) {
1845 int i = onv_index(system_onvs[ij], system_onv_collection);
1846 int j = onv_index(environment_onvs[ij], environment_onv_collection);
1860 template <
typename Z = ONVBasis>
1865 std::vector<std::vector<SpinResolvedONV>> onvs(domain_partition.dimension());
1867 const auto partition_onv = [&](
const SpinUnresolvedONV& onv_alpha,
size_t I_alpha,
const SpinUnresolvedONV& onv_beta,
size_t I_beta) {
1868 const auto onv = GQCP::SpinResolvedONV(onv_alpha, onv_beta);
1869 const auto I_ab = this->
onvBasis().compoundAddress(I_alpha, I_beta);
1871 ONVPartition<SpinResolvedONV> onv_partition {domain_partition, onv};
1872 for (
size_t i = 0; i < onv_partition.dimension(); ++i) {
1873 onvs[i].push_back(onv_partition(i));
1875 adjusted_coefficients(I_ab) = this->
coefficient(I_ab) * onv_partition.phaseFactor();
1878 this->
onvBasis().forEach(partition_onv);
1885 return C.template einsum<1>(
"ij,kj->ik", C);
1896 template <
typename Z = ONVBasis>
1901 std::vector<std::vector<SpinUnresolvedONV>> onvs(domain_partition.dimension());
1903 const auto partition_onv = [&](
const SpinUnresolvedONV& onv,
size_t I) {
1904 ONVPartition<SpinUnresolvedONV> onv_partition {domain_partition, onv};
1905 for (
size_t i = 0; i < onv_partition.dimension(); ++i) {
1906 onvs[i].push_back(onv_partition(i));
1908 adjusted_coefficients(I) = this->
coefficient(I) * onv_partition.phaseFactor();
1911 this->
onvBasis().forEach(partition_onv);
1917 std::cout <<
"system onvs: " << std::endl;
1918 for (
size_t i = 0; i < this->
onvBasis().dimension(); i++) {
1919 std::cout << onvs[0][i] <<
"\t";
1921 std::cout << std::endl;
1922 std::cout <<
"environment onvs: " << std::endl;
1923 for (
size_t i = 0; i < this->
onvBasis().dimension(); i++) {
1924 std::cout << onvs[1][i] <<
"\t";
1926 std::cout << std::endl;
1929 return C.template einsum<1>(
"ij,kj->ik", C);
1936 template <
typename Z = Scalar>
1941 Eigen::ArrayXd c2_not_replaced = this->
coefficients().array().square();
1942 Eigen::ArrayXd c2 = c2_not_replaced.unaryExpr(
1943 [](
const double c) {
1944 return c < 1.0e-18 ? 1 : c;
1947 return -1 / std::log(2) * (c2 * c2.log()).sum();
1960 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
1964 if (orbital_index > this->onv_basis.numberOfOrbitals()) {
1965 throw std::invalid_argument(
"LinearExpansion::calculateSingleOrbitalEntropy(const size_t): The given orbital index is larger than the amount of orbitals in the system.");
1973 const auto& gamma_i_alpha = D.alpha().matrix()(orbital_index, orbital_index);
1974 const auto& gamma_i_beta = D.beta().matrix()(orbital_index, orbital_index);
1975 const auto& Gamma_ii_alpha_beta = d.alphaBeta().tensor()(orbital_index, orbital_index, orbital_index, orbital_index);
1981 rho(0, 0) += 1 - gamma_i_alpha - gamma_i_beta + Gamma_ii_alpha_beta;
1982 rho(1, 1) += gamma_i_alpha - Gamma_ii_alpha_beta;
1983 rho(2, 2) += gamma_i_beta - Gamma_ii_alpha_beta;
1984 rho(3, 3) += Gamma_ii_alpha_beta;
1989 for (
int i = 0; i < 4; i++) {
1990 if (abs(rho(i, i)) > 1e-12) {
1991 S -= rho(i, i) * log(rho(i, i));
2009 template <
typename Z1 = Scalar,
typename Z2 = ONVBasis>
2013 if (orbital_index > this->onv_basis.numberOfSpatialOrbitals()) {
2014 throw std::invalid_argument(
"LinearExpansion::calculateSingleOrbitalEntropy(const size_t): The given orbital index is larger than the amount of orbitals in the system.");
2021 const auto& gamma_i_alpha = D.alpha().matrix()(orbital_index, orbital_index);
2027 rho(0, 0) += 1 - gamma_i_alpha;
2028 rho(1, 1) += gamma_i_alpha;
2034 for (
int i = 0; i < 2; i++) {
2035 if (abs(rho(i, i)) > 1e-12) {
2036 S -= rho(i, i) * log(rho(i, i));
2057 template <typename ElectronPartition, typename Z = ONVBasis, std::enable_if_t<std::is_same<Z, SpinResolvedONVBasis>::value,
bool> =
true>
2060 double domain_probability = 0.0;
2061 const auto calculate_domain_probability = [&](
const SpinUnresolvedONV& onv_alpha,
size_t I_alpha,
const SpinUnresolvedONV& onv_beta,
size_t I_beta)
mutable {
2062 const SpinResolvedONV onv(onv_alpha, onv_beta);
2063 if (domain_partition.overlapWithONV(onv) == electron_partition) {
2064 const size_t I_ab = this->
onvBasis().compoundAddress(I_alpha, I_beta);
2065 domain_probability += std::pow(this->
coefficient(I_ab), 2);
2068 onv_basis.forEach(calculate_domain_probability);
2069 return domain_probability;
2080 template <typename ElectronPartition, typename Z = ONVBasis, std::enable_if_t<std::is_same<Z, SpinUnresolvedONVBasis>::value,
bool> =
true>
2083 double domain_probability = 0.0;
2084 const auto calculate_domain_probability = [&](
const SpinUnresolvedONV& onv,
size_t I)
mutable {
2085 if (domain_partition.overlapWithONV(onv) == electron_partition) {
2086 domain_probability += std::pow(this->
coefficient(I), 2);
2089 onv_basis.forEach(calculate_domain_probability);
2090 return domain_probability;
2103 template <
typename Z = ONVBasis>
2107 const auto& onv_basis = this->onv_basis;
2109 onv_basis.forEach([&onv_basis, &callback, &
coefficients](
const SpinUnresolvedONV& onv_alpha,
const size_t I_alpha,
const SpinUnresolvedONV& onv_beta,
const size_t I_beta) {
2110 const SpinResolvedONV onv {onv_alpha, onv_beta};
2111 const auto address = onv_basis.compoundAddress(I_alpha, I_beta);
2124 template <
typename Z = ONVBasis>
2128 const auto& onv_basis = this->onv_basis;
2130 onv_basis.forEach([&onv_basis, &callback, &
coefficients](
const SpinUnresolvedONV& onv,
const size_t I) {
2150 if (this->onv_basis.dimension() != other.onv_basis.dimension()) {
Definition: GSpinorBasis.hpp:62
Definition: LinearExpansion.hpp:59
static LinearExpansion< Scalar, ONVBasis > Normalized(const ONVBasis &onv_basis, const VectorX< Scalar > &coefficients)
Definition: LinearExpansion.hpp:141
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedSelectedONVBasis >::value, Orbital1DM< double > > calculate1DM() const
Definition: LinearExpansion.hpp:1631
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedONVBasis >::value > basisTransform(const RTransformation< double > &T)
Definition: LinearExpansion.hpp:414
enable_if_t< std::is_same< Z, SpinUnresolvedONVBasis >::value, void > forEach(const std::function< void(const Scalar, const SpinUnresolvedONV)> &callback) const
Definition: LinearExpansion.hpp:2125
enable_if_t< std::is_same< Z, SpinUnresolvedONVBasis >::value, Tensor< Scalar, 2 > > calculateSystemOrbitalRDM(const DiscreteDomainPartition &domain_partition) const
Definition: LinearExpansion.hpp:1897
double calculateProbabilityOfFindingElectronPartition(const DiscreteDomainPartition &domain_partition, const ElectronPartition &electron_partition) const
Definition: LinearExpansion.hpp:2058
_ONVBasis ONVBasis
Definition: LinearExpansion.hpp:65
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SeniorityZeroONVBasis >::value, SpinResolved2DM< double > > calculateSpinResolved2DM() const
Definition: LinearExpansion.hpp:1249
enable_if_t< std::is_same< Z, SpinUnresolvedONVBasis >::value, Scalar > calculateNDMElement(const std::vector< size_t > &bra_indices, const std::vector< size_t > &ket_indices) const
Definition: LinearExpansion.hpp:669
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SeniorityZeroONVBasis >::value, Orbital2DM< double > > calculate2DM() const
Definition: LinearExpansion.hpp:1232
enable_if_t< std::is_same< Z, SpinUnresolvedONVBasis >::value|std::is_same< Z, SpinResolvedONVBasis >::value, GQCP::Tensor< Scalar, 2 > > tensorizeCoefficients(const std::vector< typename ONVBasis::ONV > &system_onvs, const std::vector< typename ONVBasis::ONV > &environment_onvs) const
Definition: LinearExpansion.hpp:1802
enable_if_t< std::is_same< Z, SpinUnresolvedSelectedONVBasis >::value, G2DM< Scalar > > calculate2DM() const
Definition: LinearExpansion.hpp:1697
enable_if_t< std::is_same< Z, SpinResolvedONVBasis >::value, Tensor< Scalar, 2 > > calculateSystemOrbitalRDM(const DiscreteDomainPartition &domain_partition) const
Definition: LinearExpansion.hpp:1861
static enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedSelectedONVBasis >::value, LinearExpansion< double, SpinResolvedSelectedONVBasis > > FromGAMESSUS(const std::string &GAMESSUS_filename)
Definition: LinearExpansion.hpp:173
Scalar coefficient(const size_t i) const
Definition: LinearExpansion.hpp:388
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedSelectedONVBasis >::value, Orbital2DM< double > > calculate2DM() const
Definition: LinearExpansion.hpp:1640
LinearExpansion()=default
enable_if_t< std::is_same< Z, double >::value, double > calculateShannonEntropy() const
Definition: LinearExpansion.hpp:1937
const VectorX< Scalar > & coefficients() const
Definition: LinearExpansion.hpp:393
static LinearExpansion< Scalar, ONVBasis > Random(const ONVBasis &onv_basis)
Definition: LinearExpansion.hpp:156
enable_if_t< std::is_same< Z, SpinUnresolvedSelectedONVBasis >::value, Scalar > calculateNDMElement(const std::vector< size_t > &bra_indices, const std::vector< size_t > &ket_indices) const
Definition: LinearExpansion.hpp:757
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SeniorityZeroONVBasis >::value, SpinResolved1DM< double > > calculateSpinResolved1DM() const
Definition: LinearExpansion.hpp:1240
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinUnresolvedONVBasis >::value, G1DM< double > > calculate1DM() const
Definition: LinearExpansion.hpp:595
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedONVBasis >::value, Orbital2DM< double > > calculate2DM() const
Definition: LinearExpansion.hpp:1185
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedONVBasis >::value, SpinResolved1DM< double > > calculateSpinResolved1DM() const
Definition: LinearExpansion.hpp:843
enable_if_t< std::is_same< Z, SpinResolvedONVBasis >::value, void > forEach(const std::function< void(const Scalar, const SpinResolvedONV)> &callback) const
Definition: LinearExpansion.hpp:2104
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SeniorityZeroONVBasis >::value, Orbital1DM< double > > calculate1DM() const
Definition: LinearExpansion.hpp:1198
enable_if_t< std::is_same< Z1, Scalar >::value &&std::is_same< Z2, SeniorityZeroONVBasis >::value, double > calculateSingleOrbitalEntropy(const size_t orbital_index) const
Definition: LinearExpansion.hpp:2010
static LinearExpansion< Scalar, ONVBasis > HartreeFock(const ONVBasis &onv_basis)
Definition: LinearExpansion.hpp:125
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedONVBasis >::value, double > calculateSingleOrbitalEntropy(const size_t orbital_index) const
Definition: LinearExpansion.hpp:1961
_Scalar Scalar
Definition: LinearExpansion.hpp:62
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedONVBasis >::value, SpinResolved2DM< double > > calculateSpinResolved2DM() const
Definition: LinearExpansion.hpp:963
static LinearExpansion< Scalar, ONVBasis > Constant(const ONVBasis &onv_basis)
Definition: LinearExpansion.hpp:109
static enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinUnresolvedONVBasis >::value, LinearExpansion< double, SpinUnresolvedONVBasis > > FromONVProjection(const SpinUnresolvedONV &onv_of, const GSpinorBasis< double, GTOShell > &spinor_basis_on, const GSpinorBasis< double, GTOShell > &spinor_basis_of)
Definition: LinearExpansion.hpp:342
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedONVBasis >::value, Orbital1DM< double > > calculate1DM() const
Definition: LinearExpansion.hpp:1176
const ONVBasis & onvBasis() const
Definition: LinearExpansion.hpp:398
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedSelectedONVBasis >::value, SpinResolved2DM< double > > calculateSpinResolved2DM() const
Definition: LinearExpansion.hpp:1399
static enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedONVBasis >::value, LinearExpansion< double, SpinResolvedONVBasis > > FromONVProjection(const SpinResolvedONV &onv, const RSpinOrbitalBasis< double, GTOShell > &r_spinor_basis, const USpinOrbitalBasis< double, GTOShell > &u_spinor_basis)
Definition: LinearExpansion.hpp:289
bool isApprox(const LinearExpansion< Scalar, ONVBasis > &other, double tolerance=1.0e-12) const
Definition: LinearExpansion.hpp:2148
enable_if_t< std::is_same< Z1, double >::value &&std::is_same< Z2, SpinResolvedSelectedONVBasis >::value, SpinResolved1DM< double > > calculateSpinResolved1DM() const
Definition: LinearExpansion.hpp:1319
LinearExpansion(const ONVBasis &onv_basis, const VectorX< Scalar > &coefficients)
Definition: LinearExpansion.hpp:87
enable_if_t< std::is_same< Z, SpinUnresolvedSelectedONVBasis >::value, G1DM< Scalar > > calculate1DM() const
Definition: LinearExpansion.hpp:1649
Definition: Matrix.hpp:47
Definition: MixedSpinResolved2DMComponent.hpp:37
Definition: Orbital1DM.hpp:42
Definition: Orbital2DM.hpp:41
Definition: PureSpinResolved2DMComponent.hpp:36
Definition: RSpinOrbitalBasis.hpp:63
SQOverlapOperator overlap() const
Definition: SimpleSpinorBasis.hpp:118
const Transformation & expansion() const
Definition: SimpleSpinorBasis.hpp:98
Definition: SpinResolved1DMComponent.hpp:41
Definition: SpinResolved1DM.hpp:44
static SpinResolved1DM< Scalar > FromOrbital1DM(const Orbital1DM< Scalar > &D)
Definition: SpinResolved1DM.hpp:79
Definition: SpinResolved2DM.hpp:44
Definition: SquareMatrix.hpp:39
size_t dimension() const
Definition: SquareMatrix.hpp:299
static Self Identity(const size_t dim)
Definition: SquareMatrix.hpp:143
std::array< Self, 2 > noPivotLUDecompose() const
Definition: SquareMatrix.hpp:335
static Self Zero(const size_t dim)
Definition: SquareMatrix.hpp:289
Definition: SquareRankFourTensor.hpp:36
static Self Zero(const size_t dim)
Definition: SquareRankFourTensor.hpp:147
Definition: Tensor.hpp:46
const Base & Eigen() const
Definition: Tensor.hpp:116
Definition: USpinOrbitalBasis.hpp:60
ScalarUSQOneElectronOperator< ExpansionScalar > overlap() const
Definition: USpinOrbitalBasis.hpp:406
UTransformation< ExpansionScalar > expansion() const
Definition: USpinOrbitalBasis.hpp:238
Definition: BaseOneElectronIntegralBuffer.hpp:25
typename std::enable_if< B, T >::type enable_if_t
Definition: type_traits.hpp:37
complex conj(const complex &c)
Definition: complex.cpp:31
@ beta
Definition: Spin.hpp:29
@ alpha
Definition: Spin.hpp:28