IMP  2.0.1
The Integrative Modeling Platform
smoothing_functions.h
Go to the documentation of this file.
1 /**
2  * \file IMP/atom/smoothing_functions.h
3  * \brief Classes to smooth nonbonded interactions
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  */
7 
8 #ifndef IMPATOM_SMOOTHING_FUNCTIONS_H
9 #define IMPATOM_SMOOTHING_FUNCTIONS_H
10 
11 #include <IMP/atom/atom_config.h>
12 
13 #include <IMP/base_types.h>
14 #include <IMP/Object.h>
15 
16 IMPATOM_BEGIN_NAMESPACE
17 
18 //! Base class for smoothing nonbonded interactions as a function of distance.
19 /** The class is given the score (and optionally its first derivative)
20  at a given distance and returns a smoothed form of the score.
21  Smoothing functions are used to avoid a discontinuity in the scoring
22  function and/or its derivatives at the cutoff distance (the distance
23  threshold used by IMP::core::ClosePairsFinder), as this can lead
24  to nonphysical motions of the system. They are used by physical scoring
25  functions that drop off slowly with distance, such as CoulombPairScore,
26  in combination with a ClosePairsFinder.
27 
28  Smoothing functions usually offset the score by a constant value
29  (a shift function) or smooth it from its normal value to zero over
30  a defined range (a switch function, such as ForceSwitch).
31  */
32 class IMPATOMEXPORT SmoothingFunction : public IMP::base::Object
33 {
34 public:
36 
37  //! Smooth the score at a given distance.
38  /** \return the smoothed score.
39  */
40  virtual double operator()(double score, double distance) const = 0;
41 
42  //! Smooth the score and its first derivative at a given distance.
43  /** \return a DerivativePair containing the smoothed score and its
44  first derivative.
45  */
46  virtual DerivativePair operator()(double score, double deriv,
47  double distance) const = 0;
48 
50 };
51 
52 
53 //! Smooth interaction scores by switching the derivatives (force switch).
54 /** This function leaves the scores unaffected for distances below or equal
55  to min_distance, returns zero for distances above max_distance, and between
56  the two thresholds smoothes the score such that its first derivatives drop
57  linearly, i.e. the score is simply multiplied by \f[
58  \left\{
59  \begin{array}{ll}
60  1 & d \leq d_{min} \\
61  \frac{(d_{max} - d)^2 (d_{max} + 2d - 3d_{min})}
62  {(d_{max} - d_{min})^3} & d_{min} < d \leq d_{max} \\
63  0 & d > d_{max} \\
64  \end{array}
65  \right.
66  \f] where \f$d\f$ is the distance, and \f$d_{min}\f$ and \f$d_{max}\f$ are
67  the thresholds set in the ForceSwitch constructor.
68 
69  This behavior is roughly equivalent to CHARMM's force switch nonbonded
70  interaction smoothing (which is also the smoothing mechanism used
71  by MODELLER).
72 
73  \see CoulombPairScore
74  */
75 class IMPATOMEXPORT ForceSwitch : public SmoothingFunction
76 {
77  double min_distance_, max_distance_;
78  double value_prefactor_, deriv_prefactor_;
79 
80  inline double get_value(double distance) const {
81  if (distance <= min_distance_) {
82  return 1.0;
83  } else if (distance > max_distance_) {
84  return 0.0;
85  } else {
86  double d = max_distance_ - distance;
87  return value_prefactor_ * d * d * (max_distance_ + 2.0 * distance
88  - 3.0 * min_distance_);
89  }
90  }
91 
92  inline double get_deriv(double distance) const {
93  if (distance <= min_distance_ || distance > max_distance_) {
94  return 0.0;
95  } else {
96  return deriv_prefactor_ * (max_distance_ - distance)
97  * (min_distance_ - distance);
98  }
99  }
100 
101 public:
102  ForceSwitch(double min_distance, double max_distance)
103  : min_distance_(min_distance), max_distance_(max_distance) {
104  IMP_USAGE_CHECK(max_distance > min_distance,
105  "max_distance should be greater than min_distance");
106  double dist_dif = max_distance - min_distance;
107  value_prefactor_ = 1.0 / (dist_dif * dist_dif * dist_dif);
108  deriv_prefactor_ = 6.0 * value_prefactor_;
109  }
110 
111  double operator()(double score, double distance) const {
112  double factor = get_value(distance);
113  return score * factor;
114  }
115 
116  DerivativePair operator()(double score, double deriv, double distance) const {
117  double factor = get_value(distance);
118  double deriv_factor = get_deriv(distance);
119  return std::make_pair(score * factor,
120  score * deriv_factor + deriv * factor);
121  }
122 
124 };
125 
126 
127 IMPATOM_END_NAMESPACE
128 
129 #endif /* IMPATOM_SMOOTHING_FUNCTIONS_H */