Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
e1dba87
set hardcoded biorthogonal coeffs till rank 7
ABesharat Oct 13, 2025
1323fc6
rank 7
ABesharat Oct 13, 2025
897a42a
discard redundant assertion
ABesharat Oct 13, 2025
a22809c
better name: computed_coefficients
ABesharat Oct 13, 2025
dbcd4e5
add hardcoded file to cmakelist
ABesharat Oct 13, 2025
8fd5be0
v2: correct rescaling factor
ABesharat Oct 13, 2025
47ccfe1
renaming original coeffs to computed_coefficients
ABesharat Oct 13, 2025
93829df
Merge remote-tracking branch 'origin/azam/feature/hardcoded_biorthogo…
ABesharat Oct 13, 2025
70ef68a
renaming
ABesharat Nov 11, 2025
4fc0898
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 8, 2025
fc0dcda
discard old coefficients
ABesharat Dec 8, 2025
f309f62
discard only the old coefficients, not num_perms
ABesharat Dec 8, 2025
b5da4b8
no inline anymore for performance
ABesharat Dec 10, 2025
25bb6f4
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 10, 2025
3926bde
at max rank 6 is enough
ABesharat Dec 10, 2025
e485b9c
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 12, 2025
87b8177
test_eval_ta: add rank 4 nns test, fix rank 3
ABesharat Dec 13, 2025
5ca6d55
test_eval_btas: fix nns for rank 3
ABesharat Dec 13, 2025
188825c
add hardcoded biortho coeffs and nns projection
ABesharat Dec 13, 2025
8e66ac7
fix include
ABesharat Dec 13, 2025
1dc89b3
use hardcoded biortho coeffs for rank<=6, otherwise use computed ones
ABesharat Dec 13, 2025
53b47be
do not call nns with int type ,use hardcoded nns for rank<=6, otherwi…
ABesharat Dec 13, 2025
a28d886
make libperm public to build the same order of permutations
ABesharat Dec 13, 2025
ab8f453
fix include for Eigen!
ABesharat Dec 13, 2025
d5b20f6
change the name of hardcoded nns fn
ABesharat Dec 14, 2025
278dcc3
renaming again!
ABesharat Dec 14, 2025
aede8b3
renaming hardcoded_biortho_coeffs fn
ABesharat Dec 14, 2025
4b1a92f
change assert to SEQUANT_ASSERT
ABesharat Dec 15, 2025
8ee5a57
no need to have rescaling for v2. new nns is enough for restoring WK …
ABesharat Dec 18, 2025
a3345c4
documentation correction
ABesharat Dec 18, 2025
78dc616
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 18, 2025
d2323d0
use abort for calling nns with int type
ABesharat Dec 21, 2025
0f4ab0c
normalization factor of S
ABesharat Dec 22, 2025
acc25f8
Remove additional print statements, cleaning
ABesharat Dec 25, 2025
877e3d4
address the requested changes
ABesharat Dec 25, 2025
0a60656
address the requested changes, except the namespace
ABesharat Dec 26, 2025
14fbd13
extract libperm calls into a helper function to avoid public dependency
ABesharat Dec 27, 2025
f4a0c82
Optimize build command with parallel jobs
ABesharat Dec 28, 2025
7087e16
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Dec 28, 2025
519e68a
a better name: biorth_threshold
ABesharat Jan 3, 2026
2e67e8e
use default threshold for compute_nns_p_matricx to avoid an additiona…
ABesharat Jan 3, 2026
aa7a41c
add some documentations
ABesharat Jan 11, 2026
69ab3a1
clear documentation
ABesharat Jan 12, 2026
af93394
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Jan 12, 2026
2d10389
apply encapsulation for nns
ABesharat Jan 15, 2026
a9a17b1
memoize nns_projection weights
ABesharat Jan 16, 2026
afed9c4
add include
ABesharat Jan 16, 2026
1ca7fa6
dox cleanup
evaleev Jan 16, 2026
ff05b7c
nns_projection_weights: no third lock needed to return the result
evaleev Jan 16, 2026
4732bf5
removed the no-longer-used biorthogonalization_hardcoded.ipp
evaleev Jan 16, 2026
ecde7eb
memoize biorthogonal coeffs by lambda to have separate cache for hard…
ABesharat Jan 16, 2026
5f490ef
Merge remote-tracking branch 'refs/remotes/origin/azam/feature/hardco…
ABesharat Jan 16, 2026
333f296
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Jan 16, 2026
6697a4e
Merge remote-tracking branch 'refs/remotes/origin/master' into azam/f…
ABesharat Jan 16, 2026
8f42dac
remove the redundant header include
ABesharat Jan 16, 2026
2e171a8
move Eigen usage from public header to implementation
ABesharat Jan 16, 2026
370bd30
remove the redundant header include
ABesharat Jan 16, 2026
e6adbab
biorthogonalization.cpp: forward declaration to avoid having Eigen in…
ABesharat Jan 16, 2026
72dac7e
move hardcoded contents to biorthogonalization.cpp and hpp
ABesharat Jan 17, 2026
711e460
add to header file to keep the documentation
ABesharat Jan 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 66 additions & 84 deletions SeQuant/core/eval/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <SeQuant/core/index.hpp>
#include <SeQuant/core/logger.hpp>
#include <SeQuant/core/utility/macros.hpp>
#include <SeQuant/domain/mbpt/biorthogonalization.hpp>

