/* * This part is the heart of merge sort algorithm it divides given array to three.*/ void trigger(int *A, int r, int t){ int q; if(t > r + 1){ q = (t + r) / 3; trigger(A, q, t -1); trigger(A, r, q + 1); trigger(A, q+r, t-1);//(q+1) di singularity(A, q, t); } }
block_gf<imtime> atomic_gf(atom_diag const& atom, double beta, std::map<std::string, indices_t> const& gf_struct, int n_tau, std::vector<std::pair<int, int>> const& excluded_states) { double z = partition_function(atom, beta); std::vector<std::string> block_names; std::vector<gf<imtime>> gf_blocks; auto const & fops = atom.get_fops(); auto is_excluded = [&excluded_states](int A, int ia) { return std::find(excluded_states.begin(), excluded_states.end(), std::make_pair(A, ia)) != excluded_states.end(); }; for (auto const& block : gf_struct) { block_names.push_back(block.first); int bl_size = block.second.size(); auto g = gf<imtime>{{beta, Fermion, n_tau}, {bl_size, bl_size}}; for (int inner_index1 = 0; inner_index1 < bl_size; ++inner_index1) for (int inner_index2 = 0; inner_index2 < bl_size; ++inner_index2) { int n1 = fops[{block.first, block.second[inner_index1]}]; // linear_index of c int n2 = fops[{block.first, block.second[inner_index2]}]; // linear_index of c_dag for (int A = 0; A < atom.n_blocks(); ++A) { // index of the A block. sum over all int B = atom.cdag_connection(n2, A); // index of the block connected to A by operator c_n if (B == -1) continue; // no matrix element if (atom.c_connection(n1, B) != A) continue; // for (int ia = 0; ia < atom.get_block_dim(A); ++ia) for (int ib = 0; ib < atom.get_block_dim(B); ++ib) { auto Ea = atom.get_eigenvalue(A, ia); auto Eb = atom.get_eigenvalue(B, ib); if (is_excluded(A, ia) || is_excluded(B, ib)) continue; for (auto tau : g.mesh()) g[tau](inner_index1, inner_index2) += -atom.cdag_matrix(n2, A)(ib, ia) * atom.c_matrix(n1, B)(ia, ib) * std::exp(-(Eb - Ea) * tau - beta * Ea) / z; } } } g.singularity()(1) = 1.0; gf_blocks.push_back(std::move(g)); } return make_block_gf(block_names, gf_blocks); }