/
moving_least_squares.cpp
113 lines (97 loc) · 4.07 KB
/
moving_least_squares.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/****************************************************************************
* Copyright (c) 2023 by the ArborX authors *
* All rights reserved. *
* *
* This file is part of the ArborX library. ArborX is *
* distributed under a BSD 3-clause license. For the licensing terms see *
* the LICENSE file in the top-level directory. *
* *
* SPDX-License-Identifier: BSD-3-Clause *
****************************************************************************/
#include <ArborX.hpp>
#include <ArborX_InterpMovingLeastSquares.hpp>
#include <Kokkos_Core.hpp>
#include <iostream>
using Point = ArborX::ExperimentalHyperGeometry::Point<2, double>;
KOKKOS_FUNCTION double functionToApproximate(Point const &p)
{
return Kokkos::cos(p[0] + p[1] / 4);
}
int main(int argc, char *argv[])
{
Kokkos::ScopeGuard guard(argc, argv);
using ExecutionSpace = Kokkos::DefaultExecutionSpace;
using MemorySpace = typename ExecutionSpace::memory_space;
ExecutionSpace space{};
// Source space is a 3x3 grid
// Target space is 3 off-grid points
//
// ^
// |
// S S S
// |
// | T
// S S T S
// |
// | T
// -S-----S-----S->
// |
int const num_sources = 9;
int const num_targets = 3;
// Set up points
Kokkos::View<Point *, MemorySpace> src_points("Example::src_points",
num_sources);
Kokkos::View<Point *, MemorySpace> tgt_points("Example::tgt_points",
num_targets);
Kokkos::parallel_for(
"Example::make_points", Kokkos::RangePolicy<ExecutionSpace>(space, 0, 1),
KOKKOS_LAMBDA(int const) {
src_points(0) = {0., 0.};
src_points(1) = {1., 0.};
src_points(2) = {2., 0.};
src_points(3) = {0., 1.};
src_points(4) = {1., 1.};
src_points(5) = {2., 1.};
src_points(6) = {0., 2.};
src_points(7) = {1., 2.};
src_points(8) = {2., 2.};
tgt_points(0) = {4. / 6., 4. / 3.};
tgt_points(1) = {9. / 6., 3. / 3.};
tgt_points(2) = {2. / 6., 1. / 3.};
});
// Set up values
Kokkos::View<double *, MemorySpace> src_values("Example::src_values",
num_sources);
Kokkos::View<double *, MemorySpace> app_values("Example::app_values",
num_targets);
Kokkos::View<double *, MemorySpace> ref_values("Example::ref_values",
num_targets);
Kokkos::parallel_for(
"Example::make_values",
Kokkos::RangePolicy<ExecutionSpace>(space, 0, num_sources),
KOKKOS_LAMBDA(int const i) {
src_values(i) = functionToApproximate(src_points(i));
if (i < num_targets)
ref_values(i) = functionToApproximate(tgt_points(i));
});
// Build the moving least squares coefficients
ArborX::Interpolation::MovingLeastSquares<MemorySpace> mls(space, src_points,
tgt_points);
// Interpolate
mls.interpolate(space, src_values, app_values);
// Show results
auto app_values_host =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, app_values);
auto ref_values_host =
Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace{}, ref_values);
auto diff = [=](int const i) {
return Kokkos::abs(app_values_host(i) - ref_values_host(i));
};
std::cout << "Approximated values: " << app_values_host(0) << ' '
<< app_values_host(1) << ' ' << app_values_host(2) << '\n';
std::cout << "Real values : " << ref_values_host(0) << ' '
<< ref_values_host(1) << ' ' << ref_values_host(2) << '\n';
std::cout << "Differences : " << diff(0) << ' ' << diff(1) << ' '
<< diff(2) << '\n';
return 0;
}