IMP logo
IMP Reference Guide  2.19.0
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-2022 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 #include <IMP/object_macros.h>
16 
17 IMPATOM_BEGIN_NAMESPACE
18 
19 //! Base class for smoothing nonbonded interactions as a function of distance.
20 /** The class is given the score (and optionally its first derivative)
21  at a given distance and returns a smoothed form of the score.
22  Smoothing functions are used to avoid a discontinuity in the scoring
23  function and/or its derivatives at the cutoff distance (the distance
24  threshold used by IMP::core::ClosePairsFinder), as this can lead
25  to nonphysical motions of the system. They are used by physical scoring
26  functions that drop off slowly with distance, such as CoulombPairScore,
27  in combination with a ClosePairsFinder.
28 
29  Smoothing functions usually offset the score by a constant value
30  (a shift function) or smooth it from its normal value to zero over
31  a defined range (a switch function, such as ForceSwitch).
32  */
33 class IMPATOMEXPORT SmoothingFunction : public IMP::Object {
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 //! Smooth interaction scores by switching the derivatives (force switch).
53 /** This function leaves the scores unaffected for distances below or equal
54  to min_distance, returns zero for distances above max_distance, and between
55  the two thresholds smoothes the score such that its first derivatives drop
56  linearly, i.e. the score is simply multiplied by \f[
57  \begin{cases}
58  1 & d \leq d_{min} \
59  \frac{(d_{max} - d)^2 (d_{max} + 2d - 3d_{min})}
60  {(d_{max} - d_{min})^3} & d_{min} < d \leq d_{max} \
61  0 & d > d_{max}
62  \end{cases}
63  \f] where \f$d\f$ is the distance, and \f$d_{min}\f$ and \f$d_{max}\f$ are
64  the thresholds set in the ForceSwitch constructor.
65 
66  This behavior is roughly equivalent to CHARMM's force switch nonbonded
67  interaction smoothing (which is also the smoothing mechanism used
68  by MODELLER).
69 
70  \see CoulombPairScore
71  */
72 class IMPATOMEXPORT ForceSwitch : public SmoothingFunction {
73  double min_distance_, max_distance_;
74  double value_prefactor_, deriv_prefactor_;
75 
76  inline double get_value(double distance) const {
77  if (distance <= min_distance_) {
78  return 1.0;
79  } else if (distance > max_distance_) {
80  return 0.0;
81  } else {
82  double d = max_distance_ - distance;
83  return value_prefactor_ * d * d *
84  (max_distance_ + 2.0 * distance - 3.0 * min_distance_);
85  }
86  }
87 
88  inline double get_deriv(double distance) const {
89  if (distance <= min_distance_ || distance > max_distance_) {
90  return 0.0;
91  } else {
92  return deriv_prefactor_ * (max_distance_ - distance) *
93  (min_distance_ - distance);
94  }
95  }
96 
97  public:
98  ForceSwitch(double min_distance, double max_distance)
99  : min_distance_(min_distance), max_distance_(max_distance) {
100  IMP_USAGE_CHECK(max_distance > min_distance,
101  "max_distance should be greater than min_distance");
102  double dist_dif = max_distance - min_distance;
103  value_prefactor_ = 1.0 / (dist_dif * dist_dif * dist_dif);
104  deriv_prefactor_ = 6.0 * value_prefactor_;
105  }
106 
107  double operator()(double score, double distance) const override {
108  double factor = get_value(distance);
109  return score * factor;
110  }
111 
112  DerivativePair operator()(double score, double deriv,
113  double distance) const override {
114  double factor = get_value(distance);
115  double deriv_factor = get_deriv(distance);
116  return std::make_pair(score * factor,
117  score * deriv_factor + deriv * factor);
118  }
119 
121 };
122 
123 IMPATOM_END_NAMESPACE
124 
125 #endif /* IMPATOM_SMOOTHING_FUNCTIONS_H */
Helper macros for implementing IMP Objects.
Basic types used by IMP.
#define IMP_OBJECT_METHODS(Name)
Define the basic things needed by any Object.
Definition: object_macros.h:25
#define IMP_REF_COUNTED_DESTRUCTOR(Name)
Set up destructor for a ref counted object.
Common base class for heavy weight IMP objects.
Definition: Object.h:111
DerivativePair operator()(double score, double deriv, double distance) const override
Smooth the score and its first derivative at a given distance.
std::pair< double, double > DerivativePair
A pair representing a function value with its first derivative.
Definition: types.h:22
double operator()(double score, double distance) const override
Smooth the score at a given distance.
A shared base class to help in debugging and things.
#define IMP_USAGE_CHECK(expr, message)
A runtime test for incorrect usage of a class or method.
Definition: check_macros.h:168
Base class for smoothing nonbonded interactions as a function of distance.
Smooth interaction scores by switching the derivatives (force switch).