diff --git a/.gitignore b/.gitignore index 3ed2d47d1..4a9a3bfbc 100644 --- a/.gitignore +++ b/.gitignore @@ -18,5 +18,6 @@ tags hmc_tm invert offline_measurement +measure lib/ benchmark diff --git a/DDalphaAMG_interface.c b/DDalphaAMG_interface.c index 4b24928fc..c677b0b1a 100644 --- a/DDalphaAMG_interface.c +++ b/DDalphaAMG_interface.c @@ -533,6 +533,25 @@ void MG_update_mu(double mu_tmLQCD, double odd_tmLQCD) } } +/* + * This extra interface has been required for the reweighting measurements. + * The update of the parameters was not taken into account properly. + */ +void MG_update_kappa(double kappa) +{ + if(mg_initialized!=1){ + return; + } + DDalphaAMG_get_parameters(&mg_params); + if (kappa!= mg_params.kappa) { + if (g_proc_id == 0) { + printf("MG WARNING: setting kappa from %.14f to %.14f general kappa %.14f\n",mg_params.kappa,kappa,g_kappa); + } + mg_params.kappa=kappa; + DDalphaAMG_update_parameters(&mg_params, &mg_status); + } +} + void MG_reset() { if(mg_do_setup == 0) diff --git a/DDalphaAMG_interface.h b/DDalphaAMG_interface.h index 144e96b4c..9b717f87e 100644 --- a/DDalphaAMG_interface.h +++ b/DDalphaAMG_interface.h @@ -44,6 +44,7 @@ extern double mg_rho_update; void MG_init(void); void MG_update_gauge(double step); void MG_update_mu(double mu_tmLQCD, double odd_tmLQCD); +void MG_update_kappa(double kappa); void MG_reset(void); void MG_finalize(void); diff --git a/Makefile.in b/Makefile.in index fe98465e4..7a16f3ccf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -124,7 +124,7 @@ ${addsuffix .o, ${SMODULES}}: %.o: ${srcdir}/%.c %.d Makefile $(abs_top_builddir # C++ modules $(addsuffix .o,${CXXMODULES}): %.o: ${srcdir}/%.cpp %.d Makefile $(abs_top_builddir)/config.h ${CXXCOMPILE} -c $< - + ${addsuffix .o, ${PROGRAMS}}: %.o: ${srcdir}/%.c %.d Makefile $(abs_top_builddir)/config.h ${top_srcdir}/git_hash.h ${COMPILE} ${OPTARGS} -c $< diff --git a/meas/Makefile.in b/meas/Makefile.in index 3b2ccaccb..521e257ee 100644 --- a/meas/Makefile.in +++ b/meas/Makefile.in @@ -34,6 +34,7 @@ LIBRARIES = libmeas libmeas_TARGETS = measurements \ oriented_plaquettes \ correlators \ + reweightingmeas \ pion_norm \ polyakov_loop \ measure_clover_field_strength_observables \ diff --git a/meas/measurements.c b/meas/measurements.c index 338ea7fea..86c0e86b4 100644 --- a/meas/measurements.c +++ b/meas/measurements.c @@ -2,6 +2,7 @@ * * Copyright (C) 2008 Carsten Urbach * 2009 Florian Burger + * 2016 Georg Bergner * * This file is part of tmLQCD. * @@ -35,8 +36,10 @@ #include "polyakov_loop.h" #include "oriented_plaquettes.h" #include "gradient_flow.h" +#include "reweightingmeas.h" #include "measurements.h" + measurement measurement_list[max_no_measurements]; int no_measurements = 0; @@ -49,6 +52,8 @@ int add_measurement(const enum MEAS_TYPE meas_type) { measurement_list[no_measurements].measurefunc = &dummy_meas; measurement_list[no_measurements].type = meas_type; measurement_list[no_measurements].initialised = 1; + measurement_list[no_measurements].parameter=(void *)NULL; + measurement_list[no_measurements].destructor = &default_destructor; no_measurements++; return(no_measurements); } @@ -80,6 +85,12 @@ int init_measurements(){ measurement_list[i].measurefunc = &gradient_flow_measurement; } + if(measurement_list[i].type == REWEIGHTING) { + measurement_list[i].measurefunc = &reweighting_measurement; + initialize_reweighting_parameter(&measurement_list[i].parameter); + measurement_list[i].destructor = &free_reweighting_parameter; + } + measurement_list[i].id = i; } return(0); @@ -88,7 +99,14 @@ return(0); void free_measurements(){ - + int i; + for(i = 0; i < no_measurements; i++) { + if (measurement_list[i].parameter) { + measurement_list[i].destructor(measurement_list[i].parameter); + free(measurement_list[i].parameter); + measurement_list[i].parameter = NULL; + } + } return; } @@ -102,5 +120,10 @@ void dummy_meas(const int traj, const int id, const int ieo) { } +void default_destructor(void* ptr) { + +} + + diff --git a/meas/measurements.h b/meas/measurements.h index 73e695a17..7a036a6e8 100644 --- a/meas/measurements.h +++ b/meas/measurements.h @@ -4,6 +4,8 @@ * * Adapted from monomial.h by Florian Burger 2009/12/16 * + * More flexible handling of measurements parameters by Georg Bergner 2016 + * * This file is part of tmLQCD. * * tmLQCD is free software: you can redistribute it and/or modify @@ -18,6 +20,9 @@ * * You should have received a copy of the GNU General Public License * along with tmLQCD. If not, see . + * + * + * ***********************************************************************/ #ifndef _MEASUREMENTS_H #define _MEASUREMENTS_H @@ -25,29 +30,31 @@ #define max_no_measurements 20 /* Give the measurement types an unambiguous ID*/ -enum MEAS_TYPE { - ONLINE, - PIONNORM, - POLYAKOV, - ORIENTED_PLAQUETTES, - GRADIENT_FLOW - }; - -typedef struct { +enum MEAS_TYPE +{ + ONLINE, PIONNORM, POLYAKOV, ORIENTED_PLAQUETTES, GRADIENT_FLOW, REWEIGHTING +}; + +typedef struct +{ enum MEAS_TYPE type; int initialised; int id; - - /* frequency of the measurement */ - int freq; - /* for maximal iterations in inversions for correlators */ - int max_iter; + /* for polyakov loop */ int direction; + /* for maximal iterations in inversions for correlators */ + int max_iter; + // random seed unsigned int seed; + void* parameter; + + /* frequency of the measurement */ + int freq; + /* how it's usually called */ char name[100]; @@ -67,21 +74,29 @@ typedef struct { double gf_tmax; /* functions for the measurement */ - void (*measurefunc) (const int traj, const int id, const int ieo); + void + (*measurefunc) (const int traj, const int id, const int ieo); + void + (*destructor) (void* param); } measurement; - /* list of all monomials */ extern measurement measurement_list[max_no_measurements]; extern int no_measurements; /* add a new measurement to the list of measurements */ -int add_measurement(const enum MEAS_TYPE); +int +add_measurement (const enum MEAS_TYPE); /* initialise all measurements in the list */ -int init_measurements(); +int +init_measurements (); /* free space again */ -void free_measurements(); +void +free_measurements (); -void dummy_meas(const int traj, const int id, const int ieo); +void +dummy_meas (const int traj, const int id, const int ieo); +void +default_destructor (void* ptr); #endif diff --git a/meas/reweightingmeas.c b/meas/reweightingmeas.c new file mode 100644 index 000000000..7b1f47e54 --- /dev/null +++ b/meas/reweightingmeas.c @@ -0,0 +1,1156 @@ +/*********************************************************************** + * + * Measurements of the reweighting factors by Georg Bergner 2016 + * + * Copyright (C) 2016 Georg Bergner + * + * This file is part of tmLQCD. + * + * tmLQCD is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * tmLQCD is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with tmLQCD. If not, see . + ***********************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include +#include +#include "global.h" +#include "start.h" +#include "ranlxs.h" +#include "su3spinor.h" +#include "source_generation.h" +#include "operator.h" +#include "invert_eo.h" +#include "solver/solver.h" +#include "geometry_eo.h" +#include "measurements.h" +#include "correlators.h" +#include "gettime.h" +#include "linalg_eo.h" +#include "linalg/mul_diff_mul_r.h" +#include "../operator/Hopping_Matrix.h" +#include "../operator/tm_operators.h" +#include "../operator/clovertm_operators.h" +#include "../operator/tm_operators_32.h" +#include "../operator/clovertm_operators_32.h" +#include "../operator/clover_leaf.h" +#include "../read_input.h" +#include "reweightingmeas.h" +#include "../operator.h" +#include "../DDalphaAMG_interface.h" +#include "../boundary.h" +#include "../global.h" +#include "../init/init_spinor_field.h" +#include "solver/jdher.h" + +#include +#ifdef _USE_SHMEM +# include +#endif + + +/* + * This struct provides an array of spinor fields. + * This is easier to handle than the pointer of pointer of pointers used in other parts of the code. + */ +typedef struct { + spinor* buffer; + spinor** ar; + unsigned int length; +} spinor_array; + +/* + * Allocation of the spinor field redirects to allocate_spinor_field_array. + */ +static int alloc_spinor_field(spinor_array* ar, int evenodd) { + unsigned long int volume = VOLUMEPLUSRAND / 2; + if (evenodd == 0) { + volume = VOLUMEPLUSRAND; + } + return (allocate_spinor_field_array(&ar->ar,&ar->buffer,volume, ar->length)); +} + +static void free_spinor_field_spinor_array(spinor_array* ar) { + if (ar->buffer != NULL) { + free_spinor_field_array(&ar->buffer); + } + if (ar->ar != NULL) { + free(ar->ar); + } + ar->ar = NULL; + ar->buffer = NULL; + ar->length = 0; +} + +/* + * The generic inverter requires different functions depending on + * preconditioned or unpreconditioned matrix. + */ +static int is_schur_complement(const matrix_mult f) { + if (f == Msw_psi || // Schur complement with mu=0 on odd sites + f == Qsw_psi || // Gamma5 - Schur complement with mu=0 on odd sites + f == Mtm_plus_psi || // Schur complement with plus mu + f == Msw_plus_psi || // Schur complement with plus mu + f == Qtm_plus_psi || // Gamma5 - Schur complement with plus mu + f == Qsw_plus_psi || // Gamma5 - Schur complement with plus mu + f == Mtm_minus_psi || // Schur complement with minus mu + f == Msw_minus_psi || // Schur complement with minus mu + f == Qtm_minus_psi || // Gamma5 - Schur complement with minus mu + f == Qsw_minus_psi || // Gamma5 - Schur complement with minus mu + f == Qtm_pm_psi || // Schur complement squared + f == Qsw_pm_psi) { // Schur complement squared + return 1; + } + return 0; +} + +/* + * This is the part of the reweighting that comes from the csw term. + */ +static double get_sw_reweighting(const double mu1, const double mu2, + const double kappa1, const double kappa2, const double csw1, + const double csw2) { + double ret; + sw_term((const su3**) g_gauge_field, kappa1, csw1); + ret = -sw_trace(0, mu1); + if (kappa1 != kappa2 || csw1 != csw2) { + sw_term((const su3**) g_gauge_field, kappa2, csw2); + } + ret += sw_trace(0, mu2); + return (ret); +} + +static int is_sym_pos_definite(const matrix_mult f) { + if (f == Qtm_pm_psi || // Schur complement squared + f == Qsw_pm_psi || f == Q_pm_psi) { // Full operator squared + return 1; + } + return 0; +} + +/* + * Change of parameters requires in some cases update of the csw part. + */ +static void update_global_parameters(const int op_id) { + operator * optr = &operator_list[op_id]; + g_kappa = optr->kappa; + boundary(g_kappa); + g_mu = optr->mu; + g_c_sw = optr->c_sw; + if (optr->type == CLOVER) { + if (g_cart_id == 0 && g_debug_level > 1) { + printf("#\n# csw = %e, computing clover leafs\n", g_c_sw); + } + init_sw_fields(VOLUME); + + sw_term((const su3**) g_gauge_field, optr->kappa, optr->c_sw); + /* this must be EE here! */ + /* to match clover_inv in Qsw_psi */ + sw_invert(EE, optr->mu); + /* now copy double sw and sw_inv fields to 32bit versions */ + copy_32_sw_fields(); + }/*clover leave update*/ +} + +/* + * Generic inversion routine. The one in operator.c (op_invert) is not appropriate for + * this purpose since it is designed for the propagator measurements. + * The solve_degenerate (solver/monomial_solve.c) does not offer the DDalphaAMG functionality + * for non-quadratic operator. + */ +static int invert_operator_Q(spinor * const P, spinor * const Q, + const int op_id, const int pm, int updateparameters) { + + operator * optr = &operator_list[op_id]; + int iteration_count = 0; + int use_solver = optr->solver; + int rel_prec = optr->rel_prec; + double eps_sq = optr->eps_sq; + double check_prec; + int max_iter = optr->maxiter; + matrix_mult f = optr->applyQm; + int is_squared = 0; + spinor * source = Q; + if (pm == 1) { + f = optr->applyQp; + } + solver_params_t solver_params = optr->solver_params; + int n = VOLUME; + if (is_schur_complement(f)) { + n = VOLUME / 2; + } + + optr->iterations = 0; + optr->reached_prec = -1.; + update_global_parameters(op_id); + + if (use_solver == MIXEDCG || use_solver == RGMIXEDCG || use_solver == CG) { + if (!is_sym_pos_definite(f)) { + f = optr->applyQsq; + is_squared = 1; + if (pm == 0) { + optr->applyQp(g_spinor_field[DUM_DERI], Q); + source = g_spinor_field[DUM_DERI]; + } + } + } + + /*check initial precision since some inverters fail if already converged*/ + f(g_spinor_field[DUM_DERI + 2], P); + diff(g_spinor_field[DUM_DERI + 2], g_spinor_field[DUM_DERI + 2], source, n); + check_prec = square_norm(g_spinor_field[DUM_DERI + 2], VOLUME, 1); + if (g_proc_id == 0) { + printf("Inversion initial precision %e\n", check_prec); + } + if (check_prec < 1e-24) { + return (0); + } + + if (use_solver == MIXEDCG || use_solver == RGMIXEDCG) { + // the default mixed solver is rg_mixed_cg_her + int + (*msolver_fp)(spinor * const, spinor * const, solver_params_t, const int, + double, const int, const int, matrix_mult, + matrix_mult32) = rg_mixed_cg_her; + + // but it might be necessary at some point to use the old version + if (use_solver == MIXEDCG) { + msolver_fp = mixed_cg_her; + } + + if (usegpu_flag) { +#ifdef HAVE_GPU +#ifdef TEMPORALGAUGE + to_temporalgauge(g_gauge_field, source , P); +#endif + iteration_count = linsolve_eo_gpu(P, source, max_iter, eps_sq, rel_prec, n, f); +#ifdef TEMPORALGAUGE + from_temporalgauge(source, P); +#endif +#endif + return (iteration_count); + } else { + if (f == Qtm_pm_psi) { + iteration_count = msolver_fp(P, source, solver_params, max_iter, eps_sq, + rel_prec, n, f, &Qtm_pm_psi_32); + return (iteration_count); + } else if (f == Q_pm_psi) { + iteration_count = msolver_fp(P, source, solver_params, max_iter, eps_sq, + rel_prec, n, f, &Q_pm_psi_32); + return (iteration_count); + } else if (f == Qsw_pm_psi) { + copy_32_sw_fields(); + iteration_count = msolver_fp(P, source, solver_params, max_iter, eps_sq, + rel_prec, n, f, &Qsw_pm_psi_32); + return (iteration_count); + } else { + if (g_proc_id == 0) + printf( + "Warning: 32 bit matrix not available. Falling back to CG in 64 bit\n"); + use_solver = CG; + } + } + } + if (use_solver == CG) { + iteration_count = cg_her(P, source, max_iter, eps_sq, rel_prec, n, f); + } else if (use_solver == BICGSTAB) { + iteration_count = bicgstab_complex(P, source, max_iter, eps_sq, rel_prec, n, + f); + } +#ifdef DDalphaAMG + else if (use_solver == MG) + { + if (updateparameters == 1) + { + MG_update_kappa (g_kappa); + } + iteration_count = MG_solver (P, source, eps_sq, max_iter, rel_prec, n, + g_gauge_field, f); + } +#endif + else { + if (g_proc_id == 0) + printf("Error: solver not allowed for degenerate solve. Aborting...\n"); + return -1; + } + if (is_squared) { + f = optr->applyQm; + if (pm == 1) { + optr->applyQm(g_spinor_field[DUM_DERI], P); + assign(P, g_spinor_field[DUM_DERI], n); + f = optr->applyQp; + } + } + /*check precision*/ + f(g_spinor_field[DUM_DERI], P); + diff(g_spinor_field[DUM_DERI], g_spinor_field[DUM_DERI], Q, n); + check_prec = square_norm(g_spinor_field[DUM_DERI], VOLUME, 1); + optr->reached_prec = check_prec; + optr->iterations = iteration_count; + if (g_proc_id == 0) { + printf("Inversion final precision %e\n", check_prec); + } + return (iteration_count); +} + +/* + * Interpolation for the factorized version of the reweighting factors. + */ +static void interpolate(double * const rcurrent, const double rinitial, + const double rfinal, const int numsteps, const int thisstep) { + (*rcurrent) = rinitial + + (thisstep + 1) * (rfinal - rinitial) / ((double) numsteps); +} + +/* + * Alternative calculation of reweighting factors using Chebyshev polynomial approximations. + */ +static void chebyshev_coeff(const unsigned int np, double * const coeff, + const double a, const double b) { + double * fxk; + double * acxk; + fxk = malloc(np * sizeof(double)); + acxk = malloc(np * sizeof(double)); + int n, k; + double fakt; + for (n = 0; n < np; n++) { + acxk[n] = (3.14159265358979323846) * ((double) n + 0.5) / ((double) np); + fxk[n] = log(a * cos(acxk[n]) + b); + } + for (k = 0; k < np; k++) { + coeff[k] = 0; + fakt = (k == 0) ? 1.0 / (double) np : 2.0 / (double) np; + for (n = 0; n < np; n++) { + coeff[k] += fakt * cos(k * acxk[n]) * fxk[n]; + } + } + free(fxk); + free(acxk); +} + +/* + * Alternative calculation of reweighting factors using Chebyshev polynomial approximations. + */ +static double poly_cheb(const unsigned int np, const double * const coeff, + const double x) { + double y, t1, t0, t2; + int j; + y = coeff[0]; + if (np < 1) { + return y; + } + t0 = 1.0; + t1 = x; + y += coeff[1] * t1; + for (j = 1; j + 1 < np; j++) { + t2 = 2.0 * x * t1 - t0; + t0 = t1; + t1 = t2; + y += coeff[j + 1] * t1; + } + return y; +} + +/* + * Alternative calculation of reweighting factors using Chebyshev polynomial approximations. + * Main part: log determinant estimation. + */ +/*Trivial test tests the function with the scaled identity matrix.*/ +/*#define TRIVIAL_TEST*/ +/*Convergence checks: comparison of order n and n+1.*/ +static void log_determinant_estimate(const int operatorid, int chebmax, + int estimators, const double minev, const double maxev, const double kappa1, + const double kappa2, const double kappa2Mu1, const double kappa2Mu2, + const double shift, const int traj, const split_list * const split, + const vector_list * const coefflist) { + double * coeff; + const double t1 = maxev - minev; + const double t2 = maxev + minev; + const double a = 2.0 / t1; + const double b = -t2 / t1; + const double am = t1 / 2.0; + const double bm = t2 / 2.0; + double rel_shift; + int k, l, n; + int orderstart, orderend; + int splitlength, sl; + spinor_array spinorarray; + static int written = 0; + double x, y, y1, prodre; + FILE * ofs; + spinor * vs; + spinor * u; + + // for convergence checks + spinor * unm1; + double prodrenm1; + + spinor * v0; + spinor * v1; + spinor * v2; + spinor * vt0; + spinor * vt1; + spinor * vt2; + spinor * tmp; + operator * optr; + char* filename; + char buf[100]; + + spinorarray.ar = NULL; + spinorarray.buffer = NULL; + spinorarray.length = 0; + + n = VOLUME; + + filename = buf; + sprintf(filename, "%s%.6d", "reweightingmeas_cheb.", traj); + + optr = &operator_list[operatorid]; + + spinorarray.length = 9; + if (is_schur_complement(optr->applyQsq)) { + n = VOLUME / 2; + alloc_spinor_field(&spinorarray, 1); + } else { + alloc_spinor_field(&spinorarray, 0); + } + + vs = spinorarray.ar[0]; + u = spinorarray.ar[1]; + v0 = spinorarray.ar[2]; + v1 = spinorarray.ar[3]; + v2 = spinorarray.ar[4]; + vt0 = spinorarray.ar[5]; + vt1 = spinorarray.ar[6]; + vt2 = spinorarray.ar[7]; + + // for convergence checks + unm1 = spinorarray.ar[8]; + + if (coefflist->el != NULL && coefflist->s != 0) { + chebmax = coefflist->s; + coeff = malloc(chebmax * sizeof(double)); + for (k = 0; k < chebmax; k++) { + coeff[k] = coefflist->el[k]; + } + } else { + coeff = malloc(chebmax * sizeof(double)); + chebyshev_coeff(chebmax, coeff, am, bm); + } + if (g_proc_id == 0 && g_debug_level > 3 && written == 0) { + written = 1; + ofs = fopen("polynomialapproxtest.txt", "w"); + fprintf(ofs, + "# Test of the Chebyshev approximation of the log(x) function: index x y |y-log(x)| chebyshevorder minx, maxx\n"); + for (k = 0; k < 200; k++) { + x = minev + (maxev - minev) * (double) k / (double) (200 - 1); + y = poly_cheb(chebmax, coeff, a * x + b); + y1 = NAN; + if (chebmax > 0) { + y1 = poly_cheb(chebmax - 1, coeff, a * x + b); + } + fprintf(ofs, "%d %g %g %g %g %g %d %g %g\n", k, x, y, y1, + fabs(y - log(x)), fabs(y1 - log(x)), chebmax, minev, maxev); + } + fclose(ofs); + ofs = fopen("coeff_out.txt", "w"); + for (k = 0; k < chebmax; k++) { + fprintf(ofs, "%g\n", coeff[k]); + } + fclose(ofs); + } + + /* include T_min(x) to T_(max-1) (x) */ + orderstart = 0; + orderend = chebmax; + splitlength = 1; + rel_shift = shift; + if (split->est != NULL && split->ord != NULL && split->s != 0) { + splitlength = split->s; + orderend = split->ord[0]; + estimators = split->est[0]; + } + for (sl = 0; sl < splitlength; sl++) { + if (sl > 0) { + orderstart = orderend; + orderend = split->ord[sl]; + estimators = split->est[sl]; + rel_shift = 0.0; + } + + if (orderend > 0) { + for (k = 0; k < estimators; k++) { + if (orderstart > 1 || orderend < 2) { + zero_spinor_field(u, n); + // convergence check + zero_spinor_field(unm1, n); + + } + /* + * Generate estimator + */ + if (n == VOLUME / 2) { + random_spinor_field_eo(vs, reproduce_randomnumber_flag, RN_Z2); + } else { + random_spinor_field_lexic(vs, reproduce_randomnumber_flag, RN_Z2); + } + + assign(v0, vs, n); + assign(vt0, vs, n); + +#ifdef TRIVIAL_TEST + prodre = scalar_prod_r(vs1, vs1, n, 1); + printf("Test noise /Volume= %g, Volume=%d\n",prodre/(double)n,n); + mul_r(v1,kappa1,vs1,n); +#else + optr->kappa = kappa1; + optr->mu = kappa2Mu1; + update_global_parameters(operatorid); + optr->applyQsq(v1, vs); +#endif + /* Makes (*R)=c1*(*R)+c2*(*S) , c1 and c2 are real constants */ + assign_mul_add_mul_r(v1, vs, a, b, n); + +#ifdef TRIVIAL_TEST + mul_r(vt1,kappa2,vs1,n); +#else + optr->kappa = kappa2; + optr->mu = kappa2Mu2; + update_global_parameters(operatorid); + optr->applyQsq(vt1, vs); +#endif + /* Makes (*R)=c1*(*R)+c2*(*S) , c1 and c2 are real constants */ + assign_mul_add_mul_r(vt1, vs, a, b, n); + + if (orderstart < 2) { + /* Makes (*R)=c1*(*S)-c2*(*U) , c1 and c2 are complex constants */ + mul_diff_mul_r(u, vt1, v1, coeff[1], coeff[1], n); + + // convergence check + if (orderend > 1) { + mul_diff_mul_r(unm1, vt1, v1, coeff[1], coeff[1], n); + } + + } + +#ifndef TRIVIAL_TEST + optr->kappa = kappa1; + optr->mu = kappa2Mu1; + update_global_parameters(operatorid); +#endif + + for (l = 1; l + 1 < orderend; l++) { +#ifdef TRIVIAL_TEST + mul_r(v2,kappa1,v1,n); +#else + optr->applyQsq(v2, v1); +#endif + + /* Makes (*R) = c1*(*R) + c2*(*S) + c3*(*U) */ + assign_mul_add_mul_add_mul_r(v2, v1, v0, 2.0 * a, 2.0 * b, -1.0, n); + tmp = v0; + v0 = v1; + v1 = v2; + v2 = tmp; + + if (l + 1 >= orderstart) { + /* (*P) = (*P) + c(*Q) c is a real constant */ + assign_add_mul_r(u, v1, -coeff[l + 1], n); + + // convergence checks + if (l + 2 < orderend) { + assign_add_mul_r(unm1, v1, -coeff[l + 1], n); + } + + } + } +#ifndef TRIVIAL_TEST + optr->kappa = kappa2; + optr->mu = kappa2Mu2; + update_global_parameters(operatorid); +#endif + + for (l = 1; l + 1 < orderend; l++) { +#ifdef TRIVIAL_TEST + mul_r(vt2,kappa2,vt1,n); +#else + optr->applyQsq(vt2, vt1); +#endif + /* Makes (*R) = c1*(*R) + c2*(*S) + c3*(*U) */ + assign_mul_add_mul_add_mul_r(vt2, vt1, vt0, 2.0 * a, 2.0 * b, -1.0, + n); + tmp = vt0; + vt0 = vt1; + vt1 = vt2; + vt2 = tmp; + if (l + 1 >= orderstart) { + /* (*P) = (*P) + c(*Q) c is a real constant */ + assign_add_mul_r(u, vt1, coeff[l + 1], n); + + // convergence checks + if (l + 2 < orderend) { + assign_add_mul_r(unm1, vt1, coeff[l + 1], n); + } + + } + } + + prodre = scalar_prod_r(vs, u, n, 1); + // convergence checks + prodrenm1 = scalar_prod_r(vs, unm1, n, 1); + + if (g_proc_id == 0) { + ofs = fopen(filename, "a"); + fprintf(ofs, "%d %d %g %g %g %g %d %d %g %g ", traj, sl, kappa1, + kappa2, kappa2Mu1, kappa2Mu2, orderend, orderstart, minev, maxev); + fprintf(ofs, " %.17g %.17g ", prodre + rel_shift, prodre); + // convergence checks + fprintf(ofs, " %.17g \n", prodrenm1 + rel_shift); + + fclose(ofs); + } + + } /* estimator iteration*/ + } /* orderend>0*/ + } /* splitlength loop */ + free(coeff); + free_spinor_field_spinor_array(&spinorarray); +} + +void reweighting_measurement(const int traj, const int id, const int ieo) { + reweighting_parameter* param; + double atime, etime; + operator * optr; + FILE *ofs; + FILE *ofs_full; + char *filename; + char *filename_full; + char buf[100]; + char buf_full[100]; + double square1, square2, prodre, prodim, prodreg5, prodimg5, cswpart; + double kappa0, kappa, k2mu0, k2mu, csw0, csw; + double kappafinal, k2mufinal, cswfinal, rmufinal; + double kappainitial, k2muinitial, cswinitial, rmuinitial; + double mdiff, rmu, rmu0; + double tmp1, tmp2, tmp3; + int updateinverter; + int kapparew; + int murew; + /* now we bring it to normal format */ + /* here we use implicitly DUM_MATRIX and DUM_MATRIX+1 */ + spinor * lexicfield1; + spinor * lexicfield2; + + int operatorid; + int numsamples, snum, internum; + unsigned long int site; + + updateinverter = 0; + param = (reweighting_parameter*) measurement_list[id].parameter; + lexicfield1 = g_spinor_field[4]; + lexicfield2 = g_spinor_field[6]; + + operatorid = param->reweighting_operator; + numsamples = param->reweighting_number_sources; + filename = buf; + filename_full = buf_full; + sprintf(filename, "%s%.6d", "reweightingmeas.", traj); + sprintf(filename_full, "%s%.6d", "reweightingmeas_full_data.", traj); + if (g_proc_id == 0) { + fprintf(stdout, "Reweighting measurement %d with %d samples.\n", id, + numsamples); + } + + init_operators(); + if (no_operators < operatorid) { + if (g_proc_id == 0) { + fprintf( + stderr, + "Warning! Number of operators smaller than the given number for the reweighting operator, unable to perform measurement!\n"); + } + return; + } + atime = gettime(); + + optr = &operator_list[operatorid]; + optr->DownProp = 0; + optr->sr0 = g_spinor_field[0]; + optr->sr1 = g_spinor_field[1]; + optr->prop0 = g_spinor_field[2]; + optr->prop1 = g_spinor_field[3]; + + /* now checking parameters + * The target values are obtained from the operator*/ + + kappafinal = optr->kappa; + k2mufinal = optr->mu; + cswfinal = optr->c_sw; + + /* the initial values are obtained + * from the parameter + */ + k2muinitial = param->k2mu0; + kappainitial = param->kappa0; + cswinitial = 0; + kapparew = 1; + if (kappainitial == kappafinal) { + kapparew = 0; + } + if (kappainitial == 0.0) { + kappainitial = kappafinal; + kapparew = 0; + } + if (cswinitial == 0.0) { + cswinitial = cswfinal; + } + /* be careful: + * in the mu reweighting it is the parameter Mu and not 2KappaMu that + * counts + */ + rmufinal = k2mufinal / 2.0 / kappafinal; + rmuinitial = k2muinitial / 2.0 / kappainitial; + murew = 1; + if (k2muinitial == 0.0) { + rmuinitial = rmufinal; + k2muinitial = 2.0 * kappainitial * rmuinitial; + murew = 0; + } + if (fabs(rmuinitial - rmufinal) < 1e-14) { + murew = 0; + } + + /* second option: + * determine mu and mu0 explicitly in the + */ + if (g_proc_id == 0 && (param->rmu != 0 || param->rmu0 != 0)) { + printf( + "WARNING: measurement uses custom mu values mu=%e, mu0=%e instead of the parameters of the operator.\n", + param->rmu, param->rmu0); + } + if (param->rmu0 != 0) { + rmuinitial = param->rmu0; + k2muinitial = 2.0 * kappainitial * rmuinitial; + } + if (param->rmu != 0) { + rmufinal = param->rmu; + k2mufinal = 2.0 * kappafinal * rmufinal; + } + if (fabs(rmuinitial - rmufinal) > 1e-14) { + murew = 1; + } + + if (murew && (g_proc_id == 0)) { + printf("Mu reweighting chosen: "); + printf("mu=%e to mu=%e.\n", rmuinitial, rmufinal); + } + + if (kapparew && (g_proc_id == 0)) { + printf("Kappa reweighting chosen: "); + printf("kappa=%e to kappa=%e\n", kappainitial, kappafinal); + } + + if (!murew && !kapparew) { + if (g_proc_id == 0) { + printf("ERROR: no mu or kappa reweighting.\n"); + } + } + + if (murew && kapparew) { + if (g_proc_id == 0) { + printf( + "WARNING: Mu AND Kappa reweighting chosen. If unprecond version, the rawdata has to be combined by hand!\n"); + } + } + + if (param->use_evenodd && !is_schur_complement(optr->applyQsq) + && g_proc_id == 0) { + printf( + "WARNING: If you want to use the preconditioned version the operator should be even-odd preconditioned.\n"); + } + + cswpart = 0; + + if (param->evest) { + if (g_proc_id == 0) { + printf( + "Calculating minimal/maximal eigenvalue estimates -- no longer supported!\n"); + } + //estimate_eigenvalues (operatorid, traj); + } + + if (param->use_cheb) { + if (is_schur_complement(optr->applyQsq) && !param->use_evenodd + && g_proc_id == 0) { + printf( + "WARNING: If you want to use Chebyshev approximation without preconditioning you have to switch it of in the operator as well.\n"); + } + if (param->use_evenodd == 1) { + cswpart = get_sw_reweighting(k2muinitial, k2mufinal, kappainitial, + kappafinal, cswinitial, cswfinal); + } + log_determinant_estimate(operatorid, param->cheborder, + param->estimatorscheb, param->minev, param->maxev, kappainitial, + kappafinal, k2muinitial, k2mufinal, cswpart, traj, ¶m->splitlist, + ¶m->coeff); + if (param->only_cheb) { + return; + } + } + + kappa0 = kappa = kappainitial; + k2mu0 = k2mu = k2muinitial; + csw0 = csw = cswinitial; + rmu0 = rmu = rmuinitial; + + if (param->interpolationsteps < 1) + param->interpolationsteps = 1; + + if(param->kappaarray.s!=0){ + param->interpolationsteps=param->kappaarray.s; + } + + if (g_proc_id == 0 && g_debug_level > 0) { + printf("REWEIGHTING: interpolation steps %d\n",param->interpolationsteps); + } + + for (internum = 0; internum < param->interpolationsteps; internum++) { + if (kapparew) { + kappa0 = kappa; + tmp1 = 1.0 / kappainitial; + tmp2 = 1.0 / kappafinal; + tmp3 = 1.0 / kappa; + if(internumkappaarray.s){ + kappa=param->kappaarray.el[internum]; + }else{ + interpolate(&tmp3, tmp1, tmp2, param->interpolationsteps, internum); + kappa = 1.0 / tmp3; + } + updateinverter = 1; + } + if (murew) { + /* use quadratic interpolation in the case of mu*/ + rmu0 = rmu; + tmp1 = rmuinitial * rmuinitial; + tmp2 = rmufinal * rmufinal; + tmp3 = rmu * rmu; + interpolate(&tmp3, tmp1, tmp2, param->interpolationsteps, internum); + rmu = sqrt(tmp3); + updateinverter = 1; + } + + k2mu = 2.0 * kappa * rmu; + k2mu0 = 2.0 * kappa0 * rmu0; + if (g_proc_id == 0 && g_debug_level > 0) { + printf("REWEIGHTING: kappa from %.14f to %.14f, mu %.16f to %.16f, 2kappamu %.16f to %.16f\n", kappa0,kappa,rmu,rmu0,k2mu0,k2mu); + } + optr->kappa = kappa; + optr->mu = k2mu; + optr->c_sw = csw; + + if (param->use_evenodd == 1) { + cswpart = get_sw_reweighting(k2mu0, k2mu, kappa0, kappa, csw0, csw); + } + + for (snum = 0; snum < numsamples; snum++) { + if (param->use_evenodd == 0) { + random_spinor_field_eo(optr->sr0, reproduce_randomnumber_flag, + RN_GAUSS); + random_spinor_field_eo(optr->sr1, reproduce_randomnumber_flag, + RN_GAUSS); + convert_eo_to_lexic(lexicfield1, optr->sr0, optr->sr1); + square1 = square_norm(lexicfield1, VOLUME, 1); + // we don't want to do inversion twice for this purpose here + // op_id = 0, index_start = 0, write_prop = 0 + optr->inverter(operatorid, 0, 0); + convert_eo_to_lexic(lexicfield2, optr->prop0, optr->prop1); + square2 = square_norm(lexicfield2, VOLUME, 1); + prodre = scalar_prod_r(lexicfield1, lexicfield2, VOLUME, 1); + prodim = scalar_prod_i(lexicfield1, lexicfield2, VOLUME, 1); + for (site = 0; site < VOLUME; site++) { + _gamma5(lexicfield2[site], lexicfield2[site]); + } + prodreg5 = scalar_prod_r(lexicfield1, lexicfield2, VOLUME, 1); + prodimg5 = scalar_prod_i(lexicfield1, lexicfield2, VOLUME, 1); + + if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + ofs = fopen(filename, "a"); + ofs_full = fopen(filename_full, "a"); + fprintf(ofs, "%d %d %d %d ", traj, operatorid, internum, snum); + fprintf(ofs_full, "%d %d %d %d ", traj, operatorid, internum, snum); + + /*print all raw data for cross check*/ + fprintf(ofs_full, + "%.17g %.17g %.17g %.17g %.17g %.17g %.17g %.17g ", k2mu0, k2mu, + kappa0, kappa, csw0, csw, rmu0, rmu); + fprintf(ofs_full, "%.17g %.17g %.17g %.17g %.17g %.17g\n", square1, + square2, prodre, prodim, prodreg5, prodimg5); + /*print two and one flavour reweighting log factors*/ + if (murew) { /* ignoring rounding errors*/ + fprintf(ofs, "%.17g %.17g %.17g\n", + (rmu * rmu - rmu0 * rmu0) * square2, (rmu - rmu0) * prodreg5, + (rmu - rmu0) * prodimg5); + } + if (kapparew) { + mdiff = 0.5 / kappa - 0.5 / kappa0; + fprintf(ofs, "%.17g %.17g %.17g\n", + 2.0 * mdiff * prodre + mdiff * mdiff * square2, mdiff * prodre, + mdiff * prodim); + } + fclose(ofs); + fclose(ofs_full); + } + } else { /* end not even odd*/ + set_even_to_zero(optr->sr0); + set_even_to_zero(optr->prop0); + random_spinor_field_eo(lexicfield1, reproduce_randomnumber_flag, + RN_GAUSS); + square1 = square_norm(lexicfield1, VOLUME / 2, 1); + + optr->kappa = kappa0; + optr->mu = k2mu0; + update_global_parameters(operatorid); + + optr->applyQm(optr->sr0, lexicfield1); + assign(optr->prop0, lexicfield1, VOLUME / 2); + + optr->kappa = kappa; + optr->mu = k2mu; + /* done in inverter: update_global_parameters(operatorid);*/ + + invert_operator_Q(optr->prop0, optr->sr0, operatorid, 0, + updateinverter); + updateinverter = 0; + + square2 = square_norm(optr->prop0, VOLUME / 2, 1); + + if (g_mpi_time_rank == 0 && g_proc_coords[0] == 0) { + ofs = fopen(filename, "a"); + ofs_full = fopen(filename_full, "a"); + fprintf(ofs, "%d %d %d %d ", traj, operatorid, internum, snum); + fprintf(ofs_full, "%d %d %d %d ", traj, operatorid, internum, snum); + fprintf(ofs_full, + "%.17g %.17g %.17g %.17g %.17g %.17g %.17g %.17g ", k2mu0, k2mu, + kappa0, kappa, csw0, csw, rmu, rmu0); + fprintf(ofs_full, "%.17g %.17g %.17g\n", square1, square2, cswpart); + fprintf(ofs, "%.17g\n", square1 - square2 + cswpart); + fclose(ofs); + fclose(ofs_full); + } + + }/* end even odd*/ + + }/* loop over estimators */ + + } /* loop over interpolation steps*/ + + etime = gettime(); + + if (g_proc_id == 0 && g_debug_level > 0) { + printf("REWEIGHTING: measurement done int t/s = %1.4e\n", etime - atime); + } + return; +} + +/** + * Destructor for the parameter, frees allocated memory. + * @param par reweighting parameter. + */ +void free_reweighting_parameter(void* par) { + reweighting_parameter* param; + param = (reweighting_parameter*) (par); + if (param->coeff.el) + free(param->coeff.el); + if (param->splitlist.ord) + free(param->splitlist.ord); + if (param->splitlist.est) + free(param->splitlist.est); + if(param->kappaarray.el) + free(param->kappaarray.el); + param->kappaarray.el=NULL; + param->kappaarray.s=0; + param->coeff.el = NULL; + param->coeff.s = 0; + param->splitlist.ord = NULL; + param->splitlist.est = NULL; + param->splitlist.s = 0; +} + +/** + * Coefficients provided for the Chebyshev approximation of log(x). + * Values are read from coeff.dat. + * @param v (output) value + */ +static void read_coeff_from_file(vector_list* v) { + FILE* file; + unsigned int l; + double dat; + + file = fopen("coeff.dat", "r"); + l = 0; + dat = 0; + + if (file) { + while (fscanf(file, "%lg ", &dat) > 0) { + l++; + } + v->s = l; + v->el = malloc(l * sizeof(double)); + file = freopen("coeff.dat", "r", file); + l = 0; + while (fscanf(file, "%lg ", &dat) > 0) { + v->el[l++] = dat; + } + if (g_debug_level > 3) { + printf( + "The following coefficients have been read from file coeff.dat:\n"); + for (l = 0; l < v->s; l++) { + printf("%d %lg\n", l, v->el[l]); + } + } + fclose(file); + } else { + if (g_proc_id == 0) { + printf("File coeff.dat not present.\n"); + } + v->el = NULL; + v->s = 0; + } + +} + +/** + * + * @param list + */ +static void read_splitlist(split_list* list) { + FILE* file; + unsigned int l; + int dat1, dat2; + + file = fopen("split.dat", "r"); + l = 0; + dat1 = dat2 = 0; + + if (file) { + while (fscanf(file, "%d ", &dat1) > 0 && fscanf(file, "%d ", &dat2) > 0) { + l++; + } + list->s = l; + list->ord = malloc(l * sizeof(unsigned int)); + list->est = malloc(l * sizeof(unsigned int)); + + file = freopen("split.dat", "r", file); + l = 0; + while (fscanf(file, "%d ", &dat1) > 0 && fscanf(file, "%d ", &dat2) > 0) { + list->ord[l] = dat1; + list->est[l] = dat2; + l++; + } + if (g_debug_level > 3) { + printf( + "The following factor splits have been read from file split.dat:\n"); + for (l = 0; l < list->s; l++) { + printf("%d %d %d\n", l, list->ord[l], list->est[l]); + } + } + fclose(file); + } else { + if (g_proc_id == 0) { + printf("File split.dat not present.\n"); + } + list->ord = NULL; + list->est = NULL; + list->s = 0; + } + +} + +static void read_kappalist(vector_list* kappaarray) { + FILE* file; + unsigned int l; + double dat; + + file = fopen("kappa.dat", "r"); + l = 0; + dat = 0; + + if (file) { + while (fscanf(file, "%lg ", &dat) > 0) { + l++; + } + if(l==0){ + fclose(file); + return; + } + kappaarray->s=l; + kappaarray->el = malloc(l * sizeof(double)); + + file = freopen("kappa.dat", "r", file); + l = 0; + while (fscanf(file, "%lg ", &dat) > 0) { + kappaarray->el[l++] = dat; + } + if (g_debug_level > 3) { + printf( + "The following kappa value have been obtained from kappa.dat:\n"); + for (l = 0; l < kappaarray->s; l++) { + printf("%d %lg\n", l, kappaarray->el[l]); + } + } + fclose(file); + } else { + if (g_proc_id == 0) { + printf("File kappa.dat not present.\n"); + } + kappaarray->el = NULL; + kappaarray->s = 0; + } + +} + +void initialize_reweighting_parameter(void** parameter) { + reweighting_parameter* param; + if (!(*parameter)) { + (*parameter) = malloc(sizeof(reweighting_parameter)); + param = (reweighting_parameter*) (*parameter); + param->reweighting_operator = 0; + param->reweighting_number_sources = 0; + param->use_evenodd = 0; + param->k2mu0 = 0.0; + param->kappa0 = 0.0; + param->kappaarray.el= NULL; + param->kappaarray.s=0; + param->rmu0 = 0.0; + param->rmu = 0.0; + param->minev = 1e-7; + param->maxev = 20.0; + param->interpolationsteps = 1; + param->estimatorscheb = 0; + param->cheborder = 0; + param->use_cheb = 0; + param->only_cheb = 0; + param->coeff.el = NULL; + param->coeff.s = 0; + param->splitlist.ord = NULL; + param->splitlist.est = NULL; + param->splitlist.s = 0; + param->evest = 0; + param->testchebconvergence = 0; + read_coeff_from_file(¶m->coeff); + read_splitlist(¶m->splitlist); + //read_kappalist(¶m->kappaarray); + } +} diff --git a/meas/reweightingmeas.h b/meas/reweightingmeas.h new file mode 100644 index 000000000..5c57a5654 --- /dev/null +++ b/meas/reweightingmeas.h @@ -0,0 +1,99 @@ +/*********************************************************************** + * + * Measurements of the reweighting factors by Georg Bergner 2016 + * + * Copyright (C) 20016 Georg Bergner + * + * This file is part of tmLQCD. + * + * tmLQCD is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * tmLQCD is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with tmLQCD. If not, see . + ***********************************************************************/ + +#ifndef _REWEIGHTING_MEASUREMENT_H +#define _REWEIGHTING_MEASUREMENT_H +#include +#include + +/** + * This struct collects data for the Chebyshev reweighting factor measurements. + * These are the coefficients for the log(x) approximation provided from outside. + */ +typedef struct{ + double* el; + unsigned int s; +} vector_list; + +inline void allocate(vector_list* v, const unsigned int length){ + v->s=length; + v->el = malloc(length * sizeof(double)); +} + +/** + * This struct collects data for the Chebyshev reweighting factor measurements. + * The split_list allows to combine different approximations. + */ +typedef struct { + unsigned int * ord; + unsigned int* est; + unsigned int s; + +} split_list; + + +/** + * Parameters for the reweighting factor measurements. + */ +typedef struct { + int reweighting_operator; + int reweighting_number_sources; + int use_evenodd; + double k2mu0; + double kappa0; + vector_list kappaarray; + double rmu0; + double rmu; + double minev; + double maxev; + double testchebconvergence; + int interpolationsteps; + int estimatorscheb; + int cheborder; + int use_cheb; + int only_cheb; + int evest; + vector_list coeff; + split_list splitlist; +} reweighting_parameter; + +/** + * Destructor for parameter. + * @param par + */ +void free_reweighting_parameter(void* par); + +/** + * Constructor for parameter. + * @param parameter + */ +void initialize_reweighting_parameter(void** parameter); + +/** + * main measurement. + * @param traj + * @param t0 + * @param ieo + */ +void reweighting_measurement(const int traj, const int t0, const int ieo); + +#endif diff --git a/monomial/monomial.h b/monomial/monomial.h index c2321956f..c03a686f5 100644 --- a/monomial/monomial.h +++ b/monomial/monomial.h @@ -50,6 +50,7 @@ #define CLOVERRAT 19 #define CLOVERRATCOR 20 #define CLOVERDETRATIORW 21 +#define CLOVERDETRATIORWD 22 #define max_no_monomials 30 diff --git a/read_input.l b/read_input.l index 16c34fc2e..b96f8ee18 100644 --- a/read_input.l +++ b/read_input.l @@ -59,6 +59,7 @@ EQL {SPC}*={SPC}* #include"monomial/monomial.h" #include"solver/solver_types.h" #include"meas/measurements.h" +#include"meas/reweightingmeas.h" #include"integrator.h" #include"operator.h" #include"phmc.h" @@ -266,6 +267,32 @@ static inline double fltlist_next_token(int * const list_end){ } } + static inline void parse_double_vector(const char * const input,vector_list* vector){ + char paramname[100]; + char* inputcopy; + int list_end = 0; + int l=0; + double value = 0; + inputcopy=strdup(input); + fltlist_tokenize(inputcopy, paramname, 100); + value = (double)fltlist_next_token(&list_end); + while( list_end != 1 ){ + l++; + value = (double)fltlist_next_token(&list_end); + } + free(inputcopy); + allocate(vector,l); + fltlist_tokenize(input, paramname, 100); + value = (double)fltlist_next_token(&list_end); + l=0; + while( list_end != 1 ){ + vector->el[l]=value; + l++; + value = (double)fltlist_next_token(&list_end); + } + } + + %} %option never-interactive @@ -339,6 +366,7 @@ static inline double fltlist_next_token(int * const list_end){ %x NOSOURCESZ2 %x INITMEASUREMENT %x ONLINEMEAS +%x REWEIGHTINGMEAS %x PIONNORMMEAS %x PLOOP %x ORIENTEDPLAQUETTESMEAS @@ -1603,6 +1631,7 @@ static inline double fltlist_next_token(int * const list_end){ mnl->type = CLOVERDETRATIORW; strcpy((*mnl).name, "CLOVERDETRATIORW"); } + else if(strcmp(yytext, "DETRATIO")==0) { mnl->type = DETRATIO; strcpy((*mnl).name, "DETRATIO"); @@ -2311,6 +2340,7 @@ static inline double fltlist_next_token(int * const list_end){ if(myverbose) printf("initialising measurements line %d\n", line_of_file); current_measurement++; meas = &measurement_list[current_measurement]; + meas->parameter=(void*)NULL; meas->id = current_measurement; meas->direction = 0; meas->max_iter = 15000; @@ -2322,6 +2352,11 @@ static inline double fltlist_next_token(int * const list_end){ meas->type = PIONNORM; strcpy((*meas).name, "PIONNORM"); } + else if(strcmp(yytext, "REWEIGHTINGMEAS")==0) { + meas->type = REWEIGHTING; + initialize_reweighting_parameter(&meas->parameter); + strcpy((*meas).name, "REWEIGHTINGMEAS"); + } else if(strcmp(yytext, "POLYAKOVLOOP")==0) { meas->type = POLYAKOV; strcpy((*meas).name, "POLYAKOV"); @@ -2358,13 +2393,14 @@ static inline double fltlist_next_token(int * const list_end){ if(myverbose) printf("measurement has id %d\n", current_measurement); if(meas->type == ONLINE) BEGIN(ONLINEMEAS); + else if(meas->type == REWEIGHTING) BEGIN(REWEIGHTINGMEAS); else if(meas->type == PIONNORM) BEGIN(PIONNORMMEAS); else if(meas->type == POLYAKOV) BEGIN(PLOOP); else if(meas->type == ORIENTED_PLAQUETTES) BEGIN(ORIENTEDPLAQUETTESMEAS); else if(meas->type == GRADIENT_FLOW) BEGIN(GRADIENTFLOWMEAS); } -{ +{ ^EndMeasurement{SPC}* { if(myverbose) printf("Measurement with id %d parsed in line %d\n\n", meas->id, line_of_file); BEGIN(0); @@ -2376,7 +2412,7 @@ static inline double fltlist_next_token(int * const list_end){ } } -{ +{ {SPC}*MaxSolverIterations{EQL}{DIGIT}+ { sscanf(yytext, " %[a-zA-Z] = %d", name, &a); meas->max_iter = a; @@ -2397,6 +2433,111 @@ static inline double fltlist_next_token(int * const list_end){ } } + +{ + {SPC}*Operator{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->reweighting_operator = a; + if(myverbose) printf(" ReweightingOperator set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*Samples{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->reweighting_number_sources = a; + if(myverbose) printf(" ReweightingSamples set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*InterpolationSteps{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->interpolationsteps = a; + if(myverbose) printf(" ReweightingSamples set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*UseEvenOdd{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->use_evenodd = a; + if(myverbose) printf(" UseEvenOdd set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*2KappaMu0{EQL}{FLT} { + sscanf(yytext, " %[20a-zA-Z] = %lf", name, &c); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->k2mu0 = c; + if(myverbose) printf("Reweighting 2KappaMu0 set to %e line %d\n", c, line_of_file); + } + {SPC}*Mu{EQL}{FLT} { + sscanf(yytext, " %[a-zA-Z] = %lf", name, &c); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->rmu = c; + if(myverbose) printf("Reweighting Mu set to %e line %d\n", c, line_of_file); + } + {SPC}*Mu0{EQL}{FLT} { + sscanf(yytext, " %[0a-zA-Z] = %lf", name, &c); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->rmu0 = c; + if(myverbose) printf("Reweighting Mu0 set to %e line %d\n", c, line_of_file); + } + {SPC}*Kappa0{EQL}{FLT} { + sscanf(yytext, " %[20a-zA-Z] = %lf", name, &c); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->kappa0 = c; + if(myverbose) printf("Reweighting Kappa0 set to %e line %d\n", c, line_of_file); + } + {SPC}*UseCheb{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->use_cheb = a; + if(myverbose) printf(" UseCheb set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*EvEst{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->evest = a; + if(myverbose) printf(" EvEst set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*UseChebOnly{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->only_cheb = a; + if(myverbose) printf(" UseChebOnly set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*ChebOrder{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->cheborder = a; + if(myverbose) printf(" ChebOrder set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*ChebEst{EQL}{DIGIT}+ { + sscanf(yytext, " %[a-zA-Z] = %d", name, &a); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->estimatorscheb = a; + if(myverbose) printf(" ChebEst set to %d line %d measurement id=%d\n", a, line_of_file, meas->id); + } + {SPC}*MinEv{EQL}{FLT} { + sscanf(yytext, " %[20a-zA-Z] = %lf", name, &c); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->minev = c; + if(myverbose) printf("Reweighting MinEv set to %e line %d\n", c, line_of_file); + } + {SPC}*MaxEv{EQL}{FLT} { + sscanf(yytext, " %[20a-zA-Z] = %lf", name, &c); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->maxev = c; + if(myverbose) printf("Reweighting MaxEv set to %e line %d\n", c, line_of_file); + } + {SPC}*ChebConvLimit{EQL}{FLT} { + sscanf(yytext, " %[a-zA-Z] = %lf", name, &c); + initialize_reweighting_parameter(&meas->parameter); + ((reweighting_parameter*)meas->parameter)->testchebconvergence = c; + if(myverbose) printf("Reweighting ChebConvLimit set to %e line %d\n", c, line_of_file); + } + {SPC}*KappaSteps{EQL}{FLTLIST} { + initialize_reweighting_parameter(&meas->parameter); + parse_double_vector(yytext,&((reweighting_parameter*)meas->parameter)->kappaarray); + if(myverbose) printf("Reweighting KappaSteps %d line %d\n", ((reweighting_parameter*)meas->parameter)->kappaarray.s, line_of_file); + } +} + { {SPC}*StepSize{EQL}{FLT} { sscanf(yytext, " %[2a-zA-Z] = %lf", name, &c); @@ -2410,6 +2551,7 @@ static inline double fltlist_next_token(int * const list_end){ } } + { {SPC}*Direction{EQL}[03] { sscanf(yytext, " %[a-zA-Z] = %d", name, &a); @@ -2941,7 +3083,7 @@ static inline double fltlist_next_token(int * const list_end){ BEGIN(comment_caller); } -{SPC}*\n { +{SPC}*\n { line_of_file++; } <*>{SPC}*\n {