Ejemplo n.º 1
0
void IsingModel2d::mcstep_dry( const unsigned int& k_max )
{
  for ( unsigned int k = 0; k < k_max; k++ ) {
    mcstep();
  }
  time -= k_max;

  if ( fsize_correction_mode == 2 ) {
    // try do determine if the system is in the ordered phase
    unsigned int msmall_count = 0, mlarge_count = 0;
    for ( unsigned int k = 0; k < k_max; k++ ) {
      mcstep();
      if ( abs( M() ) < N / 2 ) {
        msmall_count++;
      } else {
        mlarge_count++;
      }
    }
    if ( mlarge_count > msmall_count ) {
      fsize_ordered_phase = true;
      cout << "assuming ordered phase @ T = " << T << endl;
    } else {
      cout << "assuming disordered phase @ T = " << T << endl;
    }
    time -= k_max;
  }
}
Ejemplo n.º 2
0
int main(int argc, char **argv)
{
		double T=0;;
		double mag=0.0;
		int N;
		int i;
		Ising **S;
		double tot_Erg=0;
		double capacity=0.0;
		double kai=0.0; 

		init_rnd(gus());

		N=atoi(argv[1]);
		S=(Ising **)malloc(sizeof(Ising *) * N);
		for(i=0; i<N; i++)
				S[i]=(Ising *)malloc(sizeof(Ising) * N);

		initialize(N, S);

		for(T=3.01; T>=0.01; T-=0.01)
		{
				mag=0.0;
				tot_Erg=0.0;
				kai=0.0;
				capacity=0.0;

				for(i=0; i<200000; i++)
						mcstep(N, T, S);

				for(i=0; i<200000; i++)
				{
						mcstep(N, T, S);
						mag+=magnetization(N, S);
						tot_Erg+=energy(N, S);
						kai+=pow(magnetization(N, S), 2);
						capacity+=pow(energy(N,S), 2);
				}
				mag=mag/200000;
				tot_Erg=tot_Erg/200000;
				kai=kai/200000;
				capacity=capacity/200000;

				kai=(kai-mag*mag)/T;
				capacity=(capacity - tot_Erg*tot_Erg)/(T*T);

				kai=kai*N*N;
				capacity=capacity*N*N;

				printf("%lf\t%lf\t%lf\t%lf\t%lf\n", T, mag, tot_Erg, kai, capacity);
		}

		free(S);

		return 0;

}
Ejemplo n.º 3
0
    void mcsrch(int size,
                double *x,
                double f, const double *g, double *s,
                double *stp,
                int *info, int *nfev, double *wa, bool orthant, double C) {
      static const double p5 = 0.5;
      static const double p66 = 0.66;
      static const double xtrapf = 4.0;
      static const int maxfev = 20;

      /* Parameter adjustments */
      --wa;
      --s;
      --g;
      --x;

      if (*info == -1) goto L45;
      infoc = 1;

      if (size <= 0 || *stp <= 0.0) return;

      dginit = ddot_(size, &g[1], &s[1]);
      if (dginit >= 0.0) return;

      brackt = false;
      stage1 = true;
      *nfev = 0;
      finit = f;
      dgtest = ftol * dginit;
      width = lb3_1_stpmax - lb3_1_stpmin;
      width1 = width / p5;
      for (int j = 1; j <= size; ++j) {
        wa[j] = x[j];
      }

      stx = 0.0;
      fx = finit;
      dgx = dginit;
      sty = 0.0;
      fy = finit;
      dgy = dginit;

      while (true) {
        if (brackt) {
          stmin = min(stx, sty);
          stmax = max(stx, sty);
        } else {
          stmin = stx;
          stmax = *stp + xtrapf * (*stp - stx);
        }

        *stp = max(*stp, lb3_1_stpmin);
        *stp = min(*stp, lb3_1_stpmax);

        if ((brackt && ((*stp <= stmin || *stp >= stmax) ||
                        *nfev >= maxfev - 1 || infoc == 0)) ||
            (brackt && (stmax - stmin <= xtol * stmax))) {
          *stp = stx;
        }

        if (orthant) {
          for (int j = 1; j <= size; ++j) {
            double grad_neg = 0.0;
            double grad_pos = 0.0;
            double grad = 0.0;
            if (wa[j] == 0.0) {
              grad_neg = g[j] - 1.0 / C;
              grad_pos = g[j] + 1.0 / C;
            } else {
              grad_pos = grad_neg = g[j] + 1.0 * sigma(wa[j]) / C;
            }
            if (grad_neg > 0.0) {
              grad = grad_neg;
            } else if (grad_pos < 0.0) {
              grad = grad_pos;
            } else {
              grad = 0.0;
            }
            const double p = pi(s[j], -grad);
            const double xi = wa[j] == 0.0 ? sigma(-grad) : sigma(wa[j]);
            x[j] = pi(wa[j] + *stp * p, xi);
          }
        } else {
          for (int j = 1; j <= size; ++j) {
            x[j] = wa[j] + *stp * s[j];
          }
        }
        *info = -1;
        return;

      L45:
        *info = 0;
        ++(*nfev);
        double dg = ddot_(size, &g[1], &s[1]);
        double ftest1 = finit + *stp * dgtest;

        if (brackt && ((*stp <= stmin || *stp >= stmax) || infoc == 0)) {
          *info = 6;
        }
        if (*stp == lb3_1_stpmax && f <= ftest1 && dg <= dgtest) {
          *info = 5;
        }
        if (*stp == lb3_1_stpmin && (f > ftest1 || dg >= dgtest)) {
          *info = 4;
        }
        if (*nfev >= maxfev) {
          *info = 3;
        }
        if (brackt && stmax - stmin <= xtol * stmax) {
          *info = 2;
        }
        if (f <= ftest1 && std::abs(dg) <= lb3_1_gtol * (-dginit)) {
          *info = 1;
        }

        if (*info != 0) {
          return;
        }

        if (stage1 && f <= ftest1 && dg >= min(ftol, lb3_1_gtol) * dginit) {
          stage1 = false;
        }

        if (stage1 && f <= fx && f > ftest1) {
          double fm = f - *stp * dgtest;
          double fxm = fx - stx * dgtest;
          double fym = fy - sty * dgtest;
          double dgm = dg - dgtest;
          double dgxm = dgx - dgtest;
          double dgym = dgy - dgtest;
          mcstep(&stx, &fxm, &dgxm, &sty, &fym, &dgym, stp, fm, dgm, &brackt,
                 stmin, stmax, &infoc);
          fx = fxm + stx * dgtest;
          fy = fym + sty * dgtest;
          dgx = dgxm + dgtest;
          dgy = dgym + dgtest;
        } else {
          mcstep(&stx, &fx, &dgx, &sty, &fy, &dgy, stp, f, dg, &brackt,
                 stmin, stmax, &infoc);
        }

        if (brackt) {
          double d1 = 0.0;
          if ((d1 = sty - stx, std::abs(d1)) >= p66 * width1) {
            *stp = stx + p5 * (sty - stx);
          }
          width1 = width;
          width = (d1 = sty - stx, std::abs(d1));
        }
      }

      return;
    }
