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; } }
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; }
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; }
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); } } }
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] ); } } }