IMP logo
IMP Reference Guide  develop.4eee3cf66f,2026/08/01
The Integrative Modeling Platform
AttributeOptimizer.h
Go to the documentation of this file.
1 /**
2  * \file IMP/AttributeOptimizer.h
3  * \brief Base class for optimizers that act on individual attributes.
4  *
5  * Copyright 2007-2026 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_ATTRIBUTE_OPTIMIZER_H
10 #define IMPKERNEL_ATTRIBUTE_OPTIMIZER_H
11 
12 #include <IMP/kernel_config.h>
13 #include "Optimizer.h"
14 #include <cereal/access.hpp>
15 #include <cereal/types/base_class.hpp>
16 
17 IMPKERNEL_BEGIN_NAMESPACE
18 
19 //! Base class for optimizers that act on individual attributes.
20 /** AttributeOptimizers optimize the collection of optimized
21  attributes (see Model::set_is_optimized()) in contrast to,
22  say molecular dynamics where the fundamental entity is a Particle.
23 */
24 class IMPKERNELEXPORT AttributeOptimizer : public Optimizer {
25  public:
26  AttributeOptimizer(Model *m, std::string name = "Optimizer %1%");
28 
29  protected:
30  /** @name Methods for getting and setting optimized attributes
31  Optimizers don't have to go through the particles themselves
32  looking for values to optimize unless they care about special
33  properties of the optimized values. Instead they can iterate
34  through the list of optimized attributes, each of which is
35  identified by a FloatIndex. With these FloatIndex objects
36  they can get and set the values and derivatives as needed.
37  */
38  //!@{
39  FloatIndexes get_optimized_attributes() const {
40  Model *m = get_model();
41  return m->get_optimized_attributes()
42  + m->internal::Vector3DDerivAttributeTable::get_optimized_vector_attributes()
43  + m->internal::Vector4DDerivAttributeTable::get_optimized_vector_attributes();
44  }
45  void set_value(FloatIndex fi, double v) const {
46  fi.set_value(get_model(), v);
47  }
48 
49  Float get_value(FloatIndex fi) const {
50  return fi.get_value(get_model());
51  }
52 
53  Float get_derivative(FloatIndex fi) const {
54  return fi.get_derivative(get_model());
55  }
56 
57  //!@}
58 
59  double get_width(FloatKey k) const {
60  if (widths_.size() <= k.get_index() || widths_[k.get_index()] == 0) {
61  FloatRange w = get_model()->get_range(k);
62  double wid = static_cast<double>(w.second) - w.first;
63  widths_.resize(std::max(widths_.size(), size_t(k.get_index() + 1)), 0.0);
64  if (wid > .0001) {
65  // double nwid= std::pow(2, std::ceil(log2(wid)));
66  widths_[k.get_index()] = wid;
67  } else {
68  widths_[k.get_index()] = 1.0;
69  }
70  }
71  return widths_[k.get_index()];
72  }
73 
74  /** @name Methods to get and set scaled optimizable values
75  Certain optimizers benefit from having all the optimized values
76  scaled to vary over a similar range. These accessors use the
77  Model::get_range ranges to scale the values before returning
78  them and unscale them before setting them.
79 
80  For now, Vector3D and Vector4D values are not scaled.
81  */
82  //{@
83  void set_scaled_value(FloatIndex fi, Float v) const {
84  FloatKey k = fi.get_float_key();
85  if (k == FloatKey()) {
86  set_value(fi, v);
87  } else {
88  double wid = get_width(k);
89  set_value(fi, v * wid);
90  }
91  }
92 
93  double get_scaled_value(FloatIndex fi) const {
94  double uv = get_value(fi);
95  FloatKey k = fi.get_float_key();
96  if (k == FloatKey()) {
97  return uv;
98  } else {
99  double wid = get_width(fi.get_float_key());
100  return uv / wid;
101  }
102  }
103 
104  double get_scaled_derivative(FloatIndex fi) const {
105  double uv = get_derivative(fi);
106  FloatKey k = fi.get_float_key();
107  if (k == FloatKey()) {
108  return uv;
109  } else {
110  double wid = get_width(fi.get_float_key());
111  return uv * wid;
112  }
113  }
114 
115  //! Clear the cache of range information. Do this at the start of
116  // optimization
117  void clear_range_cache() { widths_.clear(); }
118  //!@}
119  private:
120  mutable Floats widths_;
121 
122  friend class cereal::access;
123 
124  template<class Archive> void serialize(Archive &ar) {
125  ar(cereal::base_class<Optimizer>(this));
126  if (std::is_base_of<cereal::detail::InputArchiveBase, Archive>::value) {
127  clear_range_cache();
128  }
129  }
130 };
131 
133 
134 IMPKERNEL_END_NAMESPACE
135 
136 #endif /* IMPKERNEL_ATTRIBUTE_OPTIMIZER_H */
Key< 0 > FloatKey
The type used to identify float attributes in the Particles.
Definition: base_types.h:32
std::pair< Float, Float > FloatRange
A pair representing the allowed range for a Float attribute.
Definition: types.h:30
Base class for all optimizers.
Class for storing model, its restraints, constraints, and particles.
Definition: Model.h:86
Base class for all optimizers.
Definition: Optimizer.h:48
A FloatIndex identifies an optimized attribute in a model.
Definition: FloatIndex.h:25
#define IMP_OBJECTS(Name, PluralName)
Define the types for storing lists of object pointers.
Definition: object_macros.h:44
Base class for optimizers that act on individual attributes.
double Float
Basic floating-point value (could be float, double...)
Definition: types.h:19
void clear_range_cache()
Clear the cache of range information. Do this at the start of.