Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hilbert_space] Simplify algorithm of space_partition::merge_subspaces() #961

Open
wants to merge 1 commit into
base: 3.3.x
Choose a base branch
from
Open
Changes from all commits
Commits
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
52 changes: 18 additions & 34 deletions c++/triqs/hilbert_space/space_partition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,42 +146,26 @@ namespace triqs {
tmp_state(i) = amplitude_t(0.);
}

// 'Zigzag' traversal algorithm
while (!Cd_connections.empty()) {

// Take one C^+ - connection
// C^+|lower_subspace> = |upper_subspace>
idx_t lower_subspace, upper_subspace;
std::tie(lower_subspace, upper_subspace) = *std::begin(Cd_connections);

// - Reveals all subspaces reachable from lower_subspace by application of
// a 'zigzag' product C^+ C C^+ C C^+ ... of any length.
// - Removes all visited connections from Cd_connections/C_connections.
// - Merges lower_subspace with all subspaces generated from lower_subspace by application of (C C^+)^(2*n).
// - Merges upper_subspace with all subspaces generated from upper_subspace by application of (C^+ C)^(2*n).
std::function<void(idx_t, bool)> zigzag_traversal = [this, lower_subspace, upper_subspace, &Cd_connections, &C_connections,
&zigzag_traversal](idx_t i_subspace, // find all connections starting from i_subspace
bool upwards // if true, C^+ connection, otherwise C connection
) {
std::multimap<idx_t, idx_t>::iterator it;
while ((it = (upwards ? Cd_connections : C_connections).find(i_subspace)) != (upwards ? Cd_connections : C_connections).end()) {

auto f_subspace = it->second;
(upwards ? Cd_connections : C_connections).erase(it);

if (upwards)
subspaces.link(f_subspace, upper_subspace);
else
subspaces.link(f_subspace, lower_subspace);

// Recursively apply to all found f_subspace's with a 'flipped' direction
zigzag_traversal(f_subspace, !upwards);
// Merge all 'out' subspaces corresponding to the same 'in' subspace
// in 'conn'.
auto merge_conn_targets = [this](auto const& conn) {
if(conn.empty()) return;

auto conn_it = conn.cbegin();
idx_t i_subspace = conn_it->first;
idx_t f_subspace = conn_it->second;
++conn_it;
for(; conn_it != conn.cend(); ++conn_it) {
if(conn_it->first == i_subspace) {
subspaces.link(f_subspace, conn_it->second);
} else {
std::tie(i_subspace, f_subspace) = *conn_it;
}
};
}
};

// Apply to all C^+ connections starting from lower_subspace
zigzag_traversal(lower_subspace, true);
}
merge_conn_targets(Cd_connections);
merge_conn_targets(C_connections);

_update_index();

Expand Down