OpenMS
GridSearch.h
Go to the documentation of this file.
1 // Copyright (c) 2002-present, OpenMS Inc. -- 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 #include <concepts>
16 #include <ranges>
17 #include <functional>
18 
19 namespace OpenMS
20 {
21  namespace Internal
22  {
23  template<typename F, typename... Args>
24  concept Evaluator = requires(F f, Args... args) {
25  { std::invoke(f, args...) } -> std::convertible_to<double>;
26  };
27 
28  // The general class template
29  template <size_t param_index, size_t grid_size, typename EvalResult, typename Tuple, typename... TupleTypes>
30  struct Looper
31  {
32  };
33 
34  // Specialization for the base case
35  template <size_t grid_size, typename EvalResult, typename Tuple, typename... TupleTypes>
36  struct Looper<grid_size, grid_size, EvalResult, Tuple, TupleTypes...>
37  {
38  template <typename Functor>
39  requires Evaluator<Functor, TupleTypes...>
40  constexpr auto operator()(const Tuple&, Functor functor, EvalResult /*bestValue*/, std::array<size_t, grid_size>& /*bestIndices*/) const
41  {
42  return std::invoke(functor);
43  }
44  };
45 
46  // Specialization for the loop case
47  template <size_t param_index, size_t grid_size, typename EvalResult, typename Tuple, typename FirstTupleType, typename... TupleTypes>
48  struct Looper<param_index, grid_size, EvalResult, Tuple, FirstTupleType, TupleTypes...>
49  {
50  template <typename Functor>
51  requires Evaluator<Functor, FirstTupleType, TupleTypes...>
52  constexpr auto operator()(const Tuple& grid, Functor functor, EvalResult bestValue, std::array<size_t, grid_size>& bestIndices) const
53  {
54  const auto& current_vector = std::get<param_index>(grid);
55 
56  for (size_t index = 0; index < current_vector.size(); ++index) {
57  const auto& value = current_vector[index];
58  auto currVal = Looper<param_index + 1, grid_size, EvalResult, Tuple, TupleTypes...>{}
59  (
60  grid,
61  [&value, &functor](TupleTypes... rest){
62  return std::invoke(functor, value, rest...);
63  },
64  bestValue,
65  bestIndices
66  );
67 
68  if (currVal > bestValue) {
69  bestValue = currVal;
70  bestIndices[param_index] = index;
71  }
72  }
73  return bestValue;
74  }
75  };
76  } // namespace Internal
77 
78  template <typename... TupleTypes>
79  class GridSearch
80  {
81  public:
82  explicit GridSearch(std::vector<TupleTypes>... gridValues)
83  : grid_(std::make_tuple<std::vector<TupleTypes>...>(std::move(gridValues)...))
84  {}
85 
86  // Implementation for function objects using concepts
87  template <typename Functor>
88  requires Internal::Evaluator<Functor, TupleTypes...>
89  constexpr auto evaluate(
90  Functor evaluator,
91  std::invoke_result_t<Functor, TupleTypes...> startValue,
92  std::array<size_t, std::tuple_size_v<std::tuple<std::vector<TupleTypes>...>>>& resultIndices) const
93  {
94  return Internal::Looper<
95  0,
96  std::tuple_size_v<std::tuple<std::vector<TupleTypes>...>>,
97  std::invoke_result_t<Functor, TupleTypes...>,
98  std::tuple<std::vector<TupleTypes>...>,
99  TupleTypes...>{}(grid_, evaluator, startValue, resultIndices);
100  }
101 
102  // Implementation for function pointers using concepts
103  template <typename EvalResult>
104  requires std::convertible_to<EvalResult, double>
105  [[nodiscard]] constexpr auto evaluate(
106  EvalResult (*evaluator)(TupleTypes...),
107  EvalResult startValue,
108  std::array<size_t, std::tuple_size_v<std::tuple<std::vector<TupleTypes>...>>>& resultIndices) const
109  {
110  return Internal::Looper<
111  0,
112  std::tuple_size_v<std::tuple<std::vector<TupleTypes>...>>,
113  EvalResult,
114  std::tuple<std::vector<TupleTypes>...>,
115  TupleTypes...>{}(grid_, evaluator, startValue, resultIndices);
116  }
117 
118  [[nodiscard]] constexpr auto getNrCombos() const -> unsigned int
119  {
120  if (combos_ready_) {
121  return combos_;
122  }
123  return calculateCombos();
124  }
125 
126  private:
127  std::tuple<std::vector<TupleTypes>...> grid_;
128  mutable unsigned int combos_ = 1;
129  mutable bool combos_ready_ = false;
130 
131  template<std::size_t I = 0>
132  [[nodiscard]] constexpr unsigned int calculateCombos() const
133  {
134  if constexpr (I == sizeof...(TupleTypes)) {
135  combos_ready_ = true;
136  return combos_;
137  } else {
138  combos_ *= std::get<I>(grid_).size();
139  return calculateCombos<I + 1>();
140  }
141  }
142  };
143 } // namespace OpenMS
Definition: GridSearch.h:80
requires constexpr std::convertible_to< EvalResult, double > auto evaluate(EvalResult(*evaluator)(TupleTypes...), EvalResult startValue, std::array< size_t, std::tuple_size_v< std::tuple< std::vector< TupleTypes >... >>> &resultIndices) const
Definition: GridSearch.h:105
std::tuple< std::vector< TupleTypes >... > grid_
Definition: GridSearch.h:127
constexpr unsigned int calculateCombos() const
Definition: GridSearch.h:132
requires constexpr Internal::Evaluator< Functor, TupleTypes... > auto evaluate(Functor evaluator, std::invoke_result_t< Functor, TupleTypes... > startValue, std::array< size_t, std::tuple_size_v< std::tuple< std::vector< TupleTypes >... >>> &resultIndices) const
Definition: GridSearch.h:89
unsigned int combos_
Definition: GridSearch.h:128
bool combos_ready_
Definition: GridSearch.h:129
constexpr auto getNrCombos() const -> unsigned int
Definition: GridSearch.h:118
GridSearch(std::vector< TupleTypes >... gridValues)
Definition: GridSearch.h:82
const double F
Definition: Constants.h:157
concept Evaluator
Definition: GridSearch.h:24
custom arguments to allow for looping calls
Definition: WizardHelper.h:47
Definition: GridSearch.h:31
Main OpenMS namespace.
Definition: openswathalgo/include/OpenMS/OPENSWATHALGO/DATAACCESS/ISpectrumAccess.h:19
requires constexpr Evaluator< Functor, TupleTypes... > auto operator()(const Tuple &, Functor functor, EvalResult, std::array< size_t, grid_size > &) const
Definition: GridSearch.h:40
requires constexpr Evaluator< Functor, FirstTupleType, TupleTypes... > auto operator()(const Tuple &grid, Functor functor, EvalResult bestValue, std::array< size_t, grid_size > &bestIndices) const
Definition: GridSearch.h:52