OpenMS
GridSearch.h
Go to the documentation of this file.
1 // Copyright (c) 2002-2023, The OpenMS Team -- EKU Tuebingen, ETH Zurich, and FU Berlin
2 // SPDX-License-Identifier: BSD-3-Clause
3 //
4 // --------------------------------------------------------------------------
5 // $Maintainer: Julianus Pfeuffer $
6 // $Authors: Julianus Pfeuffer $
7 // --------------------------------------------------------------------------
8 
9 #pragma once
10 
11 #include <array>
12 #include <vector>
13 #include <cmath>
14 #include <tuple>
15 
16 namespace OpenMS
17 {
18  namespace Internal
19  {
20  // The general class template
21  template <size_t param_index, size_t grid_size, typename EvalResult, typename Tuple, typename... TupleTypes>
22  struct Looper
23  {
24  };
25 
26  // Specialization for the base case
27  // - shape_index == shape_size
28  // - TupleTypes is empty here
29  // - All indices in Functor are bound (i.e. can be called with empty arguments)
30  template <size_t grid_size, typename EvalResult, typename Tuple, typename... TupleTypes>
31  struct Looper<grid_size, grid_size, EvalResult, Tuple, TupleTypes...>
32  {
33  template <typename Functor>
34  double operator()(const Tuple&, Functor functor, EvalResult /*bestValue*/, std::array<size_t, grid_size>& /*bestIndices*/)
35  {
36  return functor();
37  }
38  };
39 
40  // Specialization for the loop case
41  // - increment shape_index
42  // - create new Functor with one argument less and the first being bound to it
43  // - loop over all values in the current vector and update best score and best indices
44  template <size_t param_index, size_t grid_size, typename EvalResult, typename Tuple, typename FirstTupleType, typename... TupleTypes>
45  struct Looper<param_index, grid_size, EvalResult, Tuple, FirstTupleType, TupleTypes...>
46  {
47  template <typename Functor>
48  EvalResult operator()(const Tuple& grid, Functor functor, EvalResult bestValue, std::array<size_t, grid_size>& bestIndices)
49  {
50  for (size_t index = 0; index < std::get<param_index>(grid).size(); ++index)
51  {
52  double currVal = Looper<param_index + 1, grid_size, EvalResult, Tuple, TupleTypes...>()
53  (
54  grid,
55  [&grid, index, &functor](TupleTypes... rest){ return functor(std::get<param_index>(grid)[index], rest...);},
56  bestValue,
57  bestIndices
58  );
59 
60  if ( currVal > bestValue )
61  {
62  bestValue = currVal;
63  bestIndices[param_index] = index;
64  }
65  }
66  return bestValue;
67  }
68  };
69  } // namespace Internal
70 
71  template <typename... TupleTypes>
72  class GridSearch
73  {
74  public:
75  explicit GridSearch(std::vector<TupleTypes>... gridValues):
76  grid_(std::make_tuple<std::vector<TupleTypes>...>(std::move(gridValues)...))
77  {}
78 
79  //Specific implementation for function objects
80  template <typename Functor>
81  typename std::result_of<Functor(TupleTypes...)>::type evaluate(Functor evaluator,
82  typename std::result_of<Functor(TupleTypes...)>::type startValue,
83  std::array<size_t,std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value>& resultIndices)
84  {
85  return Internal::Looper<0,
86  std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value,
87  typename std::result_of<Functor(TupleTypes...)>::type,
88  std::tuple<std::vector<TupleTypes>...>,
89  TupleTypes...> ()
90  (grid_, evaluator, startValue, resultIndices);
91  }
92 
93 
94  //Specific implementation for function pointers
95  template <typename EvalResult>
96  EvalResult evaluate(EvalResult evaluator(TupleTypes...),
97  EvalResult startValue,
98  std::array<size_t,std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value>& resultIndices)
99  {
100  return Internal::Looper<0,
101  std::tuple_size<std::tuple<std::vector<TupleTypes>...>>::value,
102  EvalResult,
103  std::tuple<std::vector<TupleTypes>...>,
104  TupleTypes...>()
105  (grid_, evaluator, startValue, resultIndices);
106  }
107 
108 
109  unsigned int getNrCombos()
110  {
111  if (combos_ready_)
112  {
113  return combos_;
114  }
115  else
116  {
117  return nrCombos();
118  }
119  }
120 
121  private:
122  std::tuple<std::vector<TupleTypes>...> grid_;
123  unsigned int combos_ = 1;
124  bool combos_ready_ = false;
125 
126  template<std::size_t I = 0>
127  typename std::enable_if<I == sizeof...(TupleTypes), unsigned int>::type
129  {
130  combos_ready_ = true;
131  return combos_;
132  }
133 
134  template<std::size_t I = 0>
135  typename std::enable_if<I < sizeof...(TupleTypes), unsigned int>::type
136  nrCombos()
137  {
138  combos_ *= std::get<I>(grid_).size();
139  return nrCombos<I + 1>();
140  }
141  };
142 } // namespace OpenMS
143 
Definition: GridSearch.h:73
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:81
unsigned int getNrCombos()
Definition: GridSearch.h:109
std::tuple< std::vector< TupleTypes >... > grid_
Definition: GridSearch.h:122
unsigned int combos_
Definition: GridSearch.h:123
bool combos_ready_
Definition: GridSearch.h:124
EvalResult evaluate(EvalResult evaluator(TupleTypes...), EvalResult startValue, std::array< size_t, std::tuple_size< std::tuple< std::vector< TupleTypes >... >>::value > &resultIndices)
Definition: GridSearch.h:96
std::enable_if< I==sizeof...(TupleTypes), unsigned int >::type nrCombos()
Definition: GridSearch.h:128
GridSearch(std::vector< TupleTypes >... gridValues)
Definition: GridSearch.h:75
Main OpenMS namespace.
Definition: FeatureDeconvolution.h:22