1 #ifndef MEDUSA_BITS_INTERPOLANTS_PUAPPROXIMANT_HPP_
2 #define MEDUSA_BITS_INTERPOLANTS_PUAPPROXIMANT_HPP_
18 template <
typename vec_t>
19 template <
typename scalar_t,
typename engine_t>
21 const DomainDiscretization<vec_t>& domain,
const eigen_vt<scalar_t>& values,
22 const Range<vec_t>& query_points, d_scalar_t radius_factor,
const engine_t& engine) {
23 KDTree<vec_t> tree(query_points);
25 return evaluate(domain, values, tree, radius_factor, engine);
28 template <
typename vec_t>
29 template <
typename scalar_t,
typename engine_t>
31 const DomainDiscretization<vec_t>& domain,
const eigen_vt<scalar_t>& values,
32 const KDTree<vec_t>& query_points_tree, d_scalar_t radius_factor,
const engine_t& engine) {
33 int N = domain.size();
34 assert_msg(N >= 0,
"Missing domain positions.");
35 for (
int i = 0; i < domain.size(); i++) {
36 int support_size = domain.supportSize(i);
37 if (support_size <= 0) {
39 "Expected support size >= 0. Node %d has support size %d. Did you forget "
40 "to call findSupport()?",
44 int M = values.size();
46 "Number of function values given different from number of "
47 "nodes in the domain. Got %d function values and %d nodes.",
49 assert_msg(radius_factor >= 0 && radius_factor <= 1,
50 "Effective radius must be "
51 "larger than 0 and smaller than 1, got %g",
54 int Nq = query_points_tree.size();
55 eigen_vt<scalar_t> result_num(Nq);
56 result_num.setConstant(0);
57 eigen_vt<d_scalar_t> result_den(Nq);
58 result_den.setConstant(0);
59 Eigen::VectorXi count(Nq);
62 for (
int i = 0; i < N; ++i) {
63 if (domain.supportSize(i) <= 0)
continue;
65 const vec_t& p = domain.pos(i);
66 auto appr = engine.getApproximant(p, domain.supportNodes(i), values(domain.support(i)));
69 Range<vec_t> sup = domain.supportNodes(i);
70 auto dr = (sup[0] - sup[sup.size() - 1]).norm();
71 d_scalar_t radius = radius_factor * dr;
72 d_scalar_t radius2 = ipow<2>(radius);
75 std::tie(idx, dist2) =
76 query_points_tree.query(p, radius2);
78 for (
int j = 0; j < n; ++j) {
79 const int& k = idx[j];
81 d_scalar_t w = weight(std::sqrt(dist2[j] / radius2));
82 result_num[k] += w * appr(query_points_tree.get(k));
88 for (
int i = 0; i < Nq; ++i) {
90 "Query point %d has an undefined value. Point %s is not covered by any of "
91 "the balls with centers in discretization nodes. Consider increasing the "
93 i, query_points_tree.get(i));
96 return result_num.cwiseQuotient(result_den);
101 #endif // MEDUSA_BITS_INTERPOLANTS_PUAPPROXIMANT_HPP_