IMP logo
IMP Reference Guide  develop.e004443c3b,2024/04/25
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-2022 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 
19 #include <boost/random/uniform_real.hpp>
20 
21 IMPCORE_BEGIN_NAMESPACE
22 
23 /** Allow code to test for the changes in MC interface.*/
24 #define IMP_CORE_HAS_MONTE_CARLO_MOVER 1
25 
26 //! A Monte Carlo optimizer.
27 /** The optimizer uses a set of Mover objects to propose steps. At
28  each sampling iteration, all Movers added to MonteCarlo are called to
29  generate a new proposed configuration.
30 
31  The movers propose some modification, which is then accepted or
32  rejected based on the Metropolis criterion. Optionally, a number
33  of local optimization steps are taken before the MonteCarlo step
34  is accepted or rejected.
35 
36  If you want to sequentially call one mover at every iteration, wrap
37  all movers into a SerialMover first, and then add the SerialMover to
38  MonteCarlo.
39 
40  By default, the lowest score state encountered is returned.
41 
42  \see Mover
43  */
44 class IMPCOREEXPORT MonteCarlo : public Optimizer {
45  public:
46  MonteCarlo(Model *m);
47 
48  protected:
49  ParticleIndexes reset_pis_;
50  virtual Float do_optimize(unsigned int max_steps) override;
52  public:
53  /** By default, the optimizer returns the lowest scoring state
54  found so far. If, instead, you wish to return the last accepted
55  state, set return best to false.
56  */
57  void set_return_best(bool tf) { return_best_ = tf; }
58 
59  //! If set true (default false), only rescore moved particles
60  /** By default, on each move the score of the entire system is
61  calculated. If it is guaranteed that only Movers and ScoreStates
62  move the system, then the score can potentially be calculated
63  more quickly by caching the scores on parts of the system that
64  don't move. This is still experimental.
65 
66  \see IMP::ScoringFunction::evaluate_moved
67 
68  \note Some MonteCarlo subclasses do local optimization after each
69  move, which can move more particles than the Movers touched.
70  In this case the guarantee does not hold and this optimization
71  should probably not be used.
72  */
73  void set_score_moved(bool mv) { score_moved_ = mv; }
74 
75  /** \name kT
76  The kT value has to be on the same scale as the differences
77  in energy between good and bad states (and so the default is
78  likely to not be a good choice).
79  @{
80  */
81  void set_kt(Float t) {
82  IMP_INTERNAL_CHECK(t >= 0, "Temperature must not be negative");
83  temp_ = t;
84  }
85  Float get_kt() const { return temp_; }
86  /** @} */
87  //! Return the energy of the last accepted state.
88  double get_last_accepted_energy() const { return last_energy_; }
89 
90  //! If return best is on, returns the best energy found so far.
91  double get_best_accepted_energy() const {
92  IMP_USAGE_CHECK(return_best_, "Getting the best energy"
93  << " requires return best being on.");
94  return best_energy_;
95  }
96  /** \name Statistics
97  @{
98  */
99  //! Return how many times the optimizer has stepped to lower score
100  unsigned int get_number_of_downward_steps() const {
101  return stat_downward_steps_taken_;
102  }
103  //! Return how many times the optimizer has stepped to higher score
104  unsigned int get_number_of_upward_steps() const {
105  return stat_upward_steps_taken_;
106  }
107  //! Get number of proposed moves
108  unsigned int get_number_of_proposed_steps() const {
109  return stat_downward_steps_taken_ + stat_upward_steps_taken_ +
110  stat_num_failures_;
111  }
112  //! Get number of accepted moves
113  unsigned int get_number_of_accepted_steps() const {
114  return stat_downward_steps_taken_ + stat_upward_steps_taken_;
115  }
116  void reset_statistics() {
117  stat_downward_steps_taken_ = 0;
118  stat_upward_steps_taken_ = 0;
119  stat_num_failures_ = 0;
120  }
121 
122  /** @} */
123 
124  //! Set the score threshold.
125  //* An optimization is terminated if the score drops below this value. */
126  void set_score_threshold(double s) { min_score_ = s; }
127 
128  //! Get the score threshold.
129  double get_score_threshold() const { return min_score_; }
130 
131  /** Computations can be accelerated by throwing out
132  the tails of the distribution of accepted moves. To
133  do this, specify a maximum acceptable difference
134  between the before and after scores.
135  */
136  void set_maximum_difference(double d) { max_difference_ = d; }
137 
138  double get_maximum_difference() const { return max_difference_; }
139  /** @name Movers
140 
141  The following methods are used to manipulate the list of Movers.
142  Each mover is called at each optimization step, giving it a chance
143  to change the current configuration.
144  @{
145  */
146  IMP_LIST_ACTION(public, Mover, Movers, mover, movers, MonteCarloMover *,
147  MonteCarloMovers, {}, {}, {});
148  /** @} */
149 
150  protected:
151  /** Get all movable particles (those that can be moved by the current
152  movers.*/
153  ParticleIndexes get_movable_particles() const;
154  /** Note that if return best is true, this will save the current
155  state of the model. Also, if the move is accepted, the
156  optimizer states will be updated.
157  */
158  bool do_accept_or_reject_move(double score, double last,
159  const MonteCarloMoverResult &moved);
160 
161  bool do_accept_or_reject_move(double score,
162  const MonteCarloMoverResult &moved) {
163  return do_accept_or_reject_move(score, get_last_accepted_energy(), moved);
164  }
165 
166  MonteCarloMoverResult do_move();
167  //! a class that inherits from this should override this method
168  virtual void do_step();
169  //! Get the current energy
170  /** By default it just calls
171  Optimizer::get_scoring_function()->evaluate(false). However,
172  if an incremental scoring function is used, the list of moved
173  particles will be used to evaluate the score more efficiently.
174  Also, if there is a maximum allowed difference in scores
175  Optimizer::get_scoring_function()->evaluate_if_below()
176  will be called instead, allowing more efficient evaluation.
177  Classes which override this method should be similarly aware for
178  efficiency.
179 
180  The list of moved particles is passed.
181  */
182  virtual double do_evaluate(const ParticleIndexes &moved,
183  bool force_full_score) const {
184  if (get_maximum_difference() < NO_MAX) {
185  if (score_moved_ && !force_full_score) {
186  return get_scoring_function()->evaluate_moved_if_below(
187  false, moved, reset_pis_, last_energy_ + max_difference_);
188  } else {
189  return get_scoring_function()->evaluate_if_below(
190  false, last_energy_ + max_difference_);
191  }
192  } else {
193  if (score_moved_ && !force_full_score) {
194  return get_scoring_function()->evaluate_moved(false, moved, reset_pis_);
195  } else {
196  return get_scoring_function()->evaluate(false);
197  }
198  }
199  }
200 
201  private:
202  double temp_;
203  double last_energy_;
204  double best_energy_;
205  double max_difference_;
206  unsigned int stat_downward_steps_taken_;
207  unsigned int stat_upward_steps_taken_;
208  unsigned int stat_num_failures_;
209  bool return_best_;
210  bool score_moved_;
211  double min_score_;
213  ::boost::uniform_real<> rand_;
214 };
215 
216 //! This variant of Monte Carlo that relaxes after each move
217 class IMPCOREEXPORT MonteCarloWithLocalOptimization : public MonteCarlo {
219  unsigned int num_local_;
220 
221  public:
222  MonteCarloWithLocalOptimization(Optimizer *opt, unsigned int steps);
223 
224  unsigned int get_number_of_steps() const { return num_local_; }
225 
226  Optimizer *get_local_optimizer() const { return opt_; }
227 
228  protected:
229  virtual void do_step() override;
231 };
232 
233 //! This variant of Monte Carlo uses basis hopping
234 /** Basin hopping is where, after a move, a local optimizer is used to relax
235  the model before the energy computation. However, the pre-relaxation state
236  of the model is used as the starting point for the next step. The idea
237  is that models are accepted or rejected based on the score of the nearest
238  local minima, but they can still climb the barriers in between as the model
239  is not reset to the minima after each step.
240  */
241 class IMPCOREEXPORT MonteCarloWithBasinHopping
243  public:
244  MonteCarloWithBasinHopping(Optimizer *opt, unsigned int ns);
245 
246  protected:
247  virtual void do_step() override;
249 };
250 
251 IMPCORE_END_NAMESPACE
252 
253 #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:44
unsigned int get_number_of_upward_steps() const
Return how many times the optimizer has stepped to higher score.
Definition: MonteCarlo.h:104
double get_score_threshold() const
Get the score threshold.
Definition: MonteCarlo.h:129
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:182
void set_maximum_difference(double d)
Definition: MonteCarlo.h:136
#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:88
void set_score_moved(bool mv)
If set true (default false), only rescore moved particles.
Definition: MonteCarlo.h:73
Base class for all optimizers.
void set_score_threshold(double s)
Set the score threshold.
Definition: MonteCarlo.h:126
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:241
unsigned int get_number_of_downward_steps() const
Return how many times the optimizer has stepped to lower score.
Definition: MonteCarlo.h:100
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:113
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:217
double get_best_accepted_energy() const
If return best is on, returns the best energy found so far.
Definition: MonteCarlo.h:91
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:108
ScoringFunction * get_scoring_function() const
Return the scoring function that is being used.
Definition: Optimizer.h:106