IMP  2.0.1
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-2013 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 "Mover.h"
13 #include "monte_carlo_macros.h"
15 #include <IMP/Optimizer.h>
16 #include <IMP/optimizer_macros.h>
17 #include <IMP/container_macros.h>
18 #include <IMP/internal/container_helpers.h>
20 #include <IMP/Configuration.h>
21 
22 #include <boost/random/uniform_real.hpp>
23 
24 IMPCORE_BEGIN_NAMESPACE
25 
26 /** Allow code to test for the changes in MC interface.*/
27 #define IMP_CORE_HAS_MONTE_CARLO_MOVER 1
28 
29 //! A Monte Carlo optimizer.
30 /** The optimizer uses a set of Mover objects to propose steps. Currently
31  each Mover is called at each Monte Carlo iteration. If you only want to
32  use one mover at a time, use a SerialMover.
33  The movers propose some modification, which is then
34  accepted or rejected based on the Metropolis criterion. Optionally, a
35  number of local optimization steps are taken before the MonteCarlo step
36  is accepted or rejected.
37 
38  By default, the lowest score state encountered is returned.
39 
40  \see Mover
41  */
42 class IMPCOREEXPORT MonteCarlo: public Optimizer
43 {
44 public:
45  MonteCarlo(Model *m=nullptr);
46 
47  protected:
48  virtual Float do_optimize(unsigned int max_steps);
50  public:
51  /** By default, the optimizer returns the lowest score state
52  found so far. If, instead, you wish to return the last accepted
53  state, set return best to false.
54  */
55  void set_return_best(bool tf) {
56  return_best_=tf;
57  }
58 
59  /** \name kT
60  The kT value has to be on the same scale as the differences
61  in energy between good and bad states (and so the default is
62  likely to not be a good choice).
63  @{
64  */
65  void set_kt(Float t) {
66  IMP_INTERNAL_CHECK(t>0, "Temperature must be positive");
67  temp_=t;
68  }
69  Float get_kt() const {
70  return temp_;
71  }
72  /** @} */
73  /** Return the energy of last accepted state.
74  */
75  double get_last_accepted_energy() const {
76  return last_energy_;
77  }
78 
79  /** If return best is on, you can get the best energy
80  found so far.*/
81  double get_best_accepted_energy() const {
82  IMP_USAGE_CHECK(return_best_, "Getting the best energy"
83  << " requires return best being on.");
84  return best_energy_;
85  }
86  /** \name Statistics
87  @{
88  */
89  //! Return how many times the optimizer has succeeded in taking a step
90  unsigned int get_number_of_forward_steps() const {
91  return stat_forward_steps_taken_;
92  }
93  //! Return how many times the optimizer has stepped to higher energy
94  unsigned int get_number_of_upward_steps() const {
95  return stat_upward_steps_taken_;
96  }
97  /** @} */
98 
99  /** Computations can be acceletating by throwing out
100  the tails of the distribution of accepted moves. To
101  do this, specific a maximum acceptable difference
102  between the before and after scores.
103  */
104  void set_maximum_difference(double d) {
105  max_difference_=d;
106  }
107 
108  double get_maximum_difference() const {
109  return max_difference_;
110  }
111  /** @name Movers
112 
113  The following methods are used to manipulate the list of Movers.
114  Each mover is called at each optimization step, giving it a chance
115  to change the current configuration.
116  @{
117  */
118  IMP_LIST_ACTION(public, Mover, Movers, mover, movers,
119  MonteCarloMover*,
121  {},{},{});
122  /** @} */
123 
124 
125  /** \name Incremental
126  Efficient evaluation of non-bonded list based restraints is
127  a bit tricky with incremental evaluation.
128  @{
129  */
130  /** Set whether to use incremental evaluate or evaluate all restraints
131  each time. This cannot be changed during optimization.
132  */
133  void set_incremental_scoring_function(IncrementalScoringFunction *isf);
134  bool get_use_incremental_scoring_function() const {
135  return isf_;
136  }
137  IncrementalScoringFunction* get_incremental_scoring_function() const {
138  return isf_;
139  }
140  /** @} */
141  protected:
142  /** Get all movable particles (those that can be moved by the current
143  movers.*/
144  ParticleIndexes get_movable_particles() const;
145  /** Note that if return best is true, this will save the current
146  state of the model. Also, if the move is accepted, the
147  optimizer states will be updated.
148  */
149  bool do_accept_or_reject_move(double score, double last,
150  double proposal_ratio);
151  bool do_accept_or_reject_move(double score, double proposal_ratio)
152  {
153  return do_accept_or_reject_move(score, get_last_accepted_energy(),
154  proposal_ratio);
155  }
156 
157  MonteCarloMoverResult do_move();
158  //! a class that inherits from this should override this method
159  virtual void do_step();
160  //! Get the current energy
161  /** By default it just calls
162  Optimizer::get_scoring_function()->evaluate(false). However,
163  if an incremental scoring function is used, the list of moved
164  particles will be used to evaluate the score more efficiently.
165  Also, if there is a maximum allowed difference in scores
166  Optimizer::get_scoring_function()->evaluate_if_below()
167  will be called instead, allowing more efficient evaluation.
168  Classes which override this method should be similarly aware for
169  efficiency.
170 
171  The list of moved particles is passed.
172  */
173  virtual double do_evaluate(const ParticleIndexes &moved) const {
174  IMP_UNUSED(moved);
175  if (isf_ ) {
176  isf_->set_moved_particles(moved);
177  }
178  if (get_maximum_difference() < NO_MAX) {
179  return get_scoring_function()
180  ->evaluate_if_below(false, last_energy_+max_difference_);
181  } else {
182  return get_scoring_function()
183  ->evaluate(false);
184  }
185  }
186 private:
187  double temp_;
188  double last_energy_;
189  double best_energy_;
190  double max_difference_;
191  unsigned int stat_forward_steps_taken_;
192  unsigned int stat_upward_steps_taken_;
193  unsigned int stat_num_failures_;
194  bool return_best_;
195  IMP::OwnerPointer<Configuration> best_;
196  ::boost::uniform_real<> rand_;
197 
198  Pointer<IncrementalScoringFunction> isf_;
199 };
200 
201 
202 
203 //! This variant of Monte Carlo that relaxes after each move
204 class IMPCOREEXPORT MonteCarloWithLocalOptimization: public MonteCarlo
205 {
206  IMP::OwnerPointer<Optimizer> opt_;
207  unsigned int num_local_;
208 public:
210  unsigned int steps);
211 
212  unsigned int get_number_of_steps() const {
213  return num_local_;
214  }
215 
216  Optimizer* get_local_optimizer() const {
217  return opt_;
218  }
219 
220  protected:
221  virtual void do_step() IMP_OVERRIDE;
223 };
224 
225 //! This variant of Monte Carlo uses basis hopping
226 /** Basin hopping is where, after a move, a local optimizer is used to relax
227  the model before the energy computation. However, the pre-relaxation state
228  of the model is used as the starting point for the next step. The idea
229  is that models are accepted or rejected based on the score of the nearest
230  local minima, but they can still climb the barriers in between as the model
231  is not reset to the minima after each step.
232  */
233 class IMPCOREEXPORT MonteCarloWithBasinHopping:
235 {
236 public:
237  MonteCarloWithBasinHopping(Optimizer *opt, unsigned int ns);
238 
239  protected:
240  virtual void do_step() IMP_OVERRIDE;
242 };
243 
244 
245 IMPCORE_END_NAMESPACE
246 
247 #endif /* IMPCORE_MONTE_CARLO_H */