OpenMS  2.4.0
GridSearch.h
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
2 // OpenMS -- Open-Source Mass Spectrometry
3 // --------------------------------------------------------------------------
4 // Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
5 // ETH Zurich, and Freie Universitaet Berlin 2002-2017.
6 //
7 // This software is released under a three-clause BSD license:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of any author or any participating institution
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 // For a full list of authors, refer to the file AUTHORS.
17 // --------------------------------------------------------------------------
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
22 // INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // --------------------------------------------------------------------------
31 // $Maintainer: Julianus Pfeuffer $
32 // $Authors: Julianus Pfeuffer $
33 // --------------------------------------------------------------------------
34 
35 #ifndef OPENMS_MATH_MISC_GRIDSEARCH_H
36 #define OPENMS_MATH_MISC_GRIDSEARCH_H
37 
38 #include <array>
39 #include <iostream>
40 #include <vector>
41 #include <cmath>
42 #include <tuple>
43 
44 // The general class template
45 template <size_t param_index, size_t grid_size, typename EvalResult, typename Tuple, typename... TupleTypes>
46 struct Looper
47 {
48 };
49 
50 // Specialization for the base case
51 // - shape_index == shape_size
52 // - TupleTypes is empty here
53 // - All indices in Functor are bound (i.e. can be called with empty arguments)
54 template <size_t grid_size, typename EvalResult, typename Tuple, typename... TupleTypes>
55 struct Looper<grid_size, grid_size, EvalResult, Tuple, TupleTypes...>
56 {
57  template <typename Functor>
58  double operator()(const Tuple&, Functor functor, EvalResult /*bestValue*/, std::array<size_t, grid_size>& /*bestIndices*/)
59  {
60  return functor();
61  }
62 };
63 
64 // Specialization for the loop case
65 // - increment shape_index
66 // - create new Functor with one argument less and the first being bound to it
67 // - loop over all values in the current vector and update best score and best indices
68 template <size_t param_index, size_t grid_size, typename EvalResult, typename Tuple, typename FirstTupleType, typename... TupleTypes>
69 struct Looper<param_index, grid_size, EvalResult, Tuple, FirstTupleType, TupleTypes...>
70 {
71  template <typename Functor>
72  EvalResult operator()(const Tuple& grid, Functor functor, EvalResult bestValue, std::array<size_t, grid_size>& bestIndices)
73  {
74  for (size_t index = 0; index < std::get<param_index>(grid).size(); ++index)
75  {
76  double currVal = Looper<param_index + 1, grid_size, EvalResult, Tuple, TupleTypes...>()
77  (
78  grid,
79  [&grid, index, &functor](TupleTypes... rest){ return functor(std::get<param_index>(grid)[index], rest...);},
80  bestValue,
81  bestIndices
82  );
83 
84  if ( currVal > bestValue )
85  {
86  bestValue = currVal;
87  bestIndices[param_index] = index;
88  }
89  }
90  return bestValue;
91  }
92 };
93 
94 
95 
96 template <typename... TupleTypes>
98 {
99 public:
100  explicit GridSearch(std::vector<TupleTypes>... gridValues):
101  grid_(std::make_tuple<std::vector<TupleTypes>...>(std::move(gridValues)...))
102  {}
103 
104  //Specific implementation for function objects
105  template <typename Functor>
106  typename std::result_of<Functor(TupleTypes...)>::type evaluate(Functor evaluator,
107  typename std::result_of<Functor(TupleTypes...)>::type startValue,
108  std::array<size_t,std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value>& resultIndices)
109  {
110  return Looper<0,
111  std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value,
112  typename std::result_of<Functor(TupleTypes...)>::type,
113  std::tuple<std::vector<TupleTypes>...>,
114  TupleTypes...> ()
115  (grid_, evaluator, startValue, resultIndices);
116  }
117 
118 
119  //Specific implementation for function pointers
120  template <typename EvalResult>
121  EvalResult evaluate(EvalResult evaluator(TupleTypes...),
122  EvalResult startValue,
123  std::array<size_t,std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value>& resultIndices)
124  {
125  return Looper<0,
126  std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value,
127  EvalResult,
128  std::tuple<std::vector<TupleTypes>...>,
129  TupleTypes...>()
130  (grid_, evaluator, startValue, resultIndices);
131  }
132 
133 
134  unsigned int getNrCombos()
135  {
136  if (combos_ready_)
137  {
138  return combos_;
139  }
140  else
141  {
142  return nrCombos();
143  }
144  }
145 
146 private:
147  std::tuple<std::vector<TupleTypes>...> grid_;
148  unsigned int combos_ = 1;
149  bool combos_ready_ = false;
150 
151  template<std::size_t I = 0>
152  typename std::enable_if<I == sizeof...(TupleTypes), unsigned int>::type
154  {
155  combos_ready_ = true;
156  return combos_;
157  }
158 
159  template<std::size_t I = 0>
160  typename std::enable_if<I < sizeof...(TupleTypes), unsigned int>::type
161  nrCombos()
162  {
163  combos_ *= std::get<I>(grid_).size();
164  return nrCombos<I + 1>();
165  }
166 };
167 
168 
169 /* Example
170  double evaluator(double i, std::string j, double k, double l)
171  {
172  return i+j.length()+k+l;
173  }
174 
175  // Program
176  double wrongevaluator(std::string i, std::string j, double k, double l)
177  {
178  return i.length()+j.length()+k+l;
179  }
180 
181 
182  struct Evaluator
183  {
184  double operator()(double i, std::string j, double k, double l){return i+j.length()+k+l;};
185  };
186 
187  int main() {
188  GridSearch<double, std::string, double, double> gs({1,3,5,2},{"foo","barz"},{2},{3});
189  std::array<size_t, 4> bestParamIdx{{0u,0u,0u,0u}};
190  std::cout << "Best value " << gs.evaluate(wrongevaluator, -1.0, bestParamIdx) << " at: ";
191  for (auto idx : bestParamIdx)
192  {
193  std::cout << idx << ", ";
194  }
195  }
196 }*/
197 
198 #endif //OPENMS_MATH_MISC_GRIDSEARCH_H
unsigned int getNrCombos()
Definition: GridSearch.h:134
bool combos_ready_
Definition: GridSearch.h:149
unsigned int combos_
Definition: GridSearch.h:148
Definition: GridSearch.h:97
STL namespace.
EvalResult evaluate(EvalResult evaluator(TupleTypes...), EvalResult startValue, std::array< size_t, std::tuple_size< std::tuple< std::vector< TupleTypes >... >>::value > &resultIndices)
Definition: GridSearch.h:121
GridSearch(std::vector< TupleTypes >... gridValues)
Definition: GridSearch.h:100
std::result_of< Functor(TupleTypes...)>::type evaluate(Functor evaluator, typename std::result_of< Functor(TupleTypes...)>::type startValue, std::array< size_t, std::tuple_size< std::tuple< std::vector< TupleTypes >... >>::value > &resultIndices)
Definition: GridSearch.h:106
double operator()(const Tuple &, Functor functor, EvalResult, std::array< size_t, grid_size > &)
Definition: GridSearch.h:58
std::tuple< std::vector< TupleTypes >... > grid_
Definition: GridSearch.h:147
EvalResult operator()(const Tuple &grid, Functor functor, EvalResult bestValue, std::array< size_t, grid_size > &bestIndices)
Definition: GridSearch.h:72
Definition: GridSearch.h:46
std::enable_if< I==sizeof...(TupleTypes), unsigned int >::type nrCombos()
Definition: GridSearch.h:153