#include <TiledArray/einsum/tiledarray.h>
#include <btas/btas.h>
Expand Down Expand Up @@ -355,17 +356,13 @@ auto biorthogonal_nns_project_ta(TA::DistArray<Args...> const& arr,
SEQUANT_ASSERT(bra_rank <= rank);
size_t const ket_rank = rank - bra_rank;

if (rank <= 4) {
return arr;
}
// Residuals of rank 4 or less have no redundancy and don't require NNS
// projection
if (rank <= 4) return arr;

using numeric_type = typename TA::DistArray<Args...>::numeric_type;

size_t factorial_ket = 1;
for (size_t i = 2; i <= ket_rank; ++i) {
factorial_ket *= i;
}
numeric_type norm_factor = numeric_type(1) / numeric_type(factorial_ket);
const auto& nns_p_coeffs = nns_projection_weights<numeric_type>(ket_rank);

TA::DistArray<Args...> result;

Expand All @@ -375,43 +372,28 @@ auto biorthogonal_nns_project_ta(TA::DistArray<Args...> const& arr,

const auto lannot = ords_to_annot(perm);

auto process_permutations = [&lannot](const TA::DistArray<Args...>& input_arr,
size_t range_rank, perm_t range_perm,
const std::string& other_annot,
bool is_bra) -> TA::DistArray<Args...> {
if (range_rank <= 1) return input_arr;
TA::DistArray<Args...> result;
if (ket_rank > 2 && !nns_p_coeffs.empty()) {
const auto bra_annot = bra_rank == 0 ? "" : ords_to_annot(bra_perm);

auto callback = [&]([[maybe_unused]] int parity) {
const auto range_annot = ords_to_annot(range_perm);
const auto annot = other_annot.empty()
? range_annot
: (is_bra ? range_annot + "," + other_annot
: other_annot + "," + range_annot);
size_t num_perms = nns_p_coeffs.size();
for (size_t perm_rank = 0; perm_rank < num_perms; ++perm_rank) {
perm_t permuted_ket =
compute_permuted_indices(ket_perm, perm_rank, ket_rank);

numeric_type coeff = nns_p_coeffs[perm_rank];

const auto ket_annot = ords_to_annot(permuted_ket);
const auto annot =
bra_annot.empty() ? ket_annot : bra_annot + "," + ket_annot;

// ignore parity, all permutations get same coefficient
numeric_type p_ = 1;
if (result.is_initialized()) {
result(lannot) += p_ * input_arr(annot);
result(lannot) += coeff * arr(annot);
} else {
result(lannot) = p_ * input_arr(annot);
result(lannot) = coeff * arr(annot);
}
};
antisymmetric_permutation(ParticleRange{range_perm.begin(), range_rank},
callback);
return result;
};

// identity term with coefficient +1
result(lannot) = arr(lannot);

// process only ket permutations with coefficient norm_factor
if (ket_rank > 1) {
const auto bra_annot = bra_rank == 0 ? "" : ords_to_annot(bra_perm);
auto ket_result =
process_permutations(arr, ket_rank, ket_perm, bra_annot, false);

result(lannot) -= norm_factor * ket_result(lannot);
}
} else {
result(lannot) = arr(lannot);
}

TA::DistArray<Args...>::wait_for_lazy_cleanup(result.world());
Expand All @@ -428,64 +410,52 @@ auto biorthogonal_nns_project_ta(TA::DistArray<Args...> const& arr,
template <typename... Args>
auto biorthogonal_nns_project_btas(btas::Tensor<Args...> const& arr,
size_t bra_rank) {
using ranges::views::concat;
using ranges::views::iota;
size_t const rank = arr.rank();
SEQUANT_ASSERT(bra_rank <= rank);
size_t const ket_rank = rank - bra_rank;

if (rank <= 4) {
return arr;
}
// Residuals of rank 4 or less have no redundancy and don't require NNS
// projection
if (rank <= 4) return arr;

using numeric_type = typename btas::Tensor<Args...>::numeric_type;

size_t factorial_ket = 1;
for (size_t i = 2; i <= ket_rank; ++i) {
factorial_ket *= i;
}
numeric_type norm_factor = numeric_type(1) / numeric_type(factorial_ket);
const auto& nns_p_coeffs = nns_projection_weights<numeric_type>(ket_rank);

btas::Tensor<Args...> result;

perm_t perm = iota(size_t{0}, rank) | ranges::to<perm_t>;
perm_t bra_perm = iota(size_t{0}, bra_rank) | ranges::to<perm_t>;
perm_t ket_perm = iota(bra_rank, rank) | ranges::to<perm_t>;
const auto lannot = iota(size_t{0}, rank) | ranges::to<perm_t>;

auto process_permutations = [&lannot](const btas::Tensor<Args...>& input_arr,
size_t range_rank, perm_t range_perm,
const perm_t& other_perm, bool is_bra) {
if (range_rank <= 1) return input_arr;
btas::Tensor<Args...> result{input_arr.range()};
result.fill(0);
if (ket_rank > 2 && !nns_p_coeffs.empty()) {
bool result_initialized = false;

auto callback = [&]([[maybe_unused]] int parity) {
const auto annot =
is_bra ? concat(range_perm, other_perm) | ranges::to<perm_t>()
: concat(other_perm, range_perm) | ranges::to<perm_t>();
size_t num_perms = nns_p_coeffs.size();
for (size_t perm_rank = 0; perm_rank < num_perms; ++perm_rank) {
perm_t permuted_ket =
compute_permuted_indices(ket_perm, perm_rank, ket_rank);

// ignore parity, all permutations get same coefficient
numeric_type p_ = 1;
btas::Tensor<Args...> temp;
btas::permute(input_arr, lannot, temp, annot);
btas::scal(p_, temp);
result += temp;
};
numeric_type coeff = nns_p_coeffs[perm_rank];

antisymmetric_permutation(ParticleRange{range_perm.begin(), range_rank},
callback);
return result;
};
perm_t annot = bra_perm;
annot.insert(annot.end(), permuted_ket.begin(), permuted_ket.end());

// identity term with coefficient +1
auto result = arr;
btas::Tensor<Args...> temp;
btas::permute(arr, annot, temp, perm);
btas::scal(coeff, temp);

// process only ket permutations with coefficient norm_factor
if (ket_rank > 1) {
const auto bra_annot = bra_rank == 0 ? perm_t{} : bra_perm;
auto ket_result =
process_permutations(arr, ket_rank, ket_perm, bra_annot, false);
if (result_initialized) {
result += temp;
} else {
result = temp;
result_initialized = true;
}
}

btas::scal(norm_factor, ket_result);
result -= ket_result;
} else {
result = arr;
}

return result;
Expand Down Expand Up @@ -903,8 +873,14 @@ class ResultTensorTA final : public Result {

[[nodiscard]] ResultPtr biorthogonal_nns_project(
size_t bra_rank) const override {
return eval_result<this_type>(
biorthogonal_nns_project_ta(get<ArrayT>(), bra_rank));
if constexpr (std::is_integral_v<numeric_type>) {
SEQUANT_ABORT(
"biorthogonal_nns_project is not supported for integral numeric "
"types");
} else {
return eval_result<this_type>(
biorthogonal_nns_project_ta(get<ArrayT>(), bra_rank));
}
}

private:
Expand Down Expand Up @@ -1166,8 +1142,14 @@ class ResultTensorBTAS final : public Result {

[[nodiscard]] ResultPtr biorthogonal_nns_project(
[[maybe_unused]] size_t bra_rank) const override {
return eval_result<ResultTensorBTAS<T>>(
biorthogonal_nns_project_btas(get<T>(), bra_rank));
if constexpr (std::is_integral_v<numeric_type>) {
SEQUANT_ABORT(
"biorthogonal_nns_project is not supported for integral numeric "
"types");
} else {
return eval_result<ResultTensorBTAS<T>>(
biorthogonal_nns_project_btas(get<T>(), bra_rank));
}
}

private:
Expand Down
Loading