示例#1
0
bool IASIAM::Run(IAResult* r) //output
{  
  this->r = r;
  N = r->iagrid->get_N(); 
  iagrid = r->iagrid;

  printf("    -------IASIAM: mu=%.3f, U=%.3f, T=%.3f, epsilon=%.3f -------\n", r->mu, U, T, epsilon);
   
  complex<double>* V = new complex<double>[1];
  //----- initial guess ------// 
  V[0] = r->mu0; 
  //---------------------------//

  //------ SOLVE IASIAM ---------//
  double mu0inits [] = {0.0, 1.0, -1.0, -0.8, 2.0, 1.5, -1.5,  2.5, -2.5, 
                        -2.0, 0.05, 0.8, 0.1, -0.1, 0.3, -0.3, 0.5, -0.5, -0.05, 
                        0.4, -0.4, 0.6, -0.6, 2.3, -2.3, 2.8, -2.8, 1.8, -1.8  }; 
  bool failed = !UseBroydenFormu0;  
  int c = 0;

  //printf("IASIAM: about to do mu0 search\n");

  while ( UseBroydenFormu0 and ( UseBroyden<IASIAM>(1, MAX_ITS, Accr, &IASIAM::SolveSiam, this, V) != 1 ) )
  { c++;   //printf("IASIAM: passed the first broyden use\n");
    if ( (c >= max_tries) or (c >= sizeof(mu0inits)/sizeof(double) - 1 ) )
    {
      printf("\n\n\n\n==== IASIAM ERROR ====: Broyden mu0 search failed to converge. Now switching to amoeba ...\n\n\n\n");
      failed = true;  
      break;
    }
    V[0] = mu0inits[c]; 
    
    printf("==================== ====================== ========== TRYING new mu0 int!!! c = %d, mu0init = %f\n\n\n",c, mu0inits[c]);
  };

  if ( (failed) or (abs(V[0])>5.0) ) 
  {  V[0] = mu0inits[0];  
     Amoeba(Accr, V, &IASIAM::SolveSiam); 
  }

  delete [] V;

  //----------------------------//
  r->mu0 = mu0;

  printf("        IASIAM: mu0 = %f, n = %f\n",r->mu0, r->n);

  return false;
}
示例#2
0
double AmoebaMinimizer::Minimize(double ftol)
   {
   int i, ilo, ihi, inhi, m, nvertex = point.dim + 1;
   double rtol, ysave, ytry;

   if (point.dim == 0)
      return fmin = f(point);

   // Setup the simplex, and evaluate f at each vortex
   for (i=0; i < point.dim; i++)
      {
      simplex[i] = point;
      simplex[i].Add (directions[i]);
      y[i] = f(simplex[i]);
      if (y[i] < fmin) fmin = y[i];
      }

   simplex[nvertex - 1] = point;
   y[nvertex - 1] = f(simplex[nvertex - 1]);
   if (y[nvertex - 1] < fmin) fmin = y[nvertex - 1];

   cycleCount = nvertex;

   // Calculate psum
   for (psum = simplex[0], m = 1; m < nvertex; m++)
      psum.Add(simplex[m]);

   while (true)
      {
      // First we must determine which is the highest, next
      // highest and lowest point in the simplex
      ihi = y[0] > y[1] ? (ilo = inhi = 1, 0) : (ilo = inhi = 0, 1);

      for (i = 2; i < nvertex; i++)
         {
         if (y[i] <= y[ilo])
            ilo = i;
         else if (y[i] > y[ihi])
            {
            inhi = ihi;
            ihi = i;
            }
         else if (y[i] > y[inhi])
            inhi = i;
         }

      // Compute the range from highest to lowest, return if satisfactory
      rtol = 2 * fabs(y[ihi] - y[ilo])/(fabs(y[ihi])+fabs(y[ilo])+ZEPS);
      if (rtol < ftol)
         {
         point = simplex[ilo];
         return fmin = y[ilo];
         }

      if (cycleCount > cycleMax)
         error("Amoeba.Minimize - Couldn't converge in %d cycles", cycleMax);

      // begin a new iteration...
      // first extrapolate by a factor of -1 through the face of the simplex
      // (reflection)

      cycleCount += 2;
      ytry = Amoeba(ihi, -1.0);

      if (ytry <= y[ilo])
         // Better than previous best, keep going
         Amoeba(ihi, 2.0);
      else if (ytry >= y[inhi])
         {
         // still worse than next highest point, so do a one-
         // dimensional contraction to find an intermediate
         // lower point
         ysave = y[ihi];
         ytry = Amoeba(ihi, 0.5);
         if (ytry >= ysave)
            {
            // Can't get rid of that high point
            // Better to contract around lowest point
            for (i = 0; i < nvertex; i++)
               if (i != ilo)
                  {
                  simplex[i].Add(simplex[ilo]);
                  simplex[i].Multiply(0.5);
                  y[i] = f(simplex[i]);
                  }

            cycleCount += point.dim;     // keep track of function evaluations

            for (psum = simplex[0], m = 1; m < nvertex; m++)
               psum.Add(simplex[m]);
            }
         }
      else
         cycleCount --;
      }
   }
