BSplinebasis
Loading...
Searching...
No Matches
BilinearForm.h
1/*
2 * ########################################################################
3 * The contents of this file is free and unencumbered software released into the
4 * public domain. For more information, please refer to <http://unlicense.org/>
5 * ########################################################################
6 */
7
8#ifndef BSPLINE_INTEGRATION_BILINEARFORM_H
9#define BSPLINE_INTEGRATION_BILINEARFORM_H
10
11#include <bspline/Spline.h>
12#include <bspline/operators/GenericOperators.h>
13
22
35template <typename O1, typename O2,
36 std::enable_if_t<operators::are_operators_v<O1, O2>, bool> = true>
38 private:
40 O1 _o1;
42 O2 _o2;
43
55 template <typename T, size_t sizea, size_t sizeb>
56 static T evaluateInterval(const std::array<T, sizea> &a,
57 const std::array<T, sizeb> &b, const T &dxhalf) {
58 std::array<T, (sizea + sizeb) / 2> coefficients;
59 coefficients.fill(static_cast<T>(0));
60 for (size_t i = 0; i < sizea; i++) {
61 for (size_t j = i % 2; j < sizeb; j += 2) {
62 coefficients[(i + j) / 2] += a[i] * b[j];
63 }
64 }
65
66 // Use Horner's scheme to evaluate.
67 constexpr int endIndex = static_cast<int>(coefficients.size()) - 1;
68 static_assert(endIndex >= 0);
69
70 T result = coefficients[endIndex] / static_cast<T>(2 * endIndex + 1);
71 const T dxhalf_squared = dxhalf * dxhalf;
72
73 for (int i = endIndex - 1; i >= 0; i--) {
74 result =
75 result * dxhalf_squared + coefficients[i] / static_cast<T>(2 * i + 1);
76 }
77 return static_cast<T>(2) * dxhalf * result;
78 }
79
80 public:
88 BilinearForm(O1 o1, O2 o2) : _o1(std::move(o1)), _o2(std::move(o2)){};
89
98 explicit BilinearForm(O2 o2) : _o1(O1{}), _o2(std::move(o2)){};
99
105 BilinearForm() : _o1(O1{}), _o2(O2{}){};
106
118 template <typename T, size_t ordera, size_t orderb>
120 // Will also check whether the two grids are equivalent.
122 a.getSupport().calcIntersection(b.getSupport());
123 const size_t nintervals = integrandSupport.numberOfIntervals();
124
125 const auto &grid = integrandSupport.getGrid();
126
127 T result = static_cast<T>(0);
128
129 for (size_t interv = 0; interv < nintervals; interv++) {
130 const auto absIndex = integrandSupport.absoluteFromRelative(interv);
131
132 const auto aIndex =
133 a.getSupport().intervalIndexFromAbsolute(absIndex).value();
134 const auto bIndex =
135 b.getSupport().intervalIndexFromAbsolute(absIndex).value();
136
137 const T dxhalf = (a.getSupport()[aIndex + 1] - a.getSupport()[aIndex]) /
138 static_cast<T>(2);
139
140 result += evaluateInterval(
141 _o1.transform(a.getCoefficients()[aIndex], grid, absIndex),
142 _o2.transform(b.getCoefficients()[bIndex], grid, absIndex), dxhalf);
143 }
144 return result;
145 }
146
151 template <typename T, size_t ordera, size_t orderb>
153 return evaluate(a, b);
154 }
155};
156
167template <typename O2>
169
180
188
189} // namespace bspline::integration
190#endif // BSPLINE_INTEGRATION_BILINEARFORM_H
A bilinear form with user-provided operators.
Definition BilinearForm.h:37
T operator()(const Spline< T, ordera > &a, const Spline< T, orderb > &b) const
Definition BilinearForm.h:152
T evaluate(const Spline< T, ordera > &a, const Spline< T, orderb > &b) const
Evaluates the bilinear form for two particular splines.
Definition BilinearForm.h:119
BilinearForm()
Constructor without a user-provided operator.
Definition BilinearForm.h:105
BilinearForm(O2 o2)
Constructor with one user-provided operator.
Definition BilinearForm.h:98
BilinearForm(O1 o1, O2 o2)
Constructor with two user-provided operators.
Definition BilinearForm.h:88
Multiplicative identity operator.
Definition GenericOperators.h:95
Represents a global Grid.
Definition Grid.h:27
size_t size() const
Returns the number of elements of the Grid.
Definition Grid.h:169
Represents the Spline's Support.
Definition Support.h:33
Integration routines for Splines.
Definition BilinearForm.h:21