00001
00002
00003
00004
00005
00006
00007 #ifndef IMPATOM_SMOOTHING_FUNCTIONS_H
00008 #define IMPATOM_SMOOTHING_FUNCTIONS_H
00009
00010 #include "atom_config.h"
00011
00012 #include <IMP/base_types.h>
00013 #include <IMP/Object.h>
00014
00015 IMPATOM_BEGIN_NAMESPACE
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 class IMPATOMEXPORT SmoothingFunction : public Object
00032 {
00033 public:
00034 SmoothingFunction();
00035
00036
00037
00038
00039 virtual double operator()(double score, double distance) const = 0;
00040
00041
00042
00043
00044
00045 virtual DerivativePair operator()(double score, double deriv,
00046 double distance) const = 0;
00047
00048 IMP_REF_COUNTED_DESTRUCTOR(SmoothingFunction);
00049 };
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 class IMPATOMEXPORT ForceSwitch : public SmoothingFunction
00075 {
00076 double min_distance_, max_distance_;
00077 double value_prefactor_, deriv_prefactor_;
00078
00079 inline double get_value(double distance) const {
00080 if (distance <= min_distance_) {
00081 return 1.0;
00082 } else if (distance > max_distance_) {
00083 return 0.0;
00084 } else {
00085 double d = max_distance_ - distance;
00086 return value_prefactor_ * d * d * (max_distance_ + 2.0 * distance
00087 - 3.0 * min_distance_);
00088 }
00089 }
00090
00091 inline double get_deriv(double distance) const {
00092 if (distance <= min_distance_ || distance > max_distance_) {
00093 return 0.0;
00094 } else {
00095 return deriv_prefactor_ * (max_distance_ - distance)
00096 * (min_distance_ - distance);
00097 }
00098 }
00099
00100 public:
00101 ForceSwitch(double min_distance, double max_distance)
00102 : min_distance_(min_distance), max_distance_(max_distance) {
00103 IMP_USAGE_CHECK(max_distance > min_distance,
00104 "max_distance should be greater than min_distance");
00105 double dist_dif = max_distance - min_distance;
00106 value_prefactor_ = 1.0 / (dist_dif * dist_dif * dist_dif);
00107 deriv_prefactor_ = 6.0 * value_prefactor_;
00108 }
00109
00110 double operator()(double score, double distance) const {
00111 double factor = get_value(distance);
00112 return score * factor;
00113 }
00114
00115 DerivativePair operator()(double score, double deriv, double distance) const {
00116 double factor = get_value(distance);
00117 double deriv_factor = get_deriv(distance);
00118 return std::make_pair(score * factor,
00119 score * deriv_factor + deriv * factor);
00120 }
00121
00122 IMP_OBJECT(ForceSwitch);
00123 };
00124
00125
00126 IMPATOM_END_NAMESPACE
00127
00128 #endif