示例#3
0
double SAMinimizer::MinimizeLoop(double )
   {
   int i, ihi, ilo, m, nvertex = point.dim + 1;
   double ylo, ynhi, ysave, yt, ytry;

   // Calculate psum
   for (psum = simplex[0], m = 1; m < nvertex; m++)
      psum.Add(simplex[m]);

   while (true)
      {
      // Determine which point is highest (worst),
      // next highest, and lowest (best)
      //
      ilo = 0;
      ihi = 1;

      // whenever we look at a vertex it gets a
      // random 'thermal' fluctuation
      ynhi = ylo = y[0] - T * log(rand->Next());
      yhi = y[1] - T * log(rand->Next());
      if (ylo > yhi)
         {
         ihi = 1;
         ilo = 0;
         ynhi = yhi;
         yhi = ylo;
         ylo = ynhi;
         }

      for (i = 2; i < nvertex; i++)
         {
         yt = y[i] - T * log(rand->Next());
         if (yt <= ylo)
            {
            ilo = i;
            ylo = yt;
            }
         else if (yt > yhi)
            {
            ynhi = yhi;
            ihi = i;
            yhi = yt;
            }
         else if (yt > ynhi)
            ynhi = yt;
         }

      // Compute the fractional range from highest to lowest
      // and return if satisfactory
      // rtol = 2.0 * (yhi - ylo) / (fabs(yhi) + fabs(ylo));
      // if ((rtol < ftol) || (iter < 0))
      if (iter < 0)
         {
         // put best point and value in slot 1 before return
         y.Swap(0, ilo);
         simplex.SwapRows(0, ilo);
         return fmin;
         }

      // Begin a new iteration:
      // First. Extrapolate by a factor -1 through the face of the simplex
      //        across from the high point (ie. reflect from the high point)

      iter -= 2;

      ytry = Amoeba(ihi, -1.0);
      if (ytry < ylo)
         // gives a better result than the best point, so go even further
         Amoeba(ihi, 2.0);
      else if (ytry >= ynhi)
         {
         // the reflected point is worse than the second highest so
         // look for an intermediate (do a one-dimensional contration)
         ysave = yhi;
         ytry = Amoeba(ihi, 0.5);
         if (ytry >= ysave)
            {
            // Can't get rid of worst point, so contract around
            // lowest point
            for (i = 0; i < nvertex; i++)
               if ( i != ilo )
                  {
                  simplex[i].Add(simplex[ilo]);
                  simplex[i].Multiply(0.5);
                  y[i] = f(simplex[i]);

                  if (y[i] <= fmin)
                     {
                     point = simplex[i];
                     fmin = y[i];
                     }
                  }
            // Calculate psum
            for (psum = simplex[0], m = 1; m < nvertex; m++)
               psum.Add(simplex[m]);

            iter -= point.dim;
            }
         }
      else
         iter++;        // correct evaluation count
      }
   }
示例#4
0
bool IASIAM::Run_CHM(IAResult* r) //output
{  
  this->r = r;
  N = r->iagrid->get_N();
  iagrid = r->iagrid;

  epsilon = 0;
 
  printf("    ------- IASIAM for CHM: n=%.3f, U=%.3f, T=%.3f, epsilon=%.3f -------\n", r->n, U, T, epsilon);
  
  //----------------- CALCULATION ----------------------//
  if (PHSymmetricCase)
  {
    mu0 = 0.0;
    get_G0();
  }
  else
  { 
    complex<double>* V = new complex<double>[1];
    //------initial guess---------//
    V[0] = r->mu0; //initial guess is always the last mu0. in first DMFT iteration it is 0
    //---------------------------//

    printf("         IASIAM: about to calc mu0. at the moment: mu0 = %.3f mu=%.3f\n",r->mu0, r->mu);
    double initGuesses [] = {-1.0, 1.0, 0.3, -0.3, 0.1, -0.1, 
                             -0.8, 0.8, -0.6, 0.6, -0.7, 0.7,
                             -3.0, 3.0, 0.9, -0.9, 0.05, -0.05, 
                              0.5, -0.5, 0.2, -0.2, 2.0, -2.0};
    
    bool converged = false; 

    int i;
    for (i=0; ( (i<sizeof(initGuesses)/sizeof(double)) and (i<max_tries) ); i++)
    {  printf("------ IASIAM: trying with init guess: %f\n",real(V[0]));
       converged = UseBroyden<IASIAM>(1, 50, 1e-8, &IASIAM::get_G0, this, V);  
     if (converged) break;
     else V[0] = initGuesses[i];
    }
    if ((i==max_tries)and(!converged))
    {  V[0] = initGuesses[0]; 
       Amoeba(Accr, V, &IASIAM::get_G0); 
    }
    delete [] V;
  }
  r->mu0 = mu0;
  //PrintFunc("G0", N, r->G0, r->omega);
  printf("    mu0 = %f\n", mu0);
  
  fft->FtoT(r->G0, r->G0_tau);
  get_SOCSigma_tau();
  fft->TtoF(r->SOCSigma_tau, r->SOCSigma);

  if (PHSymmetricCase)
  { r->mu = 0.5*U;
    r->n=0.5;
    get_G();
  }
  else
  { 
    complex<double>* V = new complex<double>[1];
    V[0] = r->mu;

    double initGuesses [] = {-1.0, 1.0, -0.8, 0.8, -0.6, 0.6, 0.2, -0.2, 2.0, -2.0};
    
    bool converged = false; 

    int i;
    for (i=0; ( (i<sizeof(initGuesses)/sizeof(double)) and (i<max_tries) ); i++)
    {  printf("------ IASIAM: trying with init guess: %f\n",real(V[0]));
       converged = UseBroyden<IASIAM>(1, MAX_ITS, 1e-8, &IASIAM::get_G, this, V);
       if (converged){ break; }
       else V[0] = initGuesses[i];
       
    }
    if ((i==max_tries)and(!converged))
    {  V[0] = initGuesses[0]; 
       Amoeba(Accr, V, &IASIAM::get_G); 
    }
    delete [] V;
  }
  printf("    mu = %f\n", r->mu);

  //-----------------------------------------------------//

  return false;
}