File indexing completed on 2025-09-17 08:54:11
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <cmath>
0010 #include <cstddef>
0011 #include <iostream>
0012 #include <type_traits>
0013 #include <variant>
0014
0015 #include <covfie/core/concepts.hpp>
0016 #include <covfie/core/definitions.hpp>
0017 #include <covfie/core/parameter_pack.hpp>
0018 #include <covfie/core/qualifiers.hpp>
0019 #include <covfie/core/utility/binary_io.hpp>
0020 #include <covfie/core/vector.hpp>
0021
0022 namespace covfie::backend {
0023 template <
0024 concepts::field_backend _backend_t,
0025 concepts::vector_descriptor _input_vector_d = covfie::vector::
0026 vector_d<float, _backend_t::contravariant_input_t::dimensions>>
0027 struct nearest_neighbour {
0028 using this_t = nearest_neighbour<_backend_t, _input_vector_d>;
0029 static constexpr bool is_initial = false;
0030
0031 using backend_t = _backend_t;
0032
0033 static_assert(
0034 std::is_floating_point_v<typename _input_vector_d::type>,
0035 "Nearest neighbour interpolation contravariant input must have a "
0036 "floating point scalar type."
0037 );
0038 static_assert(
0039 _input_vector_d::size == backend_t::contravariant_input_t::dimensions,
0040 "Nearest neighbour interpolation contravariant input must have the "
0041 "same size as the backend contravariant input."
0042 );
0043
0044 using contravariant_input_t =
0045 covfie::vector::array_vector_d<_input_vector_d>;
0046 using contravariant_output_t = typename backend_t::contravariant_input_t;
0047 using covariant_input_t = typename backend_t::covariant_output_t;
0048 using covariant_output_t = covariant_input_t;
0049
0050 using configuration_t = std::monostate;
0051
0052 static constexpr uint32_t IO_MAGIC_HEADER = 0xAB020007;
0053
0054 struct owning_data_t {
0055 using parent_t = this_t;
0056
0057 owning_data_t() = default;
0058 owning_data_t(const owning_data_t &) = default;
0059 owning_data_t(owning_data_t &&) = default;
0060 owning_data_t & operator=(const owning_data_t &) = default;
0061 owning_data_t & operator=(owning_data_t &&) = default;
0062
0063 template <typename... Args>
0064 explicit owning_data_t(parameter_pack<configuration_t, Args...> && args)
0065 : m_backend(std::move(args.xs))
0066 {
0067 }
0068
0069 explicit owning_data_t(parameter_pack<owning_data_t> && conf)
0070 : owning_data_t(std::move(conf.x))
0071 {
0072 }
0073
0074 template <typename T>
0075 requires(std::same_as<
0076 typename T::parent_t::configuration_t,
0077 std::monostate>) explicit owning_data_t(const T & o)
0078 : m_backend(o.get_backend())
0079 {
0080 }
0081
0082 explicit owning_data_t(
0083 const configuration_t &, typename backend_t::owning_data_t && b
0084 )
0085 : m_backend(std::forward<typename backend_t::owning_data_t>(b))
0086 {
0087 }
0088
0089 typename backend_t::owning_data_t & get_backend(void)
0090 {
0091 return m_backend;
0092 }
0093
0094 const typename backend_t::owning_data_t & get_backend(void) const
0095 {
0096 return m_backend;
0097 }
0098
0099 configuration_t get_configuration(void) const
0100 {
0101 return {};
0102 }
0103
0104 static owning_data_t read_binary(std::istream & fs)
0105 {
0106 auto be = backend_t::owning_data_t::read_binary(fs);
0107
0108 return owning_data_t(configuration_t{}, std::move(be));
0109 }
0110
0111 static void write_binary(std::ostream & fs, const owning_data_t & o)
0112 {
0113 backend_t::owning_data_t::write_binary(fs, o.m_backend);
0114 }
0115
0116 typename backend_t::owning_data_t m_backend;
0117 };
0118
0119 struct non_owning_data_t {
0120 using parent_t = this_t;
0121
0122 non_owning_data_t(const owning_data_t & src)
0123 : m_backend(src.m_backend)
0124 {
0125 }
0126
0127 COVFIE_HOST_DEVICE typename covariant_output_t::vector_t
0128 at(typename contravariant_input_t::vector_t c) const
0129 {
0130 typename contravariant_output_t::vector_t nc;
0131
0132 for (std::size_t i = 0; i < contravariant_output_t::dimensions; ++i)
0133 {
0134 nc[i] = static_cast<typename contravariant_output_t::scalar_t>(
0135 std::lrintf(c[i])
0136 );
0137 }
0138
0139 return m_backend.at(nc);
0140 }
0141
0142 typename backend_t::non_owning_data_t & get_backend(void)
0143 {
0144 return m_backend;
0145 }
0146
0147 const typename backend_t::non_owning_data_t & get_backend(void) const
0148 {
0149 return m_backend;
0150 }
0151
0152 typename backend_t::non_owning_data_t m_backend;
0153 };
0154 };
0155 }