Skip to content

Commit 19d8ad5

Browse files
authored
Merge pull request #6 from mili1247/unstable
add measure_statehist
2 parents 5185fde + 8995421 commit 19d8ad5

File tree

12 files changed

+158
-0
lines changed

12 files changed

+158
-0
lines changed

c++/triqs_ctseg/configuration.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,30 @@ double K_overlap(std::vector<segment_t> const &seglist, tau_t const &tau, bool i
222222
return is_c ? result : -result;
223223
}
224224

225+
// ---------------------------
226+
227+
// List of operators containing all colors.
228+
// Time are ordered in decreasing order, in agreement with the whole physic literature.
229+
std::vector<colored_ops_t> colored_ordered_ops(std::vector<std::vector<segment_t>> const &seglists) {
230+
int c = 0; // index of color
231+
std::vector<colored_ops_t> ops_list; // list of all the operators
232+
for (auto const &seglist : seglists) {
233+
for (auto const &s : seglist) {
234+
ops_list.push_back({s.tau_c, c, false});
235+
ops_list.push_back({s.tau_cdag, c, true});
236+
if (is_cyclic(s)) {
237+
ops_list.push_back({tau_t::beta(), c, false});
238+
ops_list.push_back({tau_t::zero(), c, true});
239+
}
240+
}
241+
++c;
242+
}
243+
std::sort(ops_list.begin(), ops_list.end(), [](const colored_ops_t &a, const colored_ops_t &b) {
244+
return b.tau < a.tau; // Note the order of b and a for descending sort
245+
});
246+
return ops_list;
247+
}
248+
225249
// =================== PRINTING ========================
226250

