Tatooine
radial_basis_functions_sampler.h
Go to the documentation of this file.
1#if TATOOINE_BLAS_AND_LAPACK_AVAILABLE
2#ifndef TATOOINE_DETAIL_POINTSET_RADIAL_BASIS_FUNCTIONS_SAMPLER_H
3#define TATOOINE_DETAIL_POINTSET_RADIAL_BASIS_FUNCTIONS_SAMPLER_H
4//==============================================================================
5#include <tatooine/field.h>
6#include <tatooine/pointset.h>
7#include <tatooine/concepts.h>
8//==============================================================================
10//==============================================================================
11template <floating_point Real, std::size_t NumDimensions, typename T,
12 invocable<Real> Kernel>
14 : field<radial_basis_functions_sampler<Real, NumDimensions, T, Kernel>,
15 Real, NumDimensions, T> {
16 using this_type =
19 using typename parent_type::pos_type;
20 using typename parent_type::real_type;
21 using typename parent_type::tensor_type;
25 typename pointset_type::template typed_vertex_property_type<T>;
26 static auto constexpr num_dimensions() { return NumDimensions; }
27 //==========================================================================
30 Kernel m_kernel;
32 //==========================================================================
34 vertex_property_type const& property,
35 convertible_to<Kernel> auto&& kernel)
36 : m_pointset{ps},
37 m_property{property},
38 m_kernel{std::forward<decltype(kernel)>(kernel)} {
39 auto const N = m_pointset.vertices().size();
40 // construct lower part of symmetric matrix A
41 auto A =
42 tensor<real_type>::zeros(N + NumDimensions + 1, N + NumDimensions + 1);
43 for (std::size_t c = 0; c < N; ++c) {
44 for (std::size_t r = c + 1; r < N; ++r) {
47 }
48 }
49 // construct polynomial requirements
50 for (std::size_t c = 0; c < N; ++c) {
51 auto const& p = m_pointset.vertex_at(c);
52 // constant part
53 A(N, c) = 1;
54
55 // linear part
56 for (std::size_t i = 0; i < NumDimensions; ++i) {
57 A(N + i + 1, c) = p(i);
58 }
59 }
60
62 if constexpr (arithmetic<T>) {
63 return tensor<T>::zeros(N + NumDimensions + 1);
64 } else if constexpr (static_tensor<T>) {
65 return tensor<tatooine::value_type<T>>::zeros(N + NumDimensions + 1,
66 T::num_components());
67 }
68 }();
69
70 for (std::size_t i = 0; i < N; ++i) {
71 if constexpr (arithmetic<T>) {
73 } else if constexpr (static_tensor<T>) {
74 for (std::size_t j = 0; j < T::num_components(); ++j) {
76 }
77 }
78 }
79 // do not copy by moving A and m_radial_and_monomial_coefficients into
80 // solver
82 std::move(A), std::move(m_radial_and_monomial_coefficients),
84 }
85 //----------------------------------------------------------------------------
87 default;
88 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89 // -
91 default;
92 //----------------------------------------------------------------------------
93 auto operator=(radial_basis_functions_sampler const&)
95 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
96 auto operator=(radial_basis_functions_sampler&&) noexcept
98 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
100 //----------------------------------------------------------------------------
101 static auto for_loop(auto&& iteration, std::size_t const degree,
102 std::size_t const dim, std::vector<std::size_t>& status)
103 -> void {
104 if (dim == degree + 1) {
105 return iteration(status);
106 } else {
107 for (; status[dim] < (dim == 0 ? num_dimensions() : status[dim - 1]);
108 ++status[dim]) {
109 for_loop(std::forward<decltype(iteration)>(iteration), begin, end,
110 status, dim + 1);
111 }
112 status[dim] = 0;
113 }
114 }
115 //============================================================================
116 [[nodiscard]] auto evaluate(pos_type const& q, real_type const /*t*/) const
117 -> tensor_type {
118 auto const N = m_pointset.vertices().size();
119 auto acc = T{};
120 // radial basis functions
121 for (auto const v : m_pointset.vertices()) {
122 auto const sqr_dist = squared_euclidean_distance(q, m_pointset[v]);
123 if (sqr_dist == 0) {
124 return m_property[v];
125 }
126 if constexpr (arithmetic<T>) {
127 acc +=
128 m_radial_and_monomial_coefficients(v.index()) * m_kernel(sqr_dist);
129 } else if constexpr (static_tensor<T>) {
130 for (std::size_t j = 0; j < T::num_components(); ++j) {
131 acc.data()[j] += m_radial_and_monomial_coefficients(v.index(), j) *
132 m_kernel(sqr_dist);
133 }
134 }
135 }
136 // polynomial part
137 if constexpr (arithmetic<T>) {
139 for (std::size_t k = 0; k < NumDimensions; ++k) {
140 acc += m_radial_and_monomial_coefficients(N + 1 + k) * q(k);
141 }
142 } else if constexpr (static_tensor<T>) {
143 for (std::size_t j = 0; j < T::num_components(); ++j) {
144 acc.data()[j] += m_radial_and_monomial_coefficients(N, j);
145 for (std::size_t k = 0; k < NumDimensions; ++k) {
146 acc.data()[j] +=
147 m_radial_and_monomial_coefficients(N + 1 + k, j) * q(k);
148 }
149 }
150 }
151 return acc;
152 }
153};
154//==============================================================================
155template <floating_point Real, std::size_t NumDimensions, typename T,
156 invocable<Real> Kernel>
161 Kernel&& kernel) -> radial_basis_functions_sampler<Real, NumDimensions, T,
162 std::decay_t<Kernel>>;
163//==============================================================================
164} // namespace tatooine::detail::pointset
165//==============================================================================
166#endif
167#endif
Definition: concepts.h:33
Definition: concepts.h:39
Definition: concepts.h:30
Definition: concepts.h:121
Definition: tensor_concepts.h:20
Definition: inverse_distance_weighting_sampler.h:4
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
auto solve_symmetric_lapack(TensorA &&A_, TensorB &&B_, lapack::uplo uplo=lapack::uplo::lower) -> std::optional< tensor< common_type< tatooine::value_type< decltype(A_)>, tatooine::value_type< decltype(B_)> > > >
Definition: solve.h:349
constexpr auto squared_euclidean_distance(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: distance.h:11
static constexpr forward_tag forward
Definition: tags.h:9
Definition: radial_basis_functions_sampler.h:15
Kernel m_kernel
Definition: radial_basis_functions_sampler.h:30
tensor< Real > m_radial_and_monomial_coefficients
Definition: radial_basis_functions_sampler.h:31
auto evaluate(pos_type const &q, real_type const) const -> tensor_type
Definition: radial_basis_functions_sampler.h:116
static auto for_loop(auto &&iteration, std::size_t const degree, std::size_t const dim, std::vector< std::size_t > &status) -> void
Definition: radial_basis_functions_sampler.h:101
typename pointset_type::vertex_handle vertex_handle
Definition: radial_basis_functions_sampler.h:23
pointset_type const & m_pointset
Definition: radial_basis_functions_sampler.h:28
static auto constexpr num_dimensions()
Definition: radial_basis_functions_sampler.h:26
radial_basis_functions_sampler(radial_basis_functions_sampler &&) noexcept=default
radial_basis_functions_sampler(radial_basis_functions_sampler const &)=default
vertex_property_type const & m_property
Definition: radial_basis_functions_sampler.h:29
typename pointset_type::template typed_vertex_property_type< T > vertex_property_type
Definition: radial_basis_functions_sampler.h:25
radial_basis_functions_sampler(pointset_type const &ps, vertex_property_type const &property, convertible_to< Kernel > auto &&kernel)
Definition: radial_basis_functions_sampler.h:33
Definition: field.h:134
Real real_type
Definition: field.h:17
vec< real_type, NumDimensions > pos_type
Definition: field.h:20
Tensor tensor_type
Definition: field.h:18
Definition: pointset.h:83
Definition: pointset.h:69
auto vertices() const
Definition: pointset.h:226
auto vertex_at(vertex_handle const v) -> auto &
Definition: pointset.h:205
Definition: tensor.h:17
static constexpr auto zeros()
Definition: tensor.h:144
Definition: property.h:66
Definition: vec.h:12