Ejemplo n.º 4
0
    std::tuple<ook::message, T, T, T>
    operator()(F phi, T finit, T dginit, T stp, const Options& opts) const
    {
        const T ftol = opts.ftol;
        const T xtol = std::numeric_limits<T>::epsilon();
        const T p5 = .5;
        const T p66 = .66;
        const T xtrapf = 4.;

        const T stpmin = 1e-20;
        const T stpmax = 1e20;

        int infoc = 1;
        int nfev = 0;
        bool brackt = false;
        bool stage1 = true;
        const T dgtest = ftol * dginit;
        T width = stpmax - stpmin;
        T width1 = width / p5;

        // The values stx, fx, dgx are step, function and derivative at the best
        // step.
        // The values sty, fy, dgy are the step, function and derivative at the
        // other endpoint of the interval of uncertainty.
        // The values stp, f, dg are the step, function and derivative at the
        // current step.
        T stx = 0.0;
        T fx = finit;
        T dgx = dginit;
        T sty = 0.0;
        T fy = finit;
        T dgy = dginit;

        while (true)
        {
            T stmin = stx;
            T stmax = stp + xtrapf * (stp - stx);

            if (brackt)
            {
                // Set max and min step to the present interval of uncertainty.
                stmin = std::min(stx, sty);
                stmax = std::max(stx, sty);
            }

            // Clamp the step to be between maximum and minimum values.
            stp = std::max(stp, stpmin);
            stp = std::min(stp, stpmax);

            // If an unusual termination occues, set stp to be the lowest point
            // obtained so far.
            if ((brackt && (stp <= stmin || stp >= stmax)) || infoc == 0 ||
                (brackt && stmax - stmin <= xtol * stmax))
            {
                stp = stx;
            }
            // Evaluate the function and derivative.
            T f, dg;
            std::tie(f, dg) = phi(stp);
            const T ftest1 = finit + stp * dgtest;

            // Test for convergence.
            ook::message msg = ook::message::null;
            if ((brackt && (stp <= stmin || stp >= stmax)) || infoc == 0)
            {
                msg = ook::message::warning_rounding_error_prevents_progress;
            }
            if (stp == stpmax && f <= ftest1 && dg <= dgtest)
            {
                msg = ook::message::warning_stp_eq_stpmax;
            }
            if (stp == stpmin && (f > ftest1 || dg >= dgtest))
            {
                msg = ook::message::warning_stp_eq_stpmin;
            }
            if (nfev >= opts.maxfev)
            {
                msg = ook::message::warning_max_line_search_attempts_reached;
            }
            if (brackt && stmax - stmin <= xtol * stmax)
            {
                msg = ook::message::warning_xtol_satisfied;
            }
            if (f <= ftest1 && fabs(dg) <= opts.gtol * (-dginit))
            {
                msg = ook::message::convergence;
            }
            // Check for termination.
            if (msg != ook::message::null)
            {
                return std::make_tuple(msg, stp, f, dg);
            }

            // In the first state, seek a step for which the modified function
            // has
            // a non-positive value and non-negative derivative.
            if (stage1 && f <= ftest1 &&
                dg >= std::min(ftol, opts.gtol) * dginit)
            {
                stage1 = false;
            }
            // A modified function is used to predict the step only if we have
            // not
            // obtained a step for which the modified function has a
            // non-positive
            // function value and non-negative derivative, and if a lower
            // function
            // value has been obtained but the decrease is not sufficient.
            if (stage1 && f <= fx && f > ftest1)
            {
                /// Define the modified function and derivative values.
                T fm = f - stp * dgtest;
                T fxm = fx - stx * dgtest;
                T fym = fy - sty * dgtest;
                T dgm = dg - dgtest;
                T dgxm = dgx - dgtest;
                T dgym = dgy - dgtest;

                // Compute new step and update the interval of uncertainty.
                infoc = mcstep(stx,
                               fxm,
                               dgxm,
                               sty,
                               fym,
                               dgym,
                               stp,
                               fm,
                               dgm,
                               brackt,
                               stmin,
                               stmax);

                // Reset function and gradient values.
                fx = fxm + stx * dgtest;
                fy = fym + sty * dgtest;
                dgx = dgxm + dgtest;
                dgy = dgym + dgtest;
            }
            else
            {
                // Compute new step and update the interval of uncertainty.
                infoc = mcstep(stx,
                               fx,
                               dgx,
                               sty,
                               fy,
                               dgy,
                               stp,
                               f,
                               dg,
                               brackt,
                               stmin,
                               stmax);
            }
            // Force a sufficient decrease in the size od the interval of
            // uncertainty.
            if (brackt)
            {
                if (fabs(sty - stx) >= p66 * width1)
                {
                    stp = stx + p5 * (sty - stx);
                }
                width1 = width;
                width = fabs(sty - stx);
            }
        }
    }
