From c9a71cfca3486834e548b7b88f64c8a7972c7f01 Mon Sep 17 00:00:00 2001 From: Carlo Camilloni <carlo.camilloni@gmail.com> Date: Wed, 18 May 2016 16:11:37 +0200 Subject: [PATCH] METAINFERENCE: merged GJE and SPE in a new BIAS the old one are still there for reference --- regtest/.gitignore | 2 +- .../rt-bayesgje/BIAS.0.reference | 26 +- .../rt-bayesgje/BIAS.1.reference | 26 +- .../rt-bayesgje/forces.0.reference | 24 +- .../rt-bayesgje/forces.1.reference | 24 +- regtest/metainference/rt-bayesgje/plumed.dat | 9 +- regtest/metainference/rt-bayesspe/plumed.dat | 5 +- src/bias/Metainference.cpp | 490 ++++++++++++++++++ 8 files changed, 549 insertions(+), 57 deletions(-) create mode 100644 src/bias/Metainference.cpp diff --git a/regtest/.gitignore b/regtest/.gitignore index d7b7fd89d..5874524a8 100644 --- a/regtest/.gitignore +++ b/regtest/.gitignore @@ -15,7 +15,7 @@ !/scripts !/manyrestraints !/molfile_plugin -!/bayesbias +!/metainference # These files we just want to ignore completely tmp report.txt diff --git a/regtest/metainference/rt-bayesgje/BIAS.0.reference b/regtest/metainference/rt-bayesgje/BIAS.0.reference index b8a7514ab..bf05ee067 100644 --- a/regtest/metainference/rt-bayesgje/BIAS.0.reference +++ b/regtest/metainference/rt-bayesgje/BIAS.0.reference @@ -1,13 +1,13 @@ -#! FIELDS time spe.bias spe.scale spe.accept spe.sigma_0 spe.kappa_0 spe.sigma_1 spe.kappa_1 spe.sigma_2 spe.kappa_2 spe.sigma_3 spe.kappa_3 - 0.000000 1237852.869575 1.000000 1.000000 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.050000 1282471.107299 1.000000 0.181818 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.100000 1315165.380004 1.000000 0.142857 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.150000 1333063.481567 1.000000 0.129032 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.200000 1351555.666802 1.000000 0.121951 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.250000 1371772.655731 1.000000 0.117647 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.300000 1293440.279295 1.000000 0.114754 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.350000 1292004.343160 1.000000 0.112676 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.400000 1310371.270133 1.000000 0.111111 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.450000 1243985.739979 1.000000 0.109890 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.500000 1266194.635296 1.000000 0.108911 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.550000 1247194.127448 1.000000 0.108108 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 +#! FIELDS time spe.bias spe.scale spe.accept spe.sigma_0 spe.sigma_1 spe.sigma_2 spe.sigma_3 + 0.000000 1244011.703127 1.000000 1.000000 0.010000 0.010000 0.010000 0.010000 + 0.050000 1288851.922133 1.000000 0.090909 0.010000 0.010000 0.010000 0.010000 + 0.100000 1321708.852911 1.000000 0.047619 0.010000 0.010000 0.010000 0.010000 + 0.150000 1339695.999756 1.000000 0.032258 0.010000 0.010000 0.010000 0.010000 + 0.200000 1358280.185913 1.000000 0.024390 0.010000 0.010000 0.010000 0.010000 + 0.250000 1378597.756876 1.000000 0.019608 0.010000 0.010000 0.010000 0.010000 + 0.300000 1299875.667124 1.000000 0.016393 0.010000 0.010000 0.010000 0.010000 + 0.350000 1298432.587028 1.000000 0.014085 0.010000 0.010000 0.010000 0.010000 + 0.400000 1316890.891747 1.000000 0.012346 0.010000 0.010000 0.010000 0.010000 + 0.450000 1250175.085324 1.000000 0.010989 0.010000 0.010000 0.010000 0.010000 + 0.500000 1272494.472658 1.000000 0.009901 0.010000 0.010000 0.010000 0.010000 + 0.550000 1253399.434919 1.000000 0.009009 0.010000 0.010000 0.010000 0.010000 diff --git a/regtest/metainference/rt-bayesgje/BIAS.1.reference b/regtest/metainference/rt-bayesgje/BIAS.1.reference index b8a7514ab..bf05ee067 100644 --- a/regtest/metainference/rt-bayesgje/BIAS.1.reference +++ b/regtest/metainference/rt-bayesgje/BIAS.1.reference @@ -1,13 +1,13 @@ -#! FIELDS time spe.bias spe.scale spe.accept spe.sigma_0 spe.kappa_0 spe.sigma_1 spe.kappa_1 spe.sigma_2 spe.kappa_2 spe.sigma_3 spe.kappa_3 - 0.000000 1237852.869575 1.000000 1.000000 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.050000 1282471.107299 1.000000 0.181818 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.100000 1315165.380004 1.000000 0.142857 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.150000 1333063.481567 1.000000 0.129032 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.200000 1351555.666802 1.000000 0.121951 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.250000 1371772.655731 1.000000 0.117647 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.300000 1293440.279295 1.000000 0.114754 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.350000 1292004.343160 1.000000 0.112676 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.400000 1310371.270133 1.000000 0.111111 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.450000 1243985.739979 1.000000 0.109890 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.500000 1266194.635296 1.000000 0.108911 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 - 0.550000 1247194.127448 1.000000 0.108108 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 0.010000 49392.844158 +#! FIELDS time spe.bias spe.scale spe.accept spe.sigma_0 spe.sigma_1 spe.sigma_2 spe.sigma_3 + 0.000000 1244011.703127 1.000000 1.000000 0.010000 0.010000 0.010000 0.010000 + 0.050000 1288851.922133 1.000000 0.090909 0.010000 0.010000 0.010000 0.010000 + 0.100000 1321708.852911 1.000000 0.047619 0.010000 0.010000 0.010000 0.010000 + 0.150000 1339695.999756 1.000000 0.032258 0.010000 0.010000 0.010000 0.010000 + 0.200000 1358280.185913 1.000000 0.024390 0.010000 0.010000 0.010000 0.010000 + 0.250000 1378597.756876 1.000000 0.019608 0.010000 0.010000 0.010000 0.010000 + 0.300000 1299875.667124 1.000000 0.016393 0.010000 0.010000 0.010000 0.010000 + 0.350000 1298432.587028 1.000000 0.014085 0.010000 0.010000 0.010000 0.010000 + 0.400000 1316890.891747 1.000000 0.012346 0.010000 0.010000 0.010000 0.010000 + 0.450000 1250175.085324 1.000000 0.010989 0.010000 0.010000 0.010000 0.010000 + 0.500000 1272494.472658 1.000000 0.009901 0.010000 0.010000 0.010000 0.010000 + 0.550000 1253399.434919 1.000000 0.009009 0.010000 0.010000 0.010000 0.010000 diff --git a/regtest/metainference/rt-bayesgje/forces.0.reference b/regtest/metainference/rt-bayesgje/forces.0.reference index faefc5998..0ed61d28d 100644 --- a/regtest/metainference/rt-bayesgje/forces.0.reference +++ b/regtest/metainference/rt-bayesgje/forces.0.reference @@ -1,13 +1,13 @@ #! FIELDS time ardc.rdc.rdc_0 ardc.rdc.rdc_1 ardc.rdc.rdc_2 ardc.rdc.rdc_3 - 0.000000 100642.38088002 141989.23823686 180293.36768282 243915.51628401 - 0.050000 96031.98232030 157899.37479933 182544.22046024 243354.07707703 - 0.100000 86716.33822558 159398.77609836 187600.18135685 248608.44413448 - 0.150000 81737.66067248 165952.55849053 203282.42805091 236961.41787945 - 0.200000 84584.72558079 163371.00532409 207785.88775295 237703.35057586 - 0.250000 93071.99457441 165199.43919893 194520.13904297 248451.87259207 - 0.300000 88502.40103501 166208.29851741 179909.50684797 244859.64655378 - 0.350000 88835.19479396 143704.44676296 195579.89949173 246668.89502228 - 0.400000 98275.89353361 137347.51224637 199311.50046416 247399.52636605 - 0.450000 98743.90812140 135101.70403599 196684.05229235 237083.74826703 - 0.500000 102074.94767658 127111.08569720 203939.31073060 238583.95889519 - 0.550000 102375.94644906 127568.39283256 186229.01549716 248550.43197152 + 0.000000 101143.08924261 142695.65235745 181190.34961159 245129.02631528 + 0.050000 96509.75337662 158684.94382818 183452.40066154 244564.79387841 + 0.100000 87147.76279387 160191.80483517 188533.51559246 249845.30206550 + 0.150000 82144.31570070 166778.19310989 204293.78341435 238140.33040621 + 0.200000 85005.54511104 164183.79639535 208819.64838854 238885.95431007 + 0.250000 93535.03932353 166021.32695614 195487.90092875 249687.95156019 + 0.300000 88942.71148792 167035.20547521 180804.57902134 246077.85375057 + 0.350000 89277.16093721 144419.39425930 196552.93381756 247896.10345523 + 0.400000 98764.82832731 138030.83320282 200303.09996895 248630.36978081 + 0.450000 99235.17134588 135773.85181726 197662.57991569 238263.26940268 + 0.500000 102582.78323716 127743.47915838 204953.93416707 239770.94376532 + 0.550000 102885.27951597 128203.06145362 187155.52801207 249787.00128481 diff --git a/regtest/metainference/rt-bayesgje/forces.1.reference b/regtest/metainference/rt-bayesgje/forces.1.reference index faefc5998..0ed61d28d 100644 --- a/regtest/metainference/rt-bayesgje/forces.1.reference +++ b/regtest/metainference/rt-bayesgje/forces.1.reference @@ -1,13 +1,13 @@ #! FIELDS time ardc.rdc.rdc_0 ardc.rdc.rdc_1 ardc.rdc.rdc_2 ardc.rdc.rdc_3 - 0.000000 100642.38088002 141989.23823686 180293.36768282 243915.51628401 - 0.050000 96031.98232030 157899.37479933 182544.22046024 243354.07707703 - 0.100000 86716.33822558 159398.77609836 187600.18135685 248608.44413448 - 0.150000 81737.66067248 165952.55849053 203282.42805091 236961.41787945 - 0.200000 84584.72558079 163371.00532409 207785.88775295 237703.35057586 - 0.250000 93071.99457441 165199.43919893 194520.13904297 248451.87259207 - 0.300000 88502.40103501 166208.29851741 179909.50684797 244859.64655378 - 0.350000 88835.19479396 143704.44676296 195579.89949173 246668.89502228 - 0.400000 98275.89353361 137347.51224637 199311.50046416 247399.52636605 - 0.450000 98743.90812140 135101.70403599 196684.05229235 237083.74826703 - 0.500000 102074.94767658 127111.08569720 203939.31073060 238583.95889519 - 0.550000 102375.94644906 127568.39283256 186229.01549716 248550.43197152 + 0.000000 101143.08924261 142695.65235745 181190.34961159 245129.02631528 + 0.050000 96509.75337662 158684.94382818 183452.40066154 244564.79387841 + 0.100000 87147.76279387 160191.80483517 188533.51559246 249845.30206550 + 0.150000 82144.31570070 166778.19310989 204293.78341435 238140.33040621 + 0.200000 85005.54511104 164183.79639535 208819.64838854 238885.95431007 + 0.250000 93535.03932353 166021.32695614 195487.90092875 249687.95156019 + 0.300000 88942.71148792 167035.20547521 180804.57902134 246077.85375057 + 0.350000 89277.16093721 144419.39425930 196552.93381756 247896.10345523 + 0.400000 98764.82832731 138030.83320282 200303.09996895 248630.36978081 + 0.450000 99235.17134588 135773.85181726 197662.57991569 238263.26940268 + 0.500000 102582.78323716 127743.47915838 204953.93416707 239770.94376532 + 0.550000 102885.27951597 128203.06145362 187155.52801207 249787.00128481 diff --git a/regtest/metainference/rt-bayesgje/plumed.dat b/regtest/metainference/rt-bayesgje/plumed.dat index c23798c09..70072bca8 100644 --- a/regtest/metainference/rt-bayesgje/plumed.dat +++ b/regtest/metainference/rt-bayesgje/plumed.dat @@ -11,15 +11,16 @@ ATOMS4=33,34 ardc: ENSEMBLE ARG=rdc.* stat: STATS ARG=ardc.* PARAMETERS=1.9190,2.9190,3.9190,4.9190 SQDEV -BAYESIANGJE ... -ARG=ardc.* +METAINFERENCE ... +ARG=ardc.* +NOISETYPE=MGAUSS PARAMETERS=1.9190,2.9190,3.9190,4.9190 SCALEDATA SCALE0=1 SCALE_MIN=0.00001 SCALE_MAX=3 DSCALE=0.00 -MULTISIGMA SIGMA0=0.01 SIGMA_MIN=0.00001 SIGMA_MAX=3 DSIGMA=0.00 +SIGMA0=0.01 SIGMA_MIN=0.00001 SIGMA_MAX=3 DSIGMA=0.00 SIGMA_MEAN=0.001 TEMP=300 LABEL=spe -... BAYESIANGJE +... METAINFERENCE DUMPFORCES ARG=ardc.* FILE=forces FMT=%15.8f diff --git a/regtest/metainference/rt-bayesspe/plumed.dat b/regtest/metainference/rt-bayesspe/plumed.dat index ac186bd9d..a070ff1ab 100644 --- a/regtest/metainference/rt-bayesspe/plumed.dat +++ b/regtest/metainference/rt-bayesspe/plumed.dat @@ -11,15 +11,16 @@ ATOMS4=33,34 ardc: ENSEMBLE ARG=rdc.* stat: STATS ARG=ardc.* PARAMETERS=1.9190,2.9190,3.9190,4.9190 SQDEV -BAYESIANSPE ... +METAINFERENCE ... ARG=ardc.* PARAMETERS=1.9190,2.9190,3.9190,4.9190 +NOISETYPE=LTAIL SCALEDATA SCALE0=1 SCALE_MIN=0.00001 SCALE_MAX=3 DSCALE=0.00 SIGMA0=0.01 SIGMA_MIN=0.00001 SIGMA_MAX=3 DSIGMA=0.00 SIGMA_MEAN=0.001 TEMP=300 LABEL=spe -... BAYESIANSPE +... METAINFERENCE DUMPFORCES ARG=ardc.* FILE=forces diff --git a/src/bias/Metainference.cpp b/src/bias/Metainference.cpp new file mode 100644 index 000000000..911d07a50 --- /dev/null +++ b/src/bias/Metainference.cpp @@ -0,0 +1,490 @@ +/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Copyright (c) 2013 The plumed team + (see the PEOPLE file at the root of the distribution for a list of names) + + See http://www.plumed-code.org for more information. + + This file is part of plumed, version 2. + + plumed is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + plumed 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with plumed. If not, see <http://www.gnu.org/licenses/>. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ +#include "Bias.h" +#include "ActionRegister.h" +#include "core/PlumedMain.h" +#include "core/Atoms.h" +#include "core/Value.h" +#include <cmath> + +using namespace std; + +namespace PLMD{ +namespace bias{ + +//+PLUMEDOC BIAS METAINFERENCE +/* +Calculate the Metainference Score for a set of experimental Data. + +*/ +//+ENDPLUMEDOC + +class Metainference : public Bias +{ + const double sqrt2pi; + const double sqrt2_div_pi; + // experimental values + vector<double> parameters; + // noise type + unsigned noise_type_; + enum { GAUSS, MGAUSS, LTAIL}; + // scale is data scaling factor + bool doscale_; + double scale_; + double scale_min_; + double scale_max_; + double Dscale_; + // sigma is data uncertainty + vector<double> sigma_; + double sigma_min_; + double sigma_max_; + double Dsigma_; + // sigma_mean is uncertainty in the mean estimate + double sigma_mean_; + // temperature in kbt + double kbt_; + // number of data points + unsigned ndata_; + // Monte Carlo stuff + double old_energy; + unsigned MCsteps_; + unsigned MCstride_; + unsigned MCaccept_; + long int MCfirst_; + // output + Value* valueBias; + Value* valueScale; + Value* valueAccept; + vector<Value*> valueSigma; + + unsigned nrep_; + unsigned replica_; + + double getEnergySPE(const double sigma, const double scale); + double getEnergyGJE(const vector<double> &sigma, const double scale); + void doMonteCarlo(); + double getEnergyForceSPE(); + double getEnergyForceGJE(); + +public: + explicit Metainference(const ActionOptions&); + void calculate(); + static void registerKeywords(Keywords& keys); +}; + + +PLUMED_REGISTER_ACTION(Metainference,"METAINFERENCE") + +void Metainference::registerKeywords(Keywords& keys){ + Bias::registerKeywords(keys); + keys.use("ARG"); + keys.add("optional","PARARG","the input for this action is the scalar output from other actions without derivatives."); + keys.add("optional","PARAMETERS","the parameters of the arguments in your function"); + keys.add("compulsory","NOISETYPE","functional form of the noise (GAUSS,MGAUSS,LTAIL)"); + keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas."); + keys.addFlag("OPTSIGMAMEAN", false, "Set to minimize sigma_mean on the fly"); + keys.add("compulsory","SCALE0","initial value of the uncertainty parameter"); + keys.add("compulsory","SCALE_MIN","minimum value of the uncertainty parameter"); + keys.add("compulsory","SCALE_MAX","maximum value of the uncertainty parameter"); + keys.add("compulsory","DSCALE","maximum MC move of the uncertainty parameter"); + keys.add("compulsory","SIGMA0","initial value of the uncertainty parameter"); + keys.add("compulsory","SIGMA_MIN","minimum value of the uncertainty parameter"); + keys.add("compulsory","SIGMA_MAX","maximum value of the uncertainty parameter"); + keys.add("compulsory","DSIGMA","maximum MC move of the uncertainty parameter"); + keys.add("compulsory","SIGMA_MEAN","starting value for the uncertainty in the mean estimate"); + keys.add("optional","TEMP","the system temperature - this is only needed if code doesnt' pass the temperature to plumed"); + keys.add("optional","MC_STEPS","number of MC steps"); + keys.add("optional","MC_STRIDE","MC stride"); + componentsAreNotOptional(keys); + useCustomisableComponents(keys); + keys.addOutputComponent("bias","default","the instantaneous value of the bias potential"); + keys.addOutputComponent("sigma", "default","uncertainty parameter"); + keys.addOutputComponent("scale", "default","scale parameter"); + keys.addOutputComponent("accept","default","MC acceptance"); +} + +Metainference::Metainference(const ActionOptions&ao): +PLUMED_BIAS_INIT(ao), +sqrt2pi(2.506628274631001), +sqrt2_div_pi(0.45015815807855), +doscale_(false), +ndata_(getNumberOfArguments()), +old_energy(0), +MCsteps_(1), +MCstride_(1), +MCaccept_(0), +MCfirst_(-1) +{ + parseVector("PARAMETERS",parameters); + if(parameters.size()!=static_cast<unsigned>(getNumberOfArguments())&&!parameters.empty()) + error("Size of PARAMETERS array should be either 0 or the same as of the number of arguments in ARG1"); + + vector<Value*> arg2; + parseArgumentList("PARARG",arg2); + + if(!arg2.empty()) { + if(parameters.size()>0) error("It is not possible to use PARARG and PARAMETERS together"); + if(arg2.size()!=getNumberOfArguments()) error("Size of PARARG array should be the same as number for arguments in ARG"); + for(unsigned i=0;i<arg2.size();i++){ + parameters.push_back(arg2[i]->get()); + if(arg2[i]->hasDerivatives()==true) error("PARARG can only accept arguments without derivatives"); + } + } + + if(parameters.size()!=getNumberOfArguments()) + error("PARARG or PARAMETERS arrays should include the same number of elements as the arguments in ARG"); + + string stringa_noise; + parse("NOISETYPE",stringa_noise); + if(stringa_noise=="GAUSS") noise_type_ = GAUSS; + else if(stringa_noise=="MGAUSS") noise_type_ = MGAUSS; + else if(stringa_noise=="LTAIL") noise_type_ = LTAIL; + else error("Unkwnow noise type"); + + parseFlag("SCALEDATA", doscale_); + if(doscale_) { + parse("SCALE0",scale_); + parse("SCALE_MIN",scale_min_); + parse("SCALE_MAX",scale_max_); + parse("DSCALE",Dscale_); + } else { + scale_=1.0; + } + + vector<double> readsigma; + parseVector("SIGMA0",readsigma); + if(noise_type_!=MGAUSS&&readsigma.size()>1) error("If you want to use more than one sigma you should add MULTISIGMA"); + + parse("SIGMA_MIN",sigma_min_); + parse("SIGMA_MAX",sigma_max_); + parse("DSIGMA",Dsigma_); + parse("MC_STEPS",MCsteps_); + parse("MC_STRIDE",MCstride_); + // get temperature + double temp=0.0; + parse("TEMP",temp); + parse("SIGMA_MEAN",sigma_mean_); + + checkRead(); + + if(temp>0.0) kbt_=plumed.getAtoms().getKBoltzmann()*temp; + else kbt_=plumed.getAtoms().getKbT(); + + if(readsigma.size()==getNumberOfArguments()) { + sigma_.resize(getNumberOfArguments()); + sigma_=readsigma; + } else if(readsigma.size()==1) { + if(noise_type_==MGAUSS) sigma_.resize(getNumberOfArguments(),readsigma[0]); + else sigma_.resize(1, readsigma[0]); + } else { + error("SIGMA0 can accept either one single value or as many values as the number of arguments (with MULTISIGMA)"); + } + + // get number of replicas + if(comm.Get_rank()==0) { + nrep_ = multi_sim_comm.Get_size(); + replica_ = multi_sim_comm.Get_rank(); + } else { + nrep_ = 0; + replica_ = 0; + } + comm.Sum(&nrep_,1); + comm.Sum(&replica_,1); + + // divide sigma_mean by the square root of the number of replicas + sigma_mean_ /= sqrt(static_cast<double>(nrep_)); + + // adjust for multiple-time steps + MCstride_ *= getStride(); + + switch(noise_type_) { + case GAUSS: + log.printf(" with gaussian noise and a single noise parameter for all the data\n"); + break; + case MGAUSS: + log.printf(" with gaussian noise and a noise parameter for each data point\n"); + break; + case LTAIL: + log.printf(" with long tailed gaussian noise and a single noise parameter for all the data\n"); + break; + } + + if(doscale_) { + log.printf(" sampling a common scaling factor with:\n"); + log.printf(" initial scale parameter %f\n",scale_); + log.printf(" minimum scale parameter %f\n",scale_min_); + log.printf(" maximum scale parameter %f\n",scale_max_); + log.printf(" maximum MC move of scale parameter %f\n",Dscale_); + } + + if(readsigma.size()==1) log.printf(" initial data uncertainty %f\n",sigma_[0]); + else { + log.printf(" initial data uncertainties"); + for(unsigned i=0;i<sigma_.size();++i) log.printf(" %f", sigma_[i]); + log.printf("\n"); + } + log.printf(" minimum data uncertainty %f\n",sigma_min_); + log.printf(" maximum data uncertainty %f\n",sigma_max_); + log.printf(" maximum MC move of data uncertainty %f\n",Dsigma_); + log.printf(" uncertainty in the mean estimate %f\n",sigma_mean_); + log.printf(" temperature of the system %f\n",kbt_); + log.printf(" number of experimental data points %u\n",getNumberOfArguments()); + log.printf(" number of replicas %u\n",nrep_); + log.printf(" MC steps %u\n",MCsteps_); + log.printf(" MC stride %u\n",MCstride_); + + addComponent("bias"); + componentIsNotPeriodic("bias"); + valueBias=getPntrToComponent("bias"); + if(doscale_) { + addComponent("scale"); + componentIsNotPeriodic("scale"); + valueScale=getPntrToComponent("scale"); + } + addComponent("accept"); + componentIsNotPeriodic("accept"); + valueAccept=getPntrToComponent("accept"); + + if(noise_type_==MGAUSS) { + for(unsigned i=0;i<sigma_.size();++i){ + std::string num; Tools::convert(i,num); + addComponent("sigma_"+num); componentIsNotPeriodic("sigma_"+num); + valueSigma.push_back(getPntrToComponent("sigma_"+num)); + } + } else { + addComponent("sigma"); componentIsNotPeriodic("sigma"); + valueSigma.push_back(getPntrToComponent("sigma")); + } + // initialize random seed + unsigned iseed; + if(comm.Get_rank()==0) iseed = time(NULL)+replica_; + else iseed = 0; + comm.Sum(&iseed, 1); + srand(iseed); +} + +double Metainference::getEnergySPE(const double sigma, const double scale){ + // calculate effective sigma + const double smean2 = sigma_mean_*sigma_mean_; + const double s = sqrt( sigma*sigma + smean2 ); + // cycle on arguments + double ene = 0.0; + for(unsigned i=0;i<getNumberOfArguments();++i){ + const double dev = scale*getArgument(i)-parameters[i]; + // argument + const double a2 = 0.5*dev*dev + s*s; + // increment energy + ene += std::log( 2.0 * a2 / ( 1.0 - exp(- a2 / smean2) ) ); + } + // add normalization and Jeffrey's prior + ene += std::log(s) - static_cast<double>(ndata_)*std::log(sqrt2_div_pi*s); + return kbt_ * ene; +} + +double Metainference::getEnergyGJE(const vector<double> &sigma, const double scale){ + // cycle on arguments + double ene = 0.0; + const double smean2 = sigma_mean_*sigma_mean_; + double ss = sigma[0]*sigma[0] + smean2; + for(unsigned i=0;i<getNumberOfArguments();++i){ + if(noise_type_==MGAUSS) ss = sigma[i]*sigma[i] + smean2; + const double dev = scale*getArgument(i)-parameters[i]; + ene += 0.5*dev*dev/ss + std::log(ss*sqrt2pi); + } + return kbt_ * ene; +} + +void Metainference::doMonteCarlo(){ + // calculate old energy (first time only) + if(MCfirst_==-1) { + switch(noise_type_) { + case GAUSS: + case MGAUSS: + old_energy = getEnergyGJE(sigma_,scale_); + break; + case LTAIL: + old_energy = getEnergySPE(sigma_[0],scale_); + break; + } + } + + // cycle on MC steps + for(unsigned i=0;i<MCsteps_;++i){ + + // propose move for scale + double new_scale = scale_; + if(doscale_) { + const double r1 = static_cast<double>(rand()) / RAND_MAX; + const double ds1 = -Dscale_ + r1 * 2.0 * Dscale_; + new_scale += ds1; + // check boundaries + if(new_scale > scale_max_){new_scale = 2.0 * scale_max_ - new_scale;} + if(new_scale < scale_min_){new_scale = 2.0 * scale_min_ - new_scale;} + // the scaling factor should be the same for all the replicas + if(comm.Get_rank()==0) multi_sim_comm.Bcast(new_scale,0); + comm.Bcast(new_scale,0); + } + + // propose move for sigma + vector<double> new_sigma(sigma_.size()); + for(unsigned j=0;j<sigma_.size();++j) { + const double r2 = static_cast<double>(rand()) / RAND_MAX; + const double ds2 = -Dsigma_ + r2 * 2.0 * Dsigma_; + new_sigma[j] = sigma_[j] + ds2; + // check boundaries + if(new_sigma[j] > sigma_max_){new_sigma[j] = 2.0 * sigma_max_ - new_sigma[j];} + if(new_sigma[j] < sigma_min_){new_sigma[j] = 2.0 * sigma_min_ - new_sigma[j];} + } + + // calculate new energy + double new_energy=0; + switch(noise_type_) { + case GAUSS: + case MGAUSS: + new_energy = getEnergyGJE(new_sigma,new_scale); + break; + case LTAIL: + new_energy = getEnergySPE(new_sigma[0],new_scale); + break; + } + + // accept or reject + const double delta = ( new_energy - old_energy ) / kbt_; + // if delta is negative always accept move + if( delta <= 0.0 ){ + old_energy = new_energy; + scale_ = new_scale; + sigma_ = new_sigma; + MCaccept_++; + // otherwise extract random number + } else { + const double s = static_cast<double>(rand()) / RAND_MAX; + if( s < exp(-delta) ){ + old_energy = new_energy; + scale_ = new_scale; + sigma_ = new_sigma; + MCaccept_++; + } + } + + if(doscale_) { + // the scaling factor should be the same for all the replicas + if(comm.Get_rank()==0) multi_sim_comm.Bcast(scale_,0); + comm.Bcast(scale_,0); + } + } + /* save the result of the sampling */ + if(doscale_) valueScale->set(scale_); + for(unsigned i=0; i<sigma_.size(); i++) valueSigma[i]->set(sigma_[i]); +} + +double Metainference::getEnergyForceSPE() +{ + double ene = 0.0; + const unsigned narg=getNumberOfArguments(); + + const double smean2 = sigma_mean_*sigma_mean_; + const double s = sqrt( sigma_[0]*sigma_[0] + smean2 ); + vector<double> f(narg,0); + + if(comm.Get_rank()==0){ + for(unsigned i=0;i<narg;++i){ + const double dev = scale_*getArgument(i)-parameters[i]; + const double a2 = 0.5*dev*dev + s*s; + const double t = exp(-a2/smean2); + const double dt = 1./t; + const double it = 1./(1.-t); + const double dit = 1./(1.-dt); + ene += std::log(2.*a2*it); + f[i] = -scale_*dev*(dit/smean2 + 1./a2); + } + // collect contribution to forces and energy from other replicas + multi_sim_comm.Sum(&f[0],narg); + multi_sim_comm.Sum(&ene,1); + // add normalizations and priors of local replica + ene += std::log(s) - static_cast<double>(ndata_)*std::log(sqrt2_div_pi*s); + } + // intra-replica summation + comm.Sum(&f[0],narg); + comm.Sum(&ene,1); + + for(unsigned i=0; i<narg; ++i) setOutputForce(i, kbt_ * f[i]); + return ene; +} + +double Metainference::getEnergyForceGJE() +{ + double ene = 0.0; + + const unsigned ssize = sigma_.size(); + vector<double> ss(ssize); + vector<double> inv_s2(ssize, 0.); + const double smean2 = sigma_mean_*sigma_mean_; + + for(unsigned i=0;i<ssize; ++i) { + ss[i] = sigma_[i]*sigma_[i] + smean2; + if(comm.Get_rank()==0) inv_s2[i] = 1.0/ss[i]; + } + + if(comm.Get_rank()==0) multi_sim_comm.Sum(&inv_s2[0],ssize); + comm.Sum(&inv_s2[0],ssize); + + const unsigned narg=getNumberOfArguments(); + for(unsigned i=0;i<narg;++i){ + const double dev = scale_*getArgument(i)-parameters[i]; + unsigned sel_sigma=0; + if(noise_type_==MGAUSS) sel_sigma=i; + ene += 0.5*dev*dev*inv_s2[sel_sigma] + std::log(ss[sel_sigma]*sqrt2pi); + setOutputForce(i, -kbt_*dev*scale_*inv_s2[sel_sigma]); + } + return ene; +} + +void Metainference::calculate(){ + /* MONTE CARLO */ + const long int step = getStep(); + if(step%MCstride_==0&&!getExchangeStep()) doMonteCarlo(); + // this is needed when restarting simulations + if(MCfirst_==-1) MCfirst_=step; + const double MCtrials = floor(static_cast<double>(step-MCfirst_) / static_cast<double>(MCstride_))+1.0; + const double accept = static_cast<double>(MCaccept_) / static_cast<double>(MCsteps_) / MCtrials; + valueAccept->set(accept); + + // calculate bias and forces + double ene = 0; + switch(noise_type_) { + case GAUSS: + case MGAUSS: + ene = getEnergyForceGJE(); + break; + case LTAIL: + ene = getEnergyForceSPE(); + break; + } + // set value of the bias + valueBias->set(kbt_*ene); +} + +} +} + + -- GitLab