Source code for SU2xSU2.calibrate_paras

import numpy as np
from .SU2xSU2 import SU2xSU2


[docs]def calibrate(model_paras, accel=False, sim_paras=None): ''' For a model, specified by the dictionary ``model_paras``, this function calibrates the number of leapfrog integration steps and their size under the constraint that the trajectory length is 1 and that the acceptance rate is with in desireable range between 60 and 75%. The calibration is done by performing short simulation runs (500 trajectories with 50% burn in unless overridden by passing ``sim_paras``), extracting the acceptance rate and, if the acceptance rate is outside this range, adjusting the number of steps according to the difference to the ideal acceptance rate of 65% for the next run. The number of steps is inferred from constraining the trajectory length to unity. It is not guaranteed that the calibration is successful for all possible model specification given the fixed trajectory length. Hence the calibration is limited to 10 iterations. An indicator that longer trajectories are required is when the calibration algorithm tries to reduce the number of steps below one. Recommended to use the returned calibrated ``model_paras`` to define the model for the production run. Parameters ---------- model_paras: dict ``{L, a, ell, eps, beta}`` denoting lattice size, lattice spacing, number of integration steps, integration step size and the SU(2)xSU(2) model parameter beta respectively The values of ell, eps are used as guesses to start the calibration and their product must be 1. accel: bool, optional use Fourier Acceleration or not sim_paras: dict, optional ``{M, thin_freq, burnin_frac, accel=True, measurements=[], chain_paths=[], saving_bool=True, partial_save=5000, starting_config=None, RGN_state=None, renorm_freq=10000}`` Specifying the simulation parameters for the calibration run by calling :py:meth:`SU2xSU2.SU2xSU2.run_HMC`. Consider the associated docstring for definitions of these parameters. Returns ------- model_paras: dict calibrated model parameters and of the same form as model_paras ''' # defining bounds for desireable acceptance rate lower_acc, upper_acc = 0.6, 0.75 if sim_paras is None: # default for fast calibration sim_paras = {'M':500, 'thin_freq':1, 'burnin_frac':0.5, 'accel':accel, 'saving_bool':False} good_acc_rate = False count = 0 stop_flag = False while good_acc_rate == False: model = SU2xSU2(**model_paras) model.run_HMC(**sim_paras) acc_rate = model.acc_rate d_acc_rate = 0.65 - acc_rate if count >= 10: good_acc_rate = True if acc_rate < lower_acc or acc_rate > upper_acc: new_ell = int(np.rint(model_paras['ell']*(1 + d_acc_rate))) # due to rounding it can happen that ell is not updated. To avoid getting stuck in a loop, enforce minimal update of +/- 1 if new_ell == model_paras['ell']: if d_acc_rate > 0: new_ell += 1 else: new_ell -= 1 if new_ell == 0: # stop calibration when step size has to be reduce below 1. stop_flag = True break model_paras['ell'] = new_ell model_paras['eps'] = 1/model_paras['ell'] count +=1 else: good_acc_rate = True stats = 'acc= %.2f%%, ell=%d, eps=%.3f'%(acc_rate*100, model_paras['ell'], model_paras['eps']) if count < 10 and not stop_flag: print('Successful calibration: '+stats) else: print('Unsuccessful calibration: '+stats) return model_paras