Exemplo n.º 1
0
  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;
  }
Exemplo n.º 7
0
  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();
 }