EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
interpolation_impl.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file interpolation_impl.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
11 #include <array>
12 
13 namespace Acts {
14 
15 namespace detail {
16 
36 template <typename Point1, typename Point2, typename Point3, typename Value>
38  template <typename C>
39  static auto value_type_test(C* c)
40  -> decltype(C(std::declval<double>() * std::declval<C>() +
41  std::declval<double>() * std::declval<C>()),
42  std::true_type());
43  template <typename C>
44  static std::false_type value_type_test(...);
45 
46  template <typename C>
47  static auto point_type_test(C* c)
48  -> decltype(double(std::declval<C>()[0]), std::true_type());
49  template <typename C>
50  static std::false_type point_type_test(...);
51 
52  static const bool value =
53  std::is_same<std::true_type,
54  decltype(value_type_test<Value>(nullptr))>::value and
55  std::is_same<std::true_type,
56  decltype(point_type_test<Point1>(nullptr))>::value and
57  std::is_same<std::true_type,
58  decltype(point_type_test<Point2>(nullptr))>::value and
59  std::is_same<std::true_type,
60  decltype(point_type_test<Point3>(nullptr))>::value;
61 };
62 
66 template <size_t N>
67 struct get_dimension {
69  static constexpr size_t value = get_dimension<(N >> 1)>::value + 1u;
70 };
71 
73 template <>
74 struct get_dimension<2u> {
75  static constexpr size_t value = 1u;
76 };
78 
97 template <typename T, class Point1, class Point2, class Point3, size_t D,
98  size_t N>
100 
102 // recursive implementation of linear interpolation in multiple dimensions
103 template <typename T, class Point1, class Point2, class Point3, size_t D,
104  size_t N>
105 struct interpolate_impl {
106  static T run(const Point1& pos, const Point2& lowerLeft,
107  const Point3& upperRight, const std::array<T, N>& fields) {
108  // get distance to lower boundary relative to total bin width
109  const double f = (pos[D] - lowerLeft[D]) / (upperRight[D] - lowerLeft[D]);
110 
111  std::array<T, (N >> 1)> newFields;
112  for (size_t i = 0; i < N / 2; ++i) {
113  newFields.at(i) = (1 - f) * fields.at(2 * i) + f * fields.at(2 * i + 1);
114  }
115 
116  return interpolate_impl<T, Point1, Point2, Point3, D - 1, (N >> 1)>::run(
117  pos, lowerLeft, upperRight, newFields);
118  }
119 };
120 
121 // simple linear interpolation in 1D
122 template <typename T, class Point1, class Point2, class Point3, size_t D>
123 struct interpolate_impl<T, Point1, Point2, Point3, D, 2u> {
124  static T run(const Point1& pos, const Point2& lowerLeft,
125  const Point3& upperRight, const std::array<T, 2u>& fields) {
126  // get distance to lower boundary relative to total bin width
127  const double f = (pos[D] - lowerLeft[D]) / (upperRight[D] - lowerLeft[D]);
128 
129  return (1 - f) * fields.at(0) + f * fields.at(1);
130  }
131 };
133 } // namespace detail
134 
135 } // namespace Acts