227251
std::ostream &operator<<(std::ostream &out, std::vector<segment_t> const &sl) {
@@ -248,3 +272,11 @@ std::ostream &operator<<(std::ostream &out, configuration_t const &config) {
248272
return out;
249273
}
250274

275+
// ---------------------------
276+
277+
std::ostream &operator<<(std::ostream &out, std::vector<colored_ops_t> const &col) {
278+
for (auto const &[i, co] : itertools::enumerate(col))
279+
out << "\n" << "i: " << i << ", tau: " << co.tau << ", color: " << co.color
280+
<< ", " << (co.is_cdag ? "cdag" : "c");
281+
return out;
282+
}

c++/triqs_ctseg/configuration.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ struct segment_t {
4141
static segment_t full_line() { return {tau_t::beta(), tau_t::zero()}; }
4242
};
4343

44+
// operator descriptor: time, color, is_cdag[creation/annihilation]
45+
struct colored_ops_t {
46+
tau_t tau;
47+
int color;
48+
bool is_cdag;
49+
};
50+
4451
// simple alias
4552
using vec_seg_iter_t = std::vector<segment_t>::const_iterator;
4653

@@ -141,9 +148,15 @@ double K_overlap(std::vector<segment_t> const &seglist, tau_t const &tau_c, tau_
141148
double K_overlap(std::vector<segment_t> const &seglist, tau_t const &tau, bool is_c, gf<imtime, matrix_valued> const &K,
142149
int c1, int c2);
143150

151+
// List of operators containing all colors.
152+
std::vector<colored_ops_t> colored_ordered_ops(std::vector<std::vector<segment_t>> const &seglists);
153+
144154
// =================== PRINTING ========================
145155

146156
std::ostream &operator<<(std::ostream &out, std::vector<segment_t> const &sl);
147157

148158
std::ostream &operator<<(std::ostream &out, configuration_t const &config);
149159
template <> struct fmt::formatter<configuration_t> : ostream_formatter {};
160+
161+
std::ostream &operator<<(std::ostream &out, std::vector<colored_ops_t> const &col);
162+
template <> struct fmt::formatter<std::vector<colored_ops_t>> : ostream_formatter {};

c++/triqs_ctseg/measures.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
#include "./measures/density.hpp"
88
#include "./measures/sign.hpp"
99
#include "./measures/perturbation_order_histo.hpp"
10+
#include "./measures/state_hist.hpp"
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "./state_hist.hpp"
2+
#include "../logs.hpp"
3+
4+
namespace measures {
5+
6+
state_hist::state_hist(params_t const &p, work_data_t const &wdata, configuration_t const &config, results_t &results)
7+
: wdata{wdata}, config{config}, results{results} {
8+
9+
beta = p.beta;
10+
H = nda::zeros<double>(ipow(2, config.n_color()));
11+
}
12+
13+
// -------------------------------------
14+
15+
void state_hist::accumulate(double s) {
16+
17+
LOG("\n =================== MEASURE <state histogram> ================ \n");
18+
19+
/// Measure the state histogram
20+
/**
21+
*Measures the time the impurity spends in a certain atomic state:
22+
* an atomic state is characterized by occupation number for each color, e.g.
23+
* $|n_1 n_2 n_3 n_4\rangle = |0 1 1 0\rangle$ for a model with 4 colors
24+
*
25+
* - the index of a state in the histogram is given by $\sum_i n_i 2^i$
26+
*
27+
* - the length of the histogram is 2^n_colors
28+
*/
29+
30+
Z += s;
31+
32+
double tau_prev = beta; // time of prevous operator; start with beta
33+
nda::vector<bool> state = nda::zeros<bool>(config.n_color());
34+
for (auto const &op : colored_ordered_ops(config.seglists)) {
35+
int state_idx = 0;
36+
for (auto c : range(config.n_color()))
37+
if (state(c)) state_idx += ipow(2, c); // get the index of the impurity state
38+
H(state_idx) += (tau_prev - op.tau);
39+
tau_prev = (double)op.tau;
40+
ALWAYS_EXPECTS((state(op.color) == op.is_cdag), "Operator error at color {}", op.color);
41+
state(op.color) = !op.is_cdag;
42+
}
43+
44+
// get edge state contribution; tau_prev has time of last operator
45+
ALWAYS_EXPECTS((state == nda::zeros<bool>(config.n_color())), "Operator error");
46+
H(0) += tau_prev;
47+
}
48+
// -------------------------------------
49+
50+
void state_hist::collect_results(mpi::communicator const &c) {
51+
52+
Z = mpi::all_reduce(Z, c);
53+
H = mpi::all_reduce(H, c);
54+
H = H / (Z * beta);
55+
56+
// store the result (not reused later, hence we can move it).
57+
results.state_hist = std::move(H);
58+
}
59+
} // namespace measures
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
#include "../configuration.hpp"
3+
#include "../work_data.hpp"
4+
#include "../results.hpp"
5+
#include "../util.hpp"
6+
7+
namespace measures {
8+
9+
struct state_hist {
10+
11+
work_data_t const &wdata;
12+
configuration_t const &config;
13+
results_t &results;
14+
double beta;
15+
16+
nda::vector<double> H;
17+
18+
double Z = 0;
19+
20+
state_hist(params_t const &params, work_data_t const &wdata, configuration_t const &config, results_t &results);
21+
22+
void accumulate(double s);
23+
void collect_results(mpi::communicator const &c);
24+
};
25+
} // namespace measures

c++/triqs_ctseg/params.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ struct solve_params_t {
108108
/// Whether to measure langle s_x(tau)s_x(0)rangle (see [[measure_sperp_tau]])
109109
bool measure_sperpt = false;
110110

111+
/// Whether to measure state histograms (see [[measure_statehist]])
112+
bool measure_statehist = false;
113+
111114
/// Hartree shift of the chem pot
112115
nda::vector<double> hartree_shift = nda::vector<double>{};
113116

c++/triqs_ctseg/results.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ void h5_write(h5::group h5group, std::string subgroup_name, results_t const &c)
1515
h5_write(grp, "densities", c.densities);
1616
h5_write(grp, "perturbation_order_histo_Delta", c.perturbation_order_histo_Delta);
1717
h5_write(grp, "perturbation_order_histo_Jperp", c.perturbation_order_histo_Jperp);
18+
h5_write(grp, "state_hist", c.state_hist);
1819
}
1920

2021
//------------------------------------
@@ -34,4 +35,5 @@ void h5_read(h5::group h5group, std::string subgroup_name, results_t &c) {
3435
h5_read(grp, "densities", c.densities);
3536
h5_read(grp, "perturbation_order_histo_Delta", c.perturbation_order_histo_Delta);
3637
h5_read(grp, "perturbation_order_histo_Jperp", c.perturbation_order_histo_Jperp);
38+
h5_read(grp, "state_hist", c.state_hist);
3739
}

c++/triqs_ctseg/results.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ struct results_t {
3838
/// Perturbation order histogram
3939
std::optional<triqs::stat::histogram> perturbation_order_histo_Jperp;
4040

41+
/// State histogram
42+
std::optional<nda::vector<double>> state_hist;
43+
4144
/// Average sign
4245
double sign;
4346
};

c++/triqs_ctseg/solver_core.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ void solver_core::solve(solve_params_t const &solve_params) {
9393
if (p.measure_sperpt) CTQMC.add_measure(measures::sperp_tau{p, wdata, config, results}, "<s_x s_x>(tau)");
9494
if (p.measure_perturbation_order_histograms)
9595
CTQMC.add_measure(measures::perturbation_order_histo{p, wdata, config, results}, "Perturbation orders");
96+
if (p.measure_statehist) CTQMC.add_measure(measures::state_hist{p, wdata, config, results}, "State histograms");
9697

9798
// Run and collect results
9899
CTQMC.warmup_and_accumulate(p.n_warmup_cycles, p.n_cycles, p.length_cycle,

c++/triqs_ctseg/util.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@ long det_lower_bound_x(auto const &d, auto const &x) {
2626
long det_lower_bound_y(auto const &d, auto const &y) {
2727
return lower_bound([&d](long i) { return d.get_y(i).first; }, d.size(), y);
2828
}
29+
30+
// Integer power
31+
constexpr unsigned int ipow(unsigned int n, unsigned int m) {
32+
return m == 0 ? 1 : m == 1 ? n : n * ipow(n, m - 1);
33+
}

0 commit comments

Comments
 (0)