mc_weight_type accept() { Config.DT.confirm_insert_and_remove_One_Operator(); det->complete_operation(); #ifdef DEBUG std::cout << "CONFIG ACCEPT: " << Config.DT << std::endl; std::cout << "ROLL MATRIX: " << roll_matrix << std::endl; for (int a = 0; a < Config.Na; ++a) print_det(Config.dets[a]); #endif Config.update_Sign(); return Config.ratioNewSign_OldSign() * det->roll_matrix(roll_matrix); }
mc_weight_type Accept() { Config.DT.confirm_insertTwoOperators(); det->accept_move(); if (Config.RecordStatisticConfigurations) { HISTO_Length_Kinks_Accepted << deltaTau; } Config.update_Sign(); return Config.ratioNewSign_OldSign(); }
mc_weight_type Accept() { Config.DT.confirm_removeTwoOperators(); det->complete_operation(); #ifdef DEBUG std::cout << "CONFIG ACCEPT: " << Config.DT << std::endl; for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif Config.update_Sign(); return Config.ratioNewSign_OldSign(); }
mc_weight_type Accept() { Config.DT.confirm_insertTwoOperators(); det->complete_operation(); if (Config.RecordStatisticConfigurations) { HISTO_Length_Kinks_Accepted << deltaTau; } #ifdef DEBUG std::cout << "CONFIG ACCEPT: " << Config.DT << std::endl; for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif Config.update_Sign(); return Config.ratioNewSign_OldSign(); }
mc_weight_type Try() { #ifdef DEBUG std::cout << "I AM IN Try for Remove_Cdag_C_Delta" << std::endl; std::cout << "CONFIG BEFORE: " << Config.DT << std::endl; //for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif // the det has to be recomputed each time, since global moves will change it det = Config.dets[a_level]; // Pick up a couple of C, Cdagger to remove at random const int Na(det->NumberOfC()); if (Na==0) return 0; int numCdag = 1 + Random(Na); int numC = 1 + Random(Na); // det is in decreasing order. numC = Na - numC + 1; numCdag = Na - numCdag + 1; // Remove the operators from the traces // the -Na +1 is to move backward, to compare with V1 ... Config.DT.removeTwoOperators(*det->select_Cdagger( numCdag ), *det->select_C( numC )); // Acceptance probability mc_weight_type p = Config.DT.ratioNewTrace_OldTrace() * det->try_remove(numCdag,numC); double Tratio = power(2*Nalpha* Config.Beta / double(2*Na) ,2); #ifdef DEBUG std::cout << "RATIO: " << Config.DT.ratioNewTrace_OldTrace() << std::endl; std::cout << "CONFIG AFTER: " << Config.DT << std::endl; //for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif return p/Tratio; }
mc_weight_type Try() { #ifdef DEBUG std::cout << "I AM IN Try for Insert_Cdag_C_Delta" << std::endl; std::cout << "CONFIG BEFORE: " << Config.DT << std::endl; // for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif // Pick up the value of alpha and choose the operators const Hloc::Operator & Op1(*Config.CdagOps[a_level][Random(Nalpha)]), & Op2(*Config.COps[a_level][Random(Nalpha)]); // Choice of times. double tau1 = Random(Config.Beta), tau2 = Random(Config.Beta); // record the length of the kinks if (Config.RecordStatisticConfigurations) { deltaTau = Config.CyclicOrientedTimeDistance(tau2 - tau1); HISTO_Length_Kinks_Proposed<< deltaTau; } // Insert the operators Op1 and Op2 Configuration::OP_REF O1, O2; tie (no_trivial_reject,O1,O2) = Config.DT.insertTwoOperators(tau1,Op1,tau2,Op2); if (!no_trivial_reject) return 0; // pick up the determinant // NB ; the det has to be recomputed each time, since global moves will change it det = Config.dets[a_level]; int numCdag=1; // Find the position for insertion in the determinant // NB : the determinant store the C in decreasing order. for (Configuration::DET_TYPE::Cdagger_iterator p= det->Cdagger_begin(); (p != det->Cdagger_end()) && (p->tau > tau1) ; ++p, ++numCdag) {} int numC=1; for (Configuration::DET_TYPE::C_iterator p= det->C_begin(); (p != det->C_end()) && (p->tau > tau2) ; ++p, ++numC) {} // acceptance probability mc_weight_type p = Config.DT.ratioNewTrace_OldTrace() * det->try_insert(numCdag,numC,O1,O2); double Tratio =power(2*Nalpha* Config.Beta / double(2*(det->NumberOfC()+1)), 2); #ifdef DEBUG std::cout << "Trace Ratio: " << Config.DT.ratioNewTrace_OldTrace() << std::endl; std::cout << "p*T: " << p*Tratio << std::endl; std::cout << "CONFIG AFTER: " << Config.DT << std::endl; //for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif return p*Tratio; }
mc_weight_type attempt() { #ifdef DEBUG std::cout << "I AM IN attempt for Move" << std::endl; std::cout << "CONFIG BEFORE: " << Config.DT << std::endl; for (int a = 0; a < Config.Na; ++a) print_det(Config.dets[a]); #endif // find an operator (anyone) to be moved. // to do this, I go over the DT trace const int L(Config.DT.Length()); if (L==0) return 0; const int N(Random(L)); // I go over the trace to find the op oldOpref // and then I get its info Configuration::OP_REF oldOpref = Config.DT.OpRef_begin(); for (int i=0; i<N; ++i, ++oldOpref) {} int a = Config.info[oldOpref->Op->Number].a; int Nalpha = Config.COps[a].size(); bool isdagger = Config.info[oldOpref->Op->Number].dagger; double oldtau = oldOpref->tau; // chose the new alpha (this is done here for compatibility) int newalpha = Random(Nalpha); int num; double tR, tL; det = Config.dets[a]; Configuration::DET_TYPE::Cdagger_iterator itCdag = det->Cdagger_begin(); Configuration::DET_TYPE::C_iterator itC = det->C_begin(); if (det->size() > 1) { // find the C and Cdag operators at the right of oldOpref (at smaller times) // it might be Cdagger_end() or C_end() // also get the number num of oldOpref in the det num = 0; while ( (itCdag != det->Cdagger_end()) && (itCdag->tau >= oldtau) ) {++itCdag; if(isdagger) ++num;} while ( (itC != det->C_end()) && (itC->tau >= oldtau) ) {++itC; if(!isdagger) ++num;} // find the times of the operator at the right of oldOpref with cyclicity // then deduce the closest one and put its distance to oldOpref in tR double tRdag = (itCdag != det->Cdagger_end() ? (*itCdag)->tau : det->Cdagger_begin()->tau); double tRnodag = (itC != det->C_end() ? (*itC)->tau : det->C_begin()->tau); tR = std::min(Config.CyclicOrientedTimeDistance(oldtau - tRdag), Config.CyclicOrientedTimeDistance(oldtau - tRnodag)); // move itCdag and itC to the operators on the left with cyclicity // find their times and deduce the closest one with distance tL if (isdagger) --itCdag; else --itC; if (itCdag != det->Cdagger_begin()) --itCdag; else itCdag = --det->Cdagger_end(); if (itC != det->C_begin()) --itC; else itC = --det->C_end(); tL = std::min(Config.CyclicOrientedTimeDistance((*itCdag)->tau - oldtau), Config.CyclicOrientedTimeDistance((*itC)->tau - oldtau)); } else { num = 1; tR = (isdagger ? Config.CyclicOrientedTimeDistance(oldtau - (*itC)->tau) : Config.CyclicOrientedTimeDistance(oldtau - (*itCdag)->tau)); tL = (isdagger ? Config.CyclicOrientedTimeDistance((*itC)->tau - oldtau) : Config.CyclicOrientedTimeDistance((*itCdag)->tau - oldtau)); } // the new operator newOp with a new chosen alpha double newtau = Config.CyclicOrientedTimeDistance(oldtau - tR + Random(tL + tR - 2*ctqmc_utils::EPSILON) + ctqmc_utils::EPSILON); const Hloc::Operator * newOp; newOp = (isdagger ? Config.CdagOps[a][newalpha] : Config.COps[a][newalpha]); // remove oldOpref and insert newOp in the Trace bool ok; Configuration::OP_REF Op; std::tie(ok,Op) = Config.DT.insert_and_remove_One_Operator(oldOpref, newtau, *newOp); if (!ok) return 0; // in the following we want to see if we need to roll the det roll_matrix = Configuration::DET_TYPE::None; // check if we went through \tau = 0 or \tau = \beta if (newtau - oldtau > tL) roll_matrix = (isdagger ? Configuration::DET_TYPE::Down : Configuration::DET_TYPE::Right); if (oldtau - newtau > tR) roll_matrix = (isdagger ? Configuration::DET_TYPE::Up : Configuration::DET_TYPE::Left); // acceptance probability mc_weight_type p = Config.DT.ratioNewTrace_OldTrace() * (isdagger ? det->try_change_row(num-1,Op) : det->try_change_col(num-1,Op)); #ifdef DEBUG std::cout << "oldtau, tR, tL, newtau: " << oldtau << " " << tR << " " << tL << " " << newtau << endl; std::cout << "Trace Ratio: " << Config.DT.ratioNewTrace_OldTrace() << std::endl; std::cout << "Det Ratio: " << p/mc_weight_type(Config.DT.ratioNewTrace_OldTrace()) << std::endl; std::cout << "Rate: " << p << std::endl; std::cout << "CONFIG AFTER: " << Config.DT << std::endl; for (int a = 0; a < Config.Na; ++a) print_det(Config.dets[a]); #endif return p; }
mc_weight_type Try() { det = Config.dets[a_level]; // NB the det pointer has to be recomputed each time, since global moves will change it #ifdef DEBUG std::cout << "I AM IN Try for Insert_Cdag_C_Delta_SegmentPicture" << std::endl; std::cout << "CONFIG BEFORE: " << Config.DT << std::endl; // for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif // Pick up a time to insert the first operator double tau1 = Random(Config.Beta); // Now find the operator A on the same a level at later time, with cyclicity // and compute the maximal *oriented* length between the 2 operators (with cyclicity) Configuration::OP_REF A; if (det->size()>0) { // non empty Configuration::DET_TYPE::Cdagger_iterator itCdag = det->Cdagger_begin(); Configuration::DET_TYPE::C_iterator itC = det->C_begin(); while ( (itCdag != det->Cdagger_end()) && (itCdag->tau > tau1) ) {++itCdag;} while ( (itC != det->C_end()) && (itC->tau > tau1) ) {++itC;} if (itCdag != det->Cdagger_begin()) --itCdag; else itCdag = --det->Cdagger_end(); if (itC != det->C_begin()) --itC; else itC = --det->C_end(); double rC = Config.CyclicOrientedTimeDistance((*itC)->tau - tau1); double rCdag = Config.CyclicOrientedTimeDistance((*itCdag)->tau - tau1); A = ( rC > rCdag ? *itCdag : * itC); try_insert_length_max = min(rC,rCdag); } else { // empty case. try_insert_length_max = Config.Beta; A = Config.DT.OpRef_end(); } // pick up the actual segment length double rr= Random(try_insert_length_max-2*EPSILON) + EPSILON; // deduce the time of the second operator double tau2 = Config.CyclicOrientedTimeDistance(tau1 + rr); // record the length of the kinks if (Config.RecordStatisticConfigurations) { deltaTau = Config.CyclicOrientedTimeDistance(tau2 - tau1); HISTO_Length_Kinks_Proposed<< abs(deltaTau); } // Choose the operators to be inserted const Hloc::Operator & OpCdag(*Config.CdagOps[a_level][0]), & OpC(*Config.COps[a_level][0]); // shall we add C^+ C or C C^+ // we look whether the next operator is a dagger bool Op1_is_dagger = true; if (!A.atEnd()) { const Configuration::BlockInfo & INFO(Config.info[A->Op->Number]); assert(INFO.isFundamental()); Op1_is_dagger = INFO.dagger; } // Insert the operators Op1 and Op2. // O1 will always be the dagger : // Cf doc of insertTwoOperators, order of output OPREF is the same as input operators Configuration::OP_REF O1, O2; tie (no_trivial_reject,O1,O2) = (Op1_is_dagger ? Config.DT.insertTwoOperators(tau1,OpCdag,tau2,OpC) : Config.DT.insertTwoOperators(tau2,OpCdag,tau1,OpC)); if (!no_trivial_reject) return 0; double tauCdag = (Op1_is_dagger ? tau1 : tau2); double tauC = (Op1_is_dagger ? tau2 : tau1); // Find the position for insertion in the determinant // NB : the determinant store the C in decreasing order. int numCdag=1; for (Configuration::DET_TYPE::Cdagger_iterator p= det->Cdagger_begin(); (p != det->Cdagger_end()) && (p->tau > tauCdag) ; ++p, ++numCdag) {} int numC=1; for (Configuration::DET_TYPE::C_iterator p= det->C_begin(); (p != det->C_end()) && (p->tau > tauC) ; ++p, ++numC) {} // acceptance probability mc_weight_type p = Config.DT.ratioNewTrace_OldTrace() * det->try_insert(numCdag-1,numC-1,O1,O2); int Na(det->size()+1); // !!! det not modified until det->complete_operation is called, so I need to compensate by +1 double Tratio = Config.Beta * try_insert_length_max / (Na ==1 ? 1 : 2*Na); // (Na... term : cf remove move... #ifdef DEBUG std::cout << "Trace Ratio: " << Config.DT.ratioNewTrace_OldTrace() << std::endl; std::cout << "p*T: " << p*Tratio << std::endl; std::cout << "CONFIG AFTER: " << Config.DT << std::endl; //for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif return p*Tratio; }
mc_weight_type Try() { #ifdef DEBUG std::cout << "I AM IN Try for Remove_Cdag_C_Delta_SegmentPicture" << std::endl; std::cout << "CONFIG BEFORE: " << Config.DT << std::endl; for (int a = 0; a<Config.Na; ++a) print_det(Config.dets[a]); #endif // the det pointer has to be recomputed each time, since global moves will change it det = Config.dets[a_level]; // Pick up a couple of C, Cdagger to remove at random const int Na(det->size()); if (Na==0) return 0; // I am selecting the n th C or Cdag operator, starting from small time. // Because the det orders the tau in decreasing order (cf insert) // I need to iterate over the C, Cdag in reverse. int n = Random(2*Na); // pick up n // the Cs will look like 0 : c1 c2 c1 c2 c1 c2 c1 c2 : beta // where c1, c2 are C,Cdag or Cdag,C // from n, I now compute the number of the c1,c2 operator (between 0 and N-1) // if n = 2p, n1 = p , n2 = p // if n = 2p+1, n1 = p +1 , n2 = p // e.g. c1[0] c2[0] c1[1] c2[1] c1[2] c2[2] c1[3] c2[3] // n= 0 1 2 3 4 5 6 7 //eg n=2,p=1 { } //eg n=3,p=1 { } //eg n=7,p=3 } { // be careful of the cyclic condition int n1 = 1+ (n+1)/2, n2 = 1 + n/2; const bool use_cyclicity (n1 > Na); if (use_cyclicity) n1 = 1; // cyclic condition // decide whether C1 is C or Cdag bool Cisfirst = (det->Cdagger_rbegin()->tau > det->C_rbegin()->tau ); int numC = (Cisfirst ? n1: n2); int numCdag = (Cisfirst ? n2: n1); #ifdef DEBUG cout<<" Cfirst n n1 n2 "<< Cisfirst<< " "<<n<< " "<< n1 << " "<< n2 <<endl; cout<<numC<< " "<<numCdag <<endl; #endif // take an iterator on the couple C,Cdag Configuration::DET_TYPE::Cdagger_reverse_iterator itCdag = det->select_reverse_Cdagger( numCdag ); Configuration::DET_TYPE::C_reverse_iterator itC = det->select_reverse_C( numC ); // Remove the operators from the traces Config.DT.removeTwoOperators(*itCdag,*itC); // first_point is the first of the couple, next_point is the op on a_level *after* the second // with cyclicity // if cyclicity was not used, the first point is simply the lowest tau // otherwise it is the *highest* tau ! Configuration::OP_REF first_point, next_point; const bool C_before_Cdag(((*itC)->tau < (*itCdag)->tau)); if ((!use_cyclicity && C_before_Cdag) || (use_cyclicity && !C_before_Cdag)) { first_point = *itC; ++itC; next_point = (itC == det->C_rend() ? *det->C_rbegin() : *itC); // cyclicity check } else { first_point = *itCdag; ++itCdag; next_point = (itCdag == det->Cdagger_rend() ? *det->Cdagger_rbegin() : *itCdag); // cyclicity check } double length_max = ( first_point == next_point ? Config.Beta : Config.CyclicOrientedTimeDistance(next_point->tau- first_point->tau) ); // Acceptance probability mc_weight_type p = Config.DT.ratioNewTrace_OldTrace() * det->try_remove(Na-numCdag, Na-numC); double Tratio = (Na ==1 ? 1 : 2*Na) / (Config.Beta * length_max); // (Na term : because if we have only 1 couple of C Cdagger, n = 0 and 1 will lead to the same couple // and this is the only case like this. #ifdef DEBUG cout<< " length_max "<<length_max<<endl; std::cout << "RATIO: " << Config.DT.ratioNewTrace_OldTrace() << std::endl; std::cout << "CONFIG AFTER: " << Config.DT << std::endl; #endif return p*Tratio; }
mc_weight_type Accept() { Config.DT.confirm_removeTwoOperators(); det->accept_move(); Config.update_Sign(); return Config.ratioNewSign_OldSign(); }