LCOV - code coverage report
Current view: top level - isdb - MetainferenceBase.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 81 83 97.6 %
Date: 2025-03-25 09:33:27 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2017-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_isdb_MetainferenceBase_h
      23             : #define __PLUMED_isdb_MetainferenceBase_h
      24             : 
      25             : #include "core/ActionWithValue.h"
      26             : #include "core/ActionAtomistic.h"
      27             : #include "core/ActionWithArguments.h"
      28             : #include "tools/Communicator.h"
      29             : #include "core/PlumedMain.h"
      30             : #include "tools/Random.h"
      31             : #include "tools/OpenMP.h"
      32             : 
      33             : #define PLUMED_METAINF_INIT(ao) Action(ao),MetainferenceBase(ao)
      34             : 
      35             : namespace PLMD {
      36             : namespace isdb {
      37             : 
      38             : /**
      39             : \ingroup INHERIT
      40             : This is the abstract base class to use for implementing new ISDB Metainference actions, within it there is
      41             : information as to how to go about implementing a new Metainference action.
      42             : */
      43             : 
      44             : class MetainferenceBase :
      45             :   public ActionAtomistic,
      46             :   public ActionWithArguments,
      47             :   public ActionWithValue {
      48             : private:
      49             :   std::vector<double> forces;
      50             :   std::vector<double> forcesToApply;
      51             : 
      52             :   // activate metainference
      53             :   bool doscore_;
      54             :   unsigned write_stride_;
      55             :   // number of experimental data
      56             :   unsigned narg;
      57             :   // experimental data
      58             :   std::vector<double> parameters;
      59             :   // metainference derivatives
      60             :   std::vector<double> metader_;
      61             :   // vector of back-calculated experimental data
      62             :   std::vector<double> calc_data_;
      63             : 
      64             :   // noise type
      65             :   unsigned noise_type_;
      66             :   enum { GAUSS, MGAUSS, OUTLIERS, MOUTLIERS, GENERIC };
      67             :   unsigned gen_likelihood_;
      68             :   enum { LIKE_GAUSS, LIKE_LOGN };
      69             :   bool   doscale_;
      70             :   unsigned scale_prior_;
      71             :   enum { SC_GAUSS, SC_FLAT };
      72             :   double scale_;
      73             :   double scale_mu_;
      74             :   double scale_min_;
      75             :   double scale_max_;
      76             :   double Dscale_;
      77             :   // scale is data scaling factor
      78             :   // noise type
      79             :   unsigned offset_prior_;
      80             :   bool   dooffset_;
      81             :   double offset_;
      82             :   double offset_mu_;
      83             :   double offset_min_;
      84             :   double offset_max_;
      85             :   double Doffset_;
      86             :   // scale and offset regression
      87             :   bool doregres_zero_;
      88             :   int  nregres_zero_;
      89             :   // sigma is data uncertainty
      90             :   std::vector<double> sigma_;
      91             :   std::vector<double> sigma_min_;
      92             :   std::vector<double> sigma_max_;
      93             :   std::vector<double> Dsigma_;
      94             :   // sigma_mean is uncertainty in the mean estimate
      95             :   std::vector<double> sigma_mean2_;
      96             :   // this is the estimator of the mean value per replica for generic metainference
      97             :   std::vector<double> ftilde_;
      98             :   double Dftilde_;
      99             : 
     100             :   // temperature in kbt
     101             :   double   kbt_;
     102             : 
     103             :   // Monte Carlo stuff
     104             :   std::vector<Random> random;
     105             :   unsigned MCsteps_;
     106             :   long long unsigned MCaccept_;
     107             :   long long unsigned MCacceptScale_;
     108             :   long long unsigned MCacceptFT_;
     109             :   long long unsigned MCtrial_;
     110             :   unsigned MCchunksize_;
     111             : 
     112             :   // output
     113             :   Value*   valueScore;
     114             :   Value*   valueScale;
     115             :   Value*   valueOffset;
     116             :   Value*   valueAccept;
     117             :   Value*   valueAcceptScale;
     118             :   Value*   valueAcceptFT;
     119             :   std::vector<Value*> valueSigma;
     120             :   std::vector<Value*> valueSigmaMean;
     121             :   std::vector<Value*> valueFtilde;
     122             : 
     123             :   // restart
     124             :   std::string status_file_name_;
     125             :   OFile    sfile_;
     126             :   std::string fmt_;
     127             : 
     128             :   // others
     129             :   bool     firstTime;
     130             :   std::vector<bool> firstTimeW;
     131             :   bool     master;
     132             :   bool     do_reweight_;
     133             :   unsigned do_optsigmamean_;
     134             :   unsigned nrep_;
     135             :   unsigned replica_;
     136             : 
     137             :   // selector
     138             :   unsigned nsel_;
     139             :   std::string selector_;
     140             :   unsigned iselect;
     141             : 
     142             :   // optimize sigma mean
     143             :   std::vector< std::vector < std::vector <double> > > sigma_mean2_last_;
     144             :   unsigned optsigmamean_stride_;
     145             :   // optimize sigma max
     146             :   unsigned N_optimized_step_;
     147             :   unsigned optimized_step_;
     148             :   bool sigmamax_opt_done_;
     149             :   std::vector<double> sigma_max_est_;
     150             : 
     151             :   // average weights
     152             :   double decay_w_;
     153             :   std::vector< std::vector <double> >  average_weights_;
     154             : 
     155             :   double getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
     156             :                         const double scale, const double offset);
     157             :   double getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
     158             :                      const double scale, const double offset);
     159             :   double getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
     160             :                       const double scale, const double offset);
     161             :   double getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
     162             :                      const double scale, const double offset);
     163             :   double getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
     164             :                       const double scale, const double offset);
     165             :   void setMetaDer(const unsigned index, const double der);
     166             :   void getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
     167             :   void getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
     168             :   void getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
     169             :   void getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
     170             :   void getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
     171             :   double getCalcData(const unsigned index);
     172             :   void get_weights(double &weight, double &norm, double &neff);
     173             :   void replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b);
     174             :   void get_sigma_mean(const double weight, const double norm, const double neff, const std::vector<double> &mean);
     175             :   void do_regression_zero(const std::vector<double> &mean);
     176             :   void moveTilde(const std::vector<double> &mean_, double &old_energy);
     177             :   void moveScaleOffset(const std::vector<double> &mean_, double &old_energy);
     178             :   void moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow);
     179             :   double doMonteCarlo(const std::vector<double> &mean);
     180             : 
     181             : public:
     182             :   static void registerKeywords( Keywords& keys );
     183             :   explicit MetainferenceBase(const ActionOptions&);
     184             :   ~MetainferenceBase();
     185             :   void Initialise(const unsigned input);
     186             :   void Selector();
     187             :   unsigned getNarg();
     188             :   void setNarg(const unsigned input);
     189             :   void setParameters(const std::vector<double>& input);
     190             :   void setParameter(const double input);
     191             :   void setCalcData(const unsigned index, const double datum);
     192             :   void setCalcData(const std::vector<double>& data);
     193             :   bool getDoScore();
     194             :   unsigned getWstride();
     195             :   double getScore();
     196             :   void setScore(const double score);
     197             :   void setDerivatives();
     198             :   double getMetaDer(const unsigned index);
     199             :   void writeStatus();
     200             :   void turnOnDerivatives() override;
     201             :   unsigned getNumberOfDerivatives() override;
     202             :   void lockRequests() override;
     203             :   void unlockRequests() override;
     204             :   void calculateNumericalDerivatives( ActionWithValue* a ) override;
     205             :   void apply() override;
     206             :   void setArgDerivatives(Value *v, const double &d);
     207             :   void setAtomsDerivatives(Value*v, const unsigned i, const Vector&d);
     208             :   void setBoxDerivatives(Value*v, const Tensor&d);
     209             : };
     210             : 
     211             : inline
     212             : void MetainferenceBase::setNarg(const unsigned input) {
     213          44 :   narg = input;
     214             : }
     215             : 
     216             : inline
     217             : bool MetainferenceBase::getDoScore() {
     218       22895 :   return doscore_;
     219             : }
     220             : 
     221             : inline
     222             : unsigned MetainferenceBase::getWstride() {
     223        1794 :   return write_stride_;
     224             : }
     225             : 
     226             : inline
     227             : unsigned MetainferenceBase::getNarg() {
     228        2327 :   return narg;
     229             : }
     230             : 
     231             : inline
     232             : void MetainferenceBase::setMetaDer(const unsigned index, const double der) {
     233        7524 :   metader_[index] = der;
     234             : }
     235             : 
     236             : inline
     237             : double MetainferenceBase::getMetaDer(const unsigned index) {
     238      912722 :   return metader_[index];
     239             : }
     240             : 
     241             : inline
     242             : double MetainferenceBase::getCalcData(const unsigned index) {
     243             :   return calc_data_[index];
     244             : }
     245             : 
     246             : inline
     247             : void MetainferenceBase::setCalcData(const unsigned index, const double datum) {
     248        3868 :   calc_data_[index] = datum;
     249        3868 : }
     250             : 
     251             : inline
     252             : void MetainferenceBase::setCalcData(const std::vector<double>& data) {
     253             :   for(unsigned i=0; i<data.size(); i++) {
     254             :     calc_data_[i] = data[i];
     255             :   }
     256             : }
     257             : 
     258             : inline
     259          40 : void MetainferenceBase::setParameters(const std::vector<double>& input) {
     260         252 :   for(unsigned i=0; i<input.size(); i++) {
     261         212 :     parameters.push_back(input[i]);
     262             :   }
     263          40 : }
     264             : 
     265             : inline
     266             : void MetainferenceBase::setParameter(const double input) {
     267        2356 :   parameters.push_back(input);
     268        2356 : }
     269             : 
     270             : inline
     271        2327 : void MetainferenceBase::setScore(const double score) {
     272        2327 :   valueScore->set(score);
     273        2327 : }
     274             : 
     275             : inline
     276         136 : void MetainferenceBase::setDerivatives() {
     277             :   // Get appropriate number of derivatives
     278             :   // Derivatives are first for arguments and then for atoms
     279             :   unsigned nder;
     280         136 :   if( getNumberOfAtoms()>0 ) {
     281         136 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
     282             :   } else {
     283           0 :     nder = getNumberOfArguments();
     284             :   }
     285             : 
     286             :   // Resize all derivative arrays
     287         136 :   forces.resize( nder );
     288         136 :   forcesToApply.resize( nder );
     289       21777 :   for(int i=0; i<getNumberOfComponents(); ++i) {
     290       21641 :     getPntrToComponent(i)->resizeDerivatives(nder);
     291             :   }
     292         136 : }
     293             : 
     294             : inline
     295        2862 : void MetainferenceBase::turnOnDerivatives() {
     296        2862 :   ActionWithValue::turnOnDerivatives();
     297        2862 : }
     298             : 
     299             : inline
     300     2829388 : unsigned MetainferenceBase::getNumberOfDerivatives() {
     301     2829388 :   if( getNumberOfAtoms()>0 ) {
     302     2829388 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
     303             :   }
     304           0 :   return getNumberOfArguments();
     305             : }
     306             : 
     307             : inline
     308         897 : void MetainferenceBase::lockRequests() {
     309             :   ActionAtomistic::lockRequests();
     310             :   ActionWithArguments::lockRequests();
     311         897 : }
     312             : 
     313             : inline
     314         897 : void MetainferenceBase::unlockRequests() {
     315             :   ActionAtomistic::unlockRequests();
     316             :   ActionWithArguments::unlockRequests();
     317         897 : }
     318             : 
     319             : inline
     320          75 : void MetainferenceBase::calculateNumericalDerivatives( ActionWithValue* a=NULL ) {
     321          75 :   if( getNumberOfArguments()>0 ) {
     322          48 :     ActionWithArguments::calculateNumericalDerivatives( a );
     323             :   }
     324          75 :   if( getNumberOfAtoms()>0 ) {
     325          75 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
     326        1293 :     for(int j=0; j<getNumberOfComponents(); ++j) {
     327        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i)
     328        1104 :         if(getPntrToComponent(j)->hasDerivatives()) {
     329         240 :           save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
     330             :         }
     331             :     }
     332          75 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
     333        1293 :     for(int j=0; j<getNumberOfComponents(); ++j) {
     334        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i)
     335        1104 :         if(getPntrToComponent(j)->hasDerivatives()) {
     336         240 :           getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
     337             :         }
     338             :     }
     339             :   }
     340          75 : }
     341             : 
     342             : inline
     343         897 : void MetainferenceBase::apply() {
     344             :   bool wasforced=false;
     345         897 :   forcesToApply.assign(forcesToApply.size(),0.0);
     346       35268 :   for(int i=0; i<getNumberOfComponents(); ++i) {
     347       34371 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
     348             :       wasforced=true;
     349    41724504 :       for(unsigned i=0; i<forces.size(); ++i) {
     350    41717854 :         forcesToApply[i]+=forces[i];
     351             :       }
     352             :     }
     353             :   }
     354         897 :   if( wasforced ) {
     355         482 :     unsigned ind=0;
     356         482 :     addForcesOnArguments( 0, forcesToApply, ind, getLabel() );
     357         482 :     if( getNumberOfAtoms()>0 ) {
     358         482 :       setForcesOnAtoms( forcesToApply, ind );
     359             :     }
     360             :   }
     361         897 : }
     362             : 
     363             : inline
     364             : void MetainferenceBase::setArgDerivatives(Value *v, const double &d) {
     365         160 :   v->addDerivative(0,d);
     366             : }
     367             : 
     368             : inline
     369     2776760 : void MetainferenceBase::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
     370     2776760 :   const unsigned noa=getNumberOfArguments();
     371     2776760 :   v->addDerivative(noa+3*i+0,d[0]);
     372     2776760 :   v->addDerivative(noa+3*i+1,d[1]);
     373     2776760 :   v->addDerivative(noa+3*i+2,d[2]);
     374     2776760 : }
     375             : 
     376             : inline
     377       12544 : void MetainferenceBase::setBoxDerivatives(Value* v,const Tensor&d) {
     378       12544 :   const unsigned noa=getNumberOfArguments();
     379             :   const unsigned nat=getNumberOfAtoms();
     380       12544 :   v->addDerivative(noa+3*nat+0,d(0,0));
     381       12544 :   v->addDerivative(noa+3*nat+1,d(0,1));
     382       12544 :   v->addDerivative(noa+3*nat+2,d(0,2));
     383       12544 :   v->addDerivative(noa+3*nat+3,d(1,0));
     384       12544 :   v->addDerivative(noa+3*nat+4,d(1,1));
     385       12544 :   v->addDerivative(noa+3*nat+5,d(1,2));
     386       12544 :   v->addDerivative(noa+3*nat+6,d(2,0));
     387       12544 :   v->addDerivative(noa+3*nat+7,d(2,1));
     388       12544 :   v->addDerivative(noa+3*nat+8,d(2,2));
     389       12544 : }
     390             : 
     391             : 
     392             : }
     393             : }
     394             : 
     395             : #endif
     396             : 

Generated by: LCOV version 1.16