IMP logo
IMP Reference Guide  develop.385bf31a7a,2026/08/05
The Integrative Modeling Platform
MonteCarlo.h
Go to the documentation of this file.
1 /**
2  * \file IMP/core/MonteCarlo.h \brief Simple Monte Carlo optimizer.
3  *
4  * Copyright 2007-2026 IMP Inventors. All rights reserved.
5  *
6  */
7 
8 #ifndef IMPCORE_MONTE_CARLO_H
9 #define IMPCORE_MONTE_CARLO_H
10 
11 #include <IMP/core/core_config.h>
12 #include "MonteCarloMover.h"
13 #include <IMP/Optimizer.h>
14 #include <IMP/container_macros.h>
15 #include <IMP/internal/container_helpers.h>
17 #include <IMP/Configuration.h>
18 #include <cereal/access.hpp>
19 #include <cereal/types/base_class.hpp>
20 
21 #include <boost/random/uniform_real_distribution.hpp>
22 
23 IMPCORE_BEGIN_NAMESPACE
24 
25 /** Allow code to test for the changes in MC interface.*/
26 #define IMP_CORE_HAS_MONTE_CARLO_MOVER 1
27 
28 //! A Monte Carlo optimizer.
29 /** The optimizer uses a set of Mover objects to propose steps. At
30  each sampling iteration, all Movers added to MonteCarlo are called to
31  generate a new proposed configuration.
32 
33  The movers propose some modification, which is then accepted or
34  rejected based on the Metropolis criterion. Optionally, a number
35  of local optimization steps are taken before the MonteCarlo step
36  is accepted or rejected.
37 
38  If you want to sequentially call one mover at every iteration, wrap
39  all movers into a SerialMover first, and then add the SerialMover to
40  MonteCarlo.
41 
42  By default, the lowest score state encountered is returned.
43 
44  \see Mover
45  */
46 class IMPCOREEXPORT MonteCarlo : public Optimizer {
47  public:
48  MonteCarlo(Model *m);
49 
50  MonteCarlo() : rand_(0, 1) {}
51 
52  protected:
53  ParticleIndexes reset_pis_;
54  virtual Float do_optimize(unsigned int max_steps) override;
56  public:
57  /** By default, the optimizer returns the lowest scoring state
58  found so far. If, instead, you wish to return the last accepted
59  state, set return best to false.
60  */
61  void set_return_best(bool tf) { return_best_ = tf; }
62 
63  bool get_return_best() const { return return_best_; }
64 
65  //! If set true (default false), only rescore moved particles
66  /** By default, on each move the score of the entire system is
67  calculated. If it is guaranteed that only Movers and ScoreStates
68  move the system, then the score can potentially be calculated
69  more quickly by caching the scores on parts of the system that
70  don't move. This is still experimental.
71 
72  \see IMP::ScoringFunction::evaluate_moved
73 
74  \note Some MonteCarlo subclasses do local optimization after each
75  move, which can move more particles than the Movers touched.
76  In this case the guarantee does not hold and this optimization
77  should probably not be used.
78  */
79  void set_score_moved(bool mv) { score_moved_ = mv; }
80 
81  /** \name kT
82  The kT value has to be on the same scale as the differences
83  in energy between good and bad states (and so the default is
84  likely to not be a good choice).
85  @{
86  */
87  void set_kt(Float t) {
88  IMP_INTERNAL_CHECK(t >= 0, "Temperature must not be negative");
89  temp_ = t;
90  }
91  Float get_kt() const { return temp_; }
92  /** @} */
93  //! Return the energy of the last accepted state.
94  double get_last_accepted_energy() const { return last_energy_; }
95 
96  void set_last_accepted_energy(double energy) { last_energy_ = energy; }
97 
98  //! If return best is on, returns the best energy found so far.
99  double get_best_accepted_energy() const {
100  IMP_USAGE_CHECK(return_best_, "Getting the best energy"
101  << " requires return best being on.");
102  return best_energy_;
103  }
104  void set_best_accepted_energy(double energy) { best_energy_ = energy; }
105 
106  /** \name Statistics
107  @{
108  */
109  //! Return how many times the optimizer has stepped to lower score
110  unsigned int get_number_of_downward_steps() const {
111  return stat_downward_steps_taken_;
112  }
113  //! Return how many times the optimizer has stepped to higher score
114  unsigned int get_number_of_upward_steps() const {
115  return stat_upward_steps_taken_;
116  }
117  //! Get number of proposed moves
118  unsigned int get_number_of_proposed_steps() const {
119  return stat_downward_steps_taken_ + stat_upward_steps_taken_ +
120  stat_num_failures_;
121  }
122  //! Get number of accepted moves
123  unsigned int get_number_of_accepted_steps() const {
124  return stat_downward_steps_taken_ + stat_upward_steps_taken_;
125  }
126  void set_number_of_downward_steps(unsigned int nsteps) {
127  stat_downward_steps_taken_ = nsteps;
128  }
129  void set_number_of_upward_steps(unsigned int nsteps) {
130  stat_upward_steps_taken_ = nsteps;
131  }
132  void set_number_of_rejected_steps(unsigned int nsteps) {
133  stat_num_failures_ = nsteps;
134  }
135  void reset_statistics() {
136  stat_downward_steps_taken_ = 0;
137  stat_upward_steps_taken_ = 0;
138  stat_num_failures_ = 0;
139  }
140 
141  /** @} */
142 
143  //! Set the score threshold.
144  //* An optimization is terminated if the score drops below this value. */
145  void set_score_threshold(double s) { min_score_ = s; }
146 
147  //! Get the score threshold.
148  double get_score_threshold() const { return min_score_; }
149 
150  /** Computations can be accelerated by throwing out
151  the tails of the distribution of accepted moves. To
152  do this, specify a maximum acceptable difference
153  between the before and after scores.
154  */
155  void set_maximum_difference(double d) { max_difference_ = d; }
156 
157  double get_maximum_difference() const { return max_difference_; }
158  /** @name Movers
159 
160  The following methods are used to manipulate the list of Movers.
161  Each mover is called at each optimization step, giving it a chance
162  to change the current configuration.
163  @{
164  */
165  IMP_LIST_ACTION(public, Mover, Movers, mover, movers, MonteCarloMover *,
166  MonteCarloMovers, {}, {}, {});
167  /** @} */
168 
169  protected:
170  /** Get all movable particles (those that can be moved by the current
171  movers.*/
172  ParticleIndexes get_movable_particles() const;
173  /** Note that if return best is true, this will save the current
174  state of the model. Also, if the move is accepted, the
175  optimizer states will be updated.
176  */
177  bool do_accept_or_reject_move(double score, double last,
178  const MonteCarloMoverResult &moved);
179 
180  bool do_accept_or_reject_move(double score,
181  const MonteCarloMoverResult &moved) {
182  return do_accept_or_reject_move(score, get_last_accepted_energy(), moved);
183  }
184 
185  MonteCarloMoverResult do_move();
186  //! a class that inherits from this should override this method
187  virtual void do_step();
188  //! Get the current energy
189  /** By default it just calls
190  Optimizer::get_scoring_function()->evaluate(false). However,
191  if an incremental scoring function is used, the list of moved
192  particles will be used to evaluate the score more efficiently.
193  Also, if there is a maximum allowed difference in scores
194  Optimizer::get_scoring_function()->evaluate_if_below()
195  will be called instead, allowing more efficient evaluation.
196  Classes which override this method should be similarly aware for
197  efficiency.
198 
199  The list of moved particles is passed.
200  */
201  virtual double do_evaluate(const ParticleIndexes &moved,
202  bool force_full_score) const {
203  if (get_maximum_difference() < NO_MAX) {
204  if (score_moved_ && !force_full_score) {
205  return get_scoring_function()->evaluate_moved_if_below(
206  false, moved, reset_pis_, last_energy_ + max_difference_);
207  } else {
208  return get_scoring_function()->evaluate_if_below(
209  false, last_energy_ + max_difference_);
210  }
211  } else {
212  if (score_moved_ && !force_full_score) {
213  return get_scoring_function()->evaluate_moved(false, moved, reset_pis_);
214  } else {
215  return get_scoring_function()->evaluate(false);
216  }
217  }
218  }
219 
220  private:
221  double temp_;
222  double last_energy_;
223  double best_energy_;
224  double max_difference_;
225  unsigned int stat_downward_steps_taken_;
226  unsigned int stat_upward_steps_taken_;
227  unsigned int stat_num_failures_;
228  bool return_best_;
229  bool score_moved_;
230  double min_score_;
232  ::boost::random::uniform_real_distribution<> rand_;
233 
234  friend class cereal::access;
235  template<class Archive> void serialize(Archive &ar) {
236  // don't serialize rand_ as it is constant (0, 1)
237  ar(cereal::base_class<Optimizer>(this), temp_, last_energy_, best_energy_,
238  max_difference_, stat_downward_steps_taken_, stat_upward_steps_taken_,
239  stat_num_failures_, return_best_, score_moved_, min_score_, best_,
240  mutable_access_movers());
241  }
242  IMP_OBJECT_SERIALIZE_DECL(MonteCarlo);
243 };
244 
245 //! This variant of Monte Carlo that relaxes after each move
246 class IMPCOREEXPORT MonteCarloWithLocalOptimization : public MonteCarlo {
248  unsigned int num_local_;
249 
250  public:
251  MonteCarloWithLocalOptimization(Optimizer *opt, unsigned int steps);
252 
253  unsigned int get_number_of_steps() const { return num_local_; }
254 
255  Optimizer *get_local_optimizer() const { return opt_; }
256 
257  protected:
258  virtual void do_step() override;
260 };
261 
262 //! This variant of Monte Carlo uses basis hopping
263 /** Basin hopping is where, after a move, a local optimizer is used to relax
264  the model before the energy computation. However, the pre-relaxation state
265  of the model is used as the starting point for the next step. The idea
266  is that models are accepted or rejected based on the score of the nearest
267  local minima, but they can still climb the barriers in between as the model
268  is not reset to the minima after each step.
269  */
270 class IMPCOREEXPORT MonteCarloWithBasinHopping
272  public:
273  MonteCarloWithBasinHopping(Optimizer *opt, unsigned int ns);
274 
275  protected:
276  virtual void do_step() override;
278 };
279 
280 IMPCORE_END_NAMESPACE
281 
282 #endif /* IMPCORE_MONTE_CARLO_H */
double get_kt(double T)
Return kT for a given temperature in units of [kcal/mol].
A Monte Carlo optimizer.
Definition: MonteCarlo.h:46
unsigned int get_number_of_upward_steps() const
Return how many times the optimizer has stepped to higher score.
Definition: MonteCarlo.h:114
double get_score_threshold() const
Get the score threshold.
Definition: MonteCarlo.h:148
const double NO_MAX
Use this value when you want to turn off maximum for restraint evaluation.
virtual double do_evaluate(const ParticleIndexes &moved, bool force_full_score) const
Get the current energy.
Definition: MonteCarlo.h:201
void set_maximum_difference(double d)
Definition: MonteCarlo.h:155
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
double get_last_accepted_energy() const
Return the energy of the last accepted state.
Definition: MonteCarlo.h:94
void set_score_moved(bool mv)
If set true (default false), only rescore moved particles.
Definition: MonteCarlo.h:79
Base class for all optimizers.
void set_score_threshold(double s)
Set the score threshold.
Definition: MonteCarlo.h:145
Macros to define containers of objects.
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
Definition: check_macros.h:139
virtual void do_step()
a class that inherits from this should override this method
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
This variant of Monte Carlo uses basis hopping.
Definition: MonteCarlo.h:270
unsigned int get_number_of_downward_steps() const
Return how many times the optimizer has stepped to lower score.
Definition: MonteCarlo.h:110
virtual double do_optimize(unsigned int ns)=0
override this function to do actual optimization
virtual void do_step() override
a class that inherits from this should override this method
Base class for all optimizers.
Definition: Optimizer.h:48
The base class for movers for Monte Carlo optimization.
unsigned int get_number_of_accepted_steps() const
Get number of accepted moves.
Definition: MonteCarlo.h:123
#define IMP_OBJECT_SERIALIZE_DECL(Name)
Declare methods needed for serialization of Object pointers.
Definition: object_macros.h:95
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:143
This variant of Monte Carlo that relaxes after each move.
Definition: MonteCarlo.h:246
double get_best_accepted_energy() const
If return best is on, returns the best energy found so far.
Definition: MonteCarlo.h:99
double evaluate_moved(bool derivatives, const ParticleIndexes &moved_pis, const ParticleIndexes &reset_pis)
Score when some particles have moved.
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:19
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Store a set of configurations of the model.
Functions to search over vectors.
double evaluate(bool derivatives)
Evaluate and return the score for the current state of the model.
unsigned int get_number_of_proposed_steps() const
Get number of proposed moves.
Definition: MonteCarlo.h:118
ScoringFunction * get_scoring_function() const
Return the scoring function that is being used.
Definition: Optimizer.h:106