7#include "configuration.hpp"
14 std::pair<segment_t, segment_t> split_cyclic_segment(segment_t
const &s) {
22 bool disjoint(segment_t
const &s1, segment_t
const &s2) {
24 auto [sl, sr] = split_cyclic_segment(s2);
25 return disjoint(s1, sl) and disjoint(s1, sr);
27 return s1.tau_cdag > s2.tau_c or s2.tau_cdag > s1.tau_c;
33 bool tau_in_seg(
tau_t const &tau, segment_t
const &seg) {
36 auto [sl, sr] = split_cyclic_segment(seg);
37 return tau_in_seg(tau, sl) or tau_in_seg(tau, sr);
39 return (tau <= seg.tau_c and tau > seg.tau_cdag);
45 double overlap(segment_t
const &s1, segment_t
const &s2) {
48 auto [sl, sr] = split_cyclic_segment(s1);
49 return overlap(sl, s2) + overlap(sr, s2);
51 if (is_cyclic(s2))
return overlap(s2, s1);
54 if (s1.tau_cdag >= s2.tau_c or s2.tau_cdag >= s1.tau_c)
return 0;
58 tau_t tau_start = std::min(s1.tau_c, s2.tau_c);
59 tau_t tau_end = std::max(s1.tau_cdag, s2.tau_cdag);
60 assert(tau_start >= tau_end);
61 return double(tau_start - tau_end);
66 vec_seg_iter_t lower_bound(std::vector<segment_t>
const &seglist,
tau_t const &tau) {
68 return std::lower_bound(seglist.begin(), seglist.end(), tau, [](
auto &&s,
auto &&t) { return s.tau_c > t; });
76 vec_seg_iter_t find_segment_left(std::vector<segment_t>
const &seglist, segment_t
const &seg) {
77 auto seg_iter = std::upper_bound(seglist.begin(), seglist.end(), seg);
78 return (seg_iter == seglist.begin()) ? seg_iter : --seg_iter;
83 int n_at_boundary(std::vector<segment_t>
const &sl) {
84 if (sl.empty())
return 0;
85 return (is_cyclic(sl.back()) or is_full_line(sl.back())) ? 1 : 0;
91 int n_tau(
tau_t const &tau, std::vector<segment_t>
const &seglist) {
92 if (seglist.empty())
return 0;
93 auto it = find_segment_left(seglist, segment_t{tau, tau});
94 return (tau_in_seg(tau, *it) or tau_in_seg(tau, seglist.back())) ? 1 : 0;
99 std::vector<segment_t> flip(std::vector<segment_t>
const &sl) {
101 return {segment_t::full_line()};
103 if (sl.size() == 1 and is_full_line(sl[0]))
107 auto fsl = std::vector<segment_t>(N);
108 if (is_cyclic(sl.back()))
109 for (
auto i : range(N)) {
110 long ind = (i == 0) ? N - 1 : i - 1;
111 fsl[i] = segment_t{sl[ind].tau_cdag, sl[i].tau_c, sl[ind].J_cdag, sl[i].J_c};
114 for (
auto i : range(N)) {
115 long ind = (i == N - 1) ? 0 : i + 1;
116 fsl[i] = segment_t{sl[i].tau_cdag, sl[ind].tau_c, sl[i].J_cdag, sl[ind].J_c};
124 double overlap(std::vector<segment_t>
const &seglist, segment_t
const &seg) {
125 if (seglist.empty())
return 0;
127 if (is_cyclic(seg)) {
128 auto [sl, sr] = split_cyclic_segment(seg);
129 return overlap(seglist, sl) + overlap(seglist, sr);
135 auto last = seglist.end() - 1;
136 for (
auto it = find_segment_left(seglist, seg); it != last and it->tau_c > seg.tau_cdag; ++it)
137 result += overlap(*it, seg);
141 result += overlap(*last, seg);
148 bool is_insertable_into(segment_t
const &seg, std::vector<segment_t>
const &seglist) {
149 if (seglist.empty())
return true;
152 if (is_cyclic(seg)) {
153 auto [sl, sr] = split_cyclic_segment(seg);
154 return is_insertable_into(sl, seglist) and is_insertable_into(sr, seglist);
165 auto R = std::upper_bound(seglist.begin(), seglist.end(), seg);
166 auto L = (R == seglist.begin()) ? R : R - 1;
167 if (not disjoint(seg, *L))
return false;
168 if (R != seglist.end() and not disjoint(seg, *R))
return false;
170 if (not disjoint(seg, seglist.back()))
return false;
176 std::vector<long> cdag_in_window(
tau_t const &wtau_left,
tau_t const &wtau_right,
177 std::vector<segment_t>
const &seglist) {
178 if (seglist.empty())
return {};
180 if (wtau_left < wtau_right) {
181 auto left_list = cdag_in_window(
tau_t::beta(), wtau_right, seglist);
182 auto right_list = cdag_in_window(wtau_left,
tau_t::zero(), seglist);
184 left_list.insert(left_list.end(), right_list.begin(), right_list.end());
187 std::vector<long> found_indices;
188 found_indices.reserve(seglist.size());
189 auto last = seglist.end() - 1;
190 auto it = find_segment_left(seglist, segment_t{wtau_left, wtau_left});
191 for (; it->tau_cdag > wtau_right and it != last; ++it)
192 if (it->tau_cdag < wtau_left) found_indices.push_back(std::distance(seglist.cbegin(), it));
195 if (seglist.back().tau_cdag < wtau_left and seglist.back().tau_cdag > wtau_right)
196 found_indices.push_back(seglist.size() - 1);
197 return found_indices;
204 double K_overlap(std::vector<segment_t>
const &seglist,
tau_t const &tau_c,
tau_t const &tau_cdag,
205 gf<imtime, matrix_valued>
const &K,
int c1,
int c2) {
207 auto Ks = slice_target_to_scalar(K, c1, c2);
211 for (
auto const &s : seglist) {
212 result += real(Ks(
double(tau_c - s.tau_c)) + Ks(
double(tau_cdag - s.tau_cdag)) - Ks(
double(tau_cdag - s.tau_c))
213 - Ks(
double(tau_c - s.tau_cdag)));
222 double K_overlap(std::vector<segment_t>
const &seglist,
tau_t const &tau,
bool is_c,
223 gf<imtime, matrix_valued>
const &K,
int c1,
int c2) {
224 auto Ks = slice_target_to_scalar(K, c1, c2);
228 for (
auto const &s : seglist) { result += real(Ks(
double(s.tau_c - tau)) - Ks(
double(s.tau_cdag - tau))); }
229 return is_c ? result : -result;
236 std::vector<colored_ops_t> colored_ordered_ops(std::vector<std::vector<segment_t>>
const &seglists) {
238 std::vector<colored_ops_t> ops_list;
239 for (
auto const &seglist : seglists) {
240 for (
auto const &s : seglist) {
241 ops_list.push_back({s.tau_c, c,
false});
242 ops_list.push_back({s.tau_cdag, c,
true});
250 std::sort(ops_list.begin(), ops_list.end(), [](
const colored_ops_t &a,
const colored_ops_t &b) {
251 return b.tau < a.tau;
258 std::ostream &operator<<(std::ostream &out, std::vector<segment_t>
const &sl) {
260 for (
auto const &[i, seg] : itertools::enumerate(sl))
261 out <<
". Position " << i <<
" : [ J:" << seg.J_c <<
" " << seg.tau_c <<
", " << seg.tau_cdag
262 <<
" J:" << seg.J_cdag <<
"]\n";
268 std::ostream &operator<<(std::ostream &out, configuration_t
const &config) {
269 for (
auto const &[c, sl] : itertools::enumerate(config.seglists)) {
271 for (
auto const &[i, seg] : itertools::enumerate(sl))
272 out <<
"Color " << c <<
". Position " << i <<
" : [ J:" << seg.J_c <<
" " << seg.tau_c <<
", " << seg.tau_cdag
273 <<
" J:" << seg.J_cdag <<
"]\n";
275 out <<
"\nSpin lines : \n";
276 for (
auto const &[i, line] : itertools::enumerate(config.Jperp_list)) {
277 out <<
"S_minus : [" << line.tau_Sminus <<
"] S_plus : [" << line.tau_Splus <<
"]\n";
284 std::ostream &operator<<(std::ostream &out, std::vector<colored_ops_t>
const &col) {
285 for (
auto const &[i, co] : itertools::enumerate(col))
287 <<
"i: " << i <<
", tau: " << co.tau <<
", color: " << co.color <<
", " << (co.is_cdag ?
"cdag" :
"c");
static tau_t beta()
tau_t at tau = beta
static tau_t zero()
$\tau = 0$