PPCKO: Principal Predictive Components for Estimating an Autoregressive Operator
 
Loading...
Searching...
No Matches
interp1D.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Andrea Enrico Franzoni (andreaenrico.franzoni@gmail.com)
2//
3// This file is part of PPCKO
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of PPCKO and associated documentation files (the PPCKO software), to deal
7// PPCKO without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of PPCKO, and to permit persons to whom PPCKO is
10// furnished to do so, subject to the following conditions:
11//
12// PPCKO IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17// OUT OF OR IN CONNECTION WITH PPCKO OR THE USE OR OTHER DEALINGS IN
18// PPCKO.
19
20#ifndef EXAMPLES_SRC_INTERP1D_INTERP1D_HPP_
21#define EXAMPLES_SRC_INTERP1D_INTERP1D_HPP_
22#include <algorithm>
23#include <array>
24#include <exception>
25#include <functional>
26#include <iterator>
27#include <limits>
28#include <type_traits>
29
36
37
38namespace apsc
39{
89template <typename RAIterator, typename Key, typename ExtractKey,
90 typename ExtractValue, typename CompareKey = std::less<Key>>
91auto
92interp1D(RAIterator const &begin, RAIterator const &end, Key const &keyVal,
93 ExtractKey const &extractKey, ExtractValue const &extractValue,
94 CompareKey const &comp = std::less<Key>())
95{
96 // I avoid users using wrong iterators
97 // A nice use of iterator_traits and iterator_tags
98 using category = typename std::iterator_traits<RAIterator>::iterator_category;
99 static_assert(std::is_same_v<category, std::bidirectional_iterator_tag> ||
100 std::is_same_v<category, std::random_access_iterator_tag>,
101 "Iterators must be (at least) bidirectional");
102 // I need at least two point for interpolating anything. This checks also that
103 // end is after begin!
104 if(std::distance(begin, end) < 1)
105 throw std::runtime_error(
106 "Interp1D: I need at least 2 points to interpolate!");
107
108 RAIterator a{begin};
109 RAIterator b{end};
110 // bisection
111 for(auto dis = std::distance(a, b); dis > 1;)
112 {
113 RAIterator c = std::next(a, dis / 2); // midpoint
114 if(comp(keyVal, extractKey(*c))) // keyVal on the left of c
115 b = c;
116 else // keyVal on the right of c or on c
117 a = c;
118 dis = std::distance(a, b); // recompute distance
119 }
121 b = std::next(a, 1); // get other end of interval
122 if(b == end) // complex situation I need to go back of 1
123 {
124 b = a;
125 std::advance(a, -1); // here I need bi-directionality!
126 }
127 const auto valueLeft = extractValue(*a);
128 const Key keyLeft = extractKey(*a);
129 const auto valueRight = extractValue(*b);
130 const Key keyRight = extractKey(*b);
131 const auto len = keyRight - keyLeft;
132 // I assume no nodes are repeated
133 const auto coeffRight = (keyVal - keyLeft) / len;
134 const auto coeffLeft = 1.0 - coeffRight;
135 return valueLeft * coeffLeft + valueRight * coeffRight;
136}
137
138} // namespace apsc
139
140#endif /* EXAMPLES_SRC_INTERP1D_INTERP1D_HPP_ */
auto interp1D(RAIterator const &begin, RAIterator const &end, Key const &keyVal, ExtractKey const &extractKey, ExtractValue const &extractValue, CompareKey const &comp=std::less< Key >())
Definition interp1D.hpp:92