1 #ifndef MEDUSA_BITS_APPROXIMATIONS_WLS_HPP_
2 #define MEDUSA_BITS_APPROXIMATIONS_WLS_HPP_
18 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
20 const std::vector<vector_t>& support) {
21 int n = support.size();
23 "WLS cannot have more basis functions than points in support domain, but %d "
24 "support points and %d basis functions were given.", n, basis_.size());
25 assert_msg(basis_.size() > 0,
"Cannot construct an approximation with an empty basis.");
26 scale_ = scale_t::scale(point, support);
27 local_coordinates_.resize(n);
28 for (
int i = 0; i < n; ++i) {
29 local_coordinates_[i] = (support[i] - point) / scale_;
32 solver_.compute(getMatrix(local_coordinates_));
35 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
38 const std::vector<vector_t>& local_coordinates)
const {
40 int n = local_coordinates.size();
41 int m = basis_.size();
43 for (
int j = 0; j < n; j++) {
44 scalar_t w = weight_(local_coordinates[j]);
45 for (
int i = 0; i < m; i++) {
46 WB(i, j) = w * basis_.eval(i, local_coordinates[j], local_coordinates);
52 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
53 Eigen::Matrix<typename basis_t::scalar_t, Eigen::Dynamic, 1>
55 int m = basis_.size();
56 Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> b(m);
57 for (
int i = 0; i < m; i++) {
58 b(i) = basis_.evalAt0(i, local_coordinates_);
60 return getShapeFromRhs(b);
64 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
65 template <
class operator_t>
66 Eigen::Matrix<typename basis_t::scalar_t, Eigen::Dynamic, 1>
68 int m = basis_.size();
69 Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> Lb(m);
70 for (
int i = 0; i < m; i++) {
71 Lb(i) = basis_.evalOpAt0(i, op, local_coordinates_, scale_);
73 return getShapeFromRhs(Lb);
76 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
77 template <
class Derived>
78 Eigen::Matrix<typename basis_t::scalar_t, Eigen::Dynamic, 1>
80 const Eigen::MatrixBase<Derived>& Lb)
const {
81 int n = local_coordinates_.size();
83 Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> result = solver_.solve(Lb);
85 for (
int j = 0; j < n; j++) {
86 result(j) *= weight_(local_coordinates_[j]);
91 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
92 Eigen::Matrix<typename basis_t::scalar_t, Eigen::Dynamic, 1>
94 int n = local_coordinates_.size();
95 Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> w(n);
96 for (
int j = 0; j < n; j++) {
97 w(j) = weight_(local_coordinates_[j]);
104 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
107 <<
" dimension: " << wls.
dim <<
'\n'
108 <<
" basis size: " << wls.
basis_.size() <<
'\n'
109 <<
" basis: " << wls.
basis_ <<
'\n'
110 <<
" weight: " << wls.
weight_ <<
'\n'
111 <<
" scale: " << scale_t() <<
'\n';
113 os <<
" last point: not used yet";
115 os <<
" last point: " << wls.
point_;
120 template <
class basis_t,
class weight_t,
class scale_t,
class solver_t>
121 template <
typename Derived>
122 WLSApproximant<basis_t>
124 const vector_t& point,
const std::vector<vector_t>& support,
125 const Eigen::MatrixBase<Derived>& values)
const {
126 int n = support.size();
127 assert_msg(values.size() == n,
"Number of given values %d must be equal to support size %d.",
130 "WLS cannot have more basis functions than points in support domain, but %d "
131 "support points and %d basis functions were given.", n, basis_.size());
132 double scale = scale_t::scale(point, support);
133 std::vector<vector_t> local_coordinates(n);
134 for (
int i = 0; i < n; ++i) {
135 local_coordinates[i] = (support[i] - point) / scale;
138 ei_matrix_t matrix = getMatrix(local_coordinates).transpose();
139 solver.compute(matrix);
141 Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> w(n);
142 for (
int j = 0; j < n; j++) {
143 w(j) = weight_(local_coordinates[j]);
145 Eigen::Matrix<scalar_t, Eigen::Dynamic, 1> coefficients = solver.solve(values.cwiseProduct(w));
146 scalar_t residual = (matrix*coefficients - values).squaredNorm();
152 #endif // MEDUSA_BITS_APPROXIMATIONS_WLS_HPP_