FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
interpolation_set.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2007-2008 Marc Brooker and Michael Inggs
4// Copyright (c) 2008-present FERS Contributors (see AUTHORS.md).
5//
6// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
7
8/**
9 * @file interpolation_set.cpp
10 * @brief Implementation file for interpolation of sets of data.
11 */
12
13#include "interpolation_set.h"
14
15#include <algorithm>
16#include <cmath>
17#include <cstddef>
18#include <iterator>
19#include <ranges>
20#include <stdexcept>
21
22namespace interp
23{
24 template <RealConcept T>
25 std::optional<T> InterpSetData::value(T x) const noexcept
26 {
27 if (_data.empty())
28 {
29 return std::nullopt;
30 }
31
32 const auto iter = _data.lower_bound(static_cast<double>(x));
33
34 if (iter == _data.begin())
35 {
36 return static_cast<T>(iter->second);
37 }
38 if (iter == _data.end())
39 {
40 const auto prev = std::prev(iter);
41 return static_cast<T>(prev->second);
42 }
43 if (iter->first == static_cast<double>(x))
44 {
45 return static_cast<T>(iter->second);
46 }
47
48 auto prev = std::prev(iter);
49 const auto [x1, y1] = *prev;
50 const auto [x2, y2] = *iter;
51
52 return static_cast<T>(y2 * (x - x1) / (x2 - x1) + y1 * (x2 - x) / (x2 - x1));
53 }
54
55 double InterpSetData::max() const noexcept
56 {
57 auto values = _data | std::views::values;
58
59 const auto max_element =
60 std::ranges::max_element(values, [](const double a, const double b) { return std::abs(a) < std::abs(b); });
61
62 return max_element != values.end() ? std::abs(*max_element) : 0.0;
63 }
64
65 template <RealConcept T>
67 {
68 if (a == 0)
69 {
70 throw std::invalid_argument("Division by zero is not allowed.");
71 }
72
73 std::ranges::for_each(_data | std::views::values, [a](auto& value) { value /= static_cast<double>(a); });
74 }
75
76 // Explicit instantiations for double and float
77 template std::optional<double> InterpSetData::value<double>(double) const noexcept;
78
79 template void InterpSetData::divide<double>(double);
80
81 template std::optional<float> InterpSetData::value<float>(float) const noexcept;
82
83 template void InterpSetData::divide<float>(float);
84}
double max() const noexcept
Retrieves the maximum absolute value in the interpolation set.
void divide(T a)
Divides all y-values in the dataset by a given number.
std::optional< T > value(T x) const noexcept
Retrieves the interpolated value at a given point.
Header file for the interpolation of sets of data.