Ejemplo n.º 5
0
void CMcsrch::mcsrch ( int n , double x[] , double f , double g[] , double s[] ,
					  int is0 , double stp[] , double ftol , double xtol , int maxfev ,
					  int info[] , int nfev[] , double wa[] )
{
	p5 = 0.5;
	p66 = 0.66;
	xtrapf = 4;

	if ( info[0] != - 1 )
	{
		infoc[0] = 1;
		if ( n <= 0 || stp[0] <= 0 || ftol < 0 || CLBFGSCPP::gtol < 0 || xtol < 0 || CLBFGSCPP::stpmin < 0 || CLBFGSCPP::stpmax < CLBFGSCPP::stpmin || maxfev <= 0 ) 
			return;


		// Compute the initial gradient in the search direction
		// and check that s is a descent direction.
		dginit = 0;

		for ( j = 1 ; j <= n ; j += 1 ) {
			dginit = dginit + g [ j -1] * s [ is0+j -1];
		}


		if ( dginit >= 0 ) {
			
			return;
		}

		brackt[0] = false;
		stage1 = true;
		nfev[0] = 0;
		finit = f;
		dgtest = ftol*dginit;
		width = CLBFGSCPP::stpmax - CLBFGSCPP::stpmin;
		width1 = width/p5;

		for ( j = 1 ; j <= n ; j += 1 ) {
			wa [ j -1] = x [ j -1];
		}

		// The variables stx, fx, dgx contain the values of the step,
		// function, and directional derivative at the best step.
		// The variables sty, fy, dgy contain the value of the step,
		// function, and derivative at the other endpoint of
		// the interval of uncertainty.
		// The variables stp, f, dg contain the values of the step,
		// function, and derivative at the current step.

		stx[0] = 0;
		fx[0] = finit;
		dgx[0] = dginit;
		sty[0] = 0;
		fy[0] = finit;
		dgy[0] = dginit;
	}

	
	while ( true )
	{
		if ( info[0] != -1 )
		{
			// Set the minimum and maximum steps to correspond
			// to the present interval of uncertainty.

			if ( brackt[0] ) {
				stmin = min ( stx[0] , sty[0] );
				stmax = max ( stx[0] , sty[0] );
			} else {
				stmin = stx[0];
				stmax = stp[0] + xtrapf * ( stp[0] - stx[0] );
			}

			// Force the step to be within the bounds stpmax and stpmin.

			stp[0] = max ( stp[0] , CLBFGSCPP::stpmin );
			stp[0] = min ( stp[0] , CLBFGSCPP::stpmax );

			// If an unusual termination is to occur then let
			// stp be the lowest point obtained so far.

			if ( ( brackt[0] && ( stp[0] <= stmin || stp[0] >= stmax ) ) || nfev[0] >= maxfev - 1 || infoc[0] == 0 || ( brackt[0] && stmax - stmin <= xtol * stmax ) ) stp[0] = stx[0];

			// Evaluate the function and gradient at stp
			// and compute the directional derivative.
			// We return to main program to obtain F and G.

			for ( j = 1 ; j <= n ; j += 1 ) {
				x [ j -1] = wa [ j -1] + stp[0] * s [ is0+j -1];
			}

			info[0]=-1;
			return;
		}

		info[0]=0;
		nfev[0] = nfev[0] + 1;
		dg = 0;

		for ( j = 1 ; j <= n ; j += 1 ) {
			dg = dg + g [ j -1] * s [ is0+j -1];
		}

		ftest1 = finit + stp[0]*dgtest;

		// Test for convergence.

		if ( ( brackt[0] && ( stp[0] <= stmin || stp[0] >= stmax ) ) || infoc[0] == 0 ) 
			info[0] = 6;

		//stp[0] == CLBFGSCPP::stpmax
		if ( fabs(stp[0] - CLBFGSCPP::stpmax)<1e-55 && f <= ftest1 && dg <= dgtest ) 
			info[0] = 5;

		//stp[0] == CLBFGSCPP::stpmin
		if ( fabs(stp[0] - CLBFGSCPP::stpmin)<1e-55 && ( f > ftest1 || dg >= dgtest ) ) 
			info[0] = 4;

		if ( nfev[0] >= maxfev ) 
			info[0] = 3;

		if ( brackt[0] && stmax - stmin <= xtol * stmax ) 
			info[0] = 2;

		if ( f <= ftest1 && fabs ( dg ) <= CLBFGSCPP::gtol * ( - dginit ) ) 
			info[0] = 1;

		// Check for termination.

		if ( info[0] != 0 ) return;

		// In the first stage we seek a step for which the modified
		// function has a nonpositive value and nonnegative derivative.

		if ( stage1 && f <= ftest1 && dg >= min ( ftol , CLBFGSCPP::gtol ) * dginit ) 
			stage1 = false;

		// A modified function is used to predict the step only if
		// we have not obtained a step for which the modified
		// function has a nonpositive function value and nonnegative
		// derivative, and if a lower function value has been
		// obtained but the decrease is not sufficient.

		//wprintf(L">>L-BFGS.mscrch (Step Search): %d\n", ++nIter);
		if ( stage1 && f <= fx[0] && f > ftest1 )
		{
			// Define the modified function and derivative values.

			fm = f - stp[0]*dgtest;
			fxm[0] = fx[0] - stx[0]*dgtest;
			fym[0] = fy[0] - sty[0]*dgtest;
			dgm = dg - dgtest;
			dgxm[0] = dgx[0] - dgtest;
			dgym[0] = dgy[0] - dgtest;

			// Call cstep to update the interval of uncertainty
			// and to compute the new step.

			mcstep ( stx , fxm , dgxm , sty , fym , dgym , stp , fm , dgm , brackt , stmin , stmax , infoc );

			// Reset the function and gradient values for f.

			fx[0] = fxm[0] + stx[0]*dgtest;
			fy[0] = fym[0] + sty[0]*dgtest;
			dgx[0] = dgxm[0] + dgtest;
			dgy[0] = dgym[0] + dgtest;
		} else {
			// Call mcstep to update the interval of uncertainty
			// and to compute the new step.

			mcstep ( stx , fx , dgx , sty , fy , dgy , stp , f , dg , brackt , stmin , stmax , infoc );
		}

		// Force a sufficient decrease in the size of the
		// interval of uncertainty.

		if ( brackt[0] )
		{
			if ( fabs ( sty[0] - stx[0] ) >= p66 * width1 ) 
				stp[0] = stx[0] + p5 * ( sty[0] - stx[0] );
			width1 = width;
			width = fabs( sty[0] - stx[0] );
		}
	}
}