Vectorize.h
1 //-*-C++-*-
2 /***************************************************************************
3  *
4  * Copyright (C) 2011 by Willem van Straten
5  * Licensed under the Academic Free License version 2.1
6  *
7  ***************************************************************************/
8 
9 /* psrchive/More/MEAL/MEAL/Vectorize.h */
10 
11 #ifndef __Vectorize_H
12 #define __Vectorize_H
13 
14 #include "MEAL/ScalarVector.h"
15 #include "MEAL/Convert.h"
16 #include "Error.h"
17 
18 template<class Container, class Element = double> struct ScalarMapping;
19 
20 namespace MEAL {
21 
23  template<class T, class Map = ScalarMapping<typename T::Result> >
24  class Vectorize : public Convert<T,ScalarVector>
25  {
26  public:
27 
28  typedef typename T::Result Result;
29 
31  Vectorize (T* function);
32 
34  std::string get_name () const
35  { return "Vectorize<" + this->get_model()->get_name() + ">"; }
36 
38  unsigned size () const;
39 
40  private:
41 
43  void calculate (double& result, std::vector<double>* gradient);
44 
46  Map map;
47  };
48 
49  template<class T>
50  Vectorize<T>* vectorize (T* function) { return new Vectorize<T>(function); }
51 }
52 
53 
55 template<class T, class Element> struct ScalarMapping
56 {
57  typedef DatumTraits< typename DatumTraits<T>::element_type > SubTraits;
58 
59  static inline unsigned ndim ()
60  {
61  return DatumTraits<T>::ndim() * SubTraits::ndim();
62  }
63 
64  static inline Element element (const T& t, unsigned idim)
65  {
66  const unsigned index = idim / SubTraits::ndim();
67  const unsigned sub_index = idim % SubTraits::ndim();
68  return SubTraits::element( DatumTraits<T>::element(t, index), sub_index );
69  }
70 };
71 
73 template<>
74 struct ScalarMapping<double>
75 {
76  static inline unsigned ndim () { return 1; }
77  static inline double element (const double& x, unsigned idim) { return x; }
78 };
79 
80 template<class T, class M>
82 {
83  this->set_model (function);
84 }
85 
86 template<class T, class M>
87 void MEAL::Vectorize<T,M>::calculate (double& result,
88  std::vector<double>* gradient)
89 {
90  unsigned index = this->get_index();
91 
92  if (index >= size())
93  throw Error (InvalidState,
94  "MEAL::Vectorize<" + std::string(T::Name) + ">::calculate",
95  "index=%u >= size=%u", index, size());
96 
97  Result m_result;
98  std::vector<Result> m_gradient;
99  std::vector<Result>* m_gradptr = &m_gradient;
100  if (!gradient)
101  m_gradptr = 0;
102 
103  if (this->get_verbose())
104  std::cerr << get_name() + "::calculate call evaluate" << std::endl;
105 
106  m_result = this->get_model()->evaluate (m_gradptr);
107 
108  //ScalarMapping<Result> map;
109 
110  if (this->get_verbose())
111  std::cerr << get_name() + "::calculate index=" << this->get_index() << std::endl;
112 
113  result = map.element( m_result, index );
114 
115  if (!gradient)
116  return;
117 
118  if (this->get_verbose())
119  std::cerr << get_name() + "::calculate map gradient" << std::endl;
120 
121  gradient->resize( m_gradient.size() );
122  for (unsigned i=0; i<m_gradient.size(); i++)
123  (*gradient)[i] = map.element( m_gradient[i], index );
124 
125  if (this->get_verbose())
126  std::cerr << get_name() + "::calculate return" << std::endl;
127 }
128 
130 template<class T, class M>
131 unsigned MEAL::Vectorize<T,M>::size () const
132 {
133  return map.ndim(); // ScalarMapping<Result>::ndim();
134 }
135 
136 #endif
Converts a higher dimensional function into a ScalarVector.
Definition: Vectorize.h:24
This recursive template completely unrolls multi-dimensional objects.
Definition: Vectorize.h:18
Convert a function to another type.
Definition: Convert.h:24
Namespace in which all modeling and calibration related code is declared.
Definition: ExampleComplex2.h:16
Vectorize(T *function)
Default contructor.
Definition: Vectorize.h:81
unsigned size() const
Return the dimension of the vector.
Definition: Vectorize.h:131
T * get_model()
Get the function to be converted.
Definition: Convert.h:42
std::string get_name() const
Return the name of the class.
Definition: Vectorize.h:34

Generated using doxygen 1.8.17