SourceXtractorPlusPlus  0.15
Please provide a description of the project.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DependentParameter.h
Go to the documentation of this file.
1 
23 #ifndef MODELFITTING_DEPENDENTPARAMETER_H
24 #define MODELFITTING_DEPENDENTPARAMETER_H
25 
26 #include <array>
27 #include <vector>
28 #include <memory>
30 
31 namespace ModelFitting {
32 
47 template<typename... Parameters>
49 
50 public:
51 
52  static constexpr int PARAM_NO = sizeof...(Parameters);
53 
55 
60  DependentParameter(ValueCalculator calculator, Parameters... parameters)
61  : BasicParameter {calculator(parameters->getValue()...)},
62  m_calculator {new ValueCalculator{std::move(calculator)}},
64  inputParameterLoop(parameters...);
65  //m_get_value_hook = std::bind(&DependentParameter::getValueHook, this);
66  }
67 
68  virtual ~DependentParameter() = default;
69 
70  double getValue() const override {
71  if (!this->isObserved()) {
72  const_cast<DependentParameter*>(this)->update((*m_params)[0]->getValue());
73  }
74  return m_value;
75  }
76 
77 private:
78 
81 
82  // Array of the input parameter
84 
85  /* The two following methods represent the mechanism to loop over
86  * the arbitrary number of variadic elements, the first one is called
87  * as long as there is more than one elements in the list and the
88  * second one is called when there is only one left.
89  */
90  template<typename First, typename ... Rest>
91  void inputParameterLoop(First& first, Rest&... rest) {
92  addParameterObserver(PARAM_NO - sizeof...(rest) - 1, first);
93  inputParameterLoop(rest...);
94  }
95 
96  template<typename Last>
97  void inputParameterLoop(Last& last) {
98  addParameterObserver(PARAM_NO - 1, last);
99  }
100 
101  /* The two update methods below are called by the observer function
102  * passed to the param.addObserver() method. They are used to transform
103  * the array of input parameter values to a series of doubles
104  * (val1, val2, ...) which is require to call the setValue (of the
105  * BasicParameter class)
106  */
107  template <typename... ParamValues>
108  void update(ParamValues... values) {
109  update(values..., (*m_params)[sizeof...(values)]->getValue());
110  }
111 
112  void update(decltype(std::declval<Parameters>()->getValue())... values) {
113  /* Beware that it is the updated value (m_calculator(values...)) that
114  * is passed to the setValue
115  */
116  BasicParameter::setValue((*m_calculator)(values...));
117  }
118 
119  template<typename Param>
120  void addParameterObserver(int i, Param& param) {
121  param->addObserver([this](double v){
122  // Do not bother updating live if there are no observers
123  if (this->isObserved()) {
124  this->update((*m_params)[0]->getValue());
125  }
126  });
127  }
128 };
129 
130 template<typename ... Parameters>
132  typename DependentParameter<Parameters...>::ValueCalculator value_calculator, Parameters... parameters) {
133  return std::make_shared<DependentParameter<Parameters...>>(value_calculator, parameters...);
134 }
135 
136 }
137 
138 #endif /* MODELFITTING_DEPENDENTPARAMETER_H */
void update(decltype(std::declval< Parameters >() ->getValue())...values)
Implementation of a parameter depending on an arbitrary number of other parameters.
The parameter base class.
void update(ParamValues...values)
std::shared_ptr< ValueCalculator > m_calculator
function to calculate the dependent parameter value
void addParameterObserver(int i, Param &param)
virtual void setValue(const double new_value)
std::shared_ptr< DependentParameter< Parameters...> > createDependentParameter(typename DependentParameter< Parameters...>::ValueCalculator value_calculator, Parameters...parameters)
double getValue() const override
std::shared_ptr< std::array< std::shared_ptr< BasicParameter >, PARAM_NO > > m_params
virtual ~DependentParameter()=default
std::function< double(decltype(std::declval< Parameters >() ->getValue())...)> ValueCalculator
T move(T...args)
T make_shared(T...args)
STL class.
void inputParameterLoop(First &first, Rest &...rest)
DependentParameter(ValueCalculator calculator, Parameters...parameters)