quadgrid 0.1
simple cartesian quad grid with particles for c++/octave
Loading...
Searching...
No Matches
tbasisfun.h
Go to the documentation of this file.
1#ifndef HAVE_TBASISFUN_H
2#define HAVE_TBASISFUN_H
3
4#include <algorithm>
5#include <iomanip>
6#include <iostream>
7#include <iterator>
8#include <limits>
9
10namespace bspline {
11
12 template<typename FLT>
13 FLT
14 ratio (const FLT num, const FLT denom) {
15 if (denom != FLT(0.0)) {
16 return num / denom;
17 } else if (num != FLT(0.0)) {
18 throw ("division by zero!");
19 } else {
20 return FLT(1.0);
21 }
22 };
23
26
31
32 template<typename INT, typename FLT, typename ITERATOR>
33 FLT
34 onebasisfun (FLT const u, INT const p, ITERATOR const Ubegin, ITERATOR const Uend) {
35 FLT N{0.0};
36 const FLT Umin = *(std::min_element (Ubegin, Uend));
37 const FLT Umax = *(std::max_element (Ubegin, Uend));
38
39 //std::cout << std::setprecision (16) <<"Umin = " << Umin << " u = " << u << " Umax = " << Umax << std::endl;
40 if (u >= Umin && u <= Umax) {
41
42 if (p == 0) {
43 N = 1.0;
44 }
45
46 else if (p == 1) {
47 if (u < *std::next(Ubegin, 1)) {
48 N = ratio ((u - *Ubegin),
49 (*std::next(Ubegin) - *Ubegin));
50 }
51 else {
52 N = ratio ((*std::next(Ubegin, 2) - u),
53 (*std::next(Ubegin, 2) - *std::next(Ubegin)));
54 }
55 }
56
57 else if (p == 2) {
58
59 const FLT ln = u - *Ubegin;
60 const FLT dn = *std::next(Ubegin, 3) - u;
61 const FLT ld = *std::next(Ubegin, 2) - *Ubegin;
62 const FLT dd = *std::next(Ubegin, 3) - *std::next(Ubegin);
63
64 if (u < *std::next (Ubegin)) {
65 N = ratio (ln*ln, ld * (*std::next (Ubegin) - *Ubegin));
66 }
67 else if (u > *std::next (Ubegin, 2)) {
68 N = ratio (dn*dn,
69 (dd * (*std::next (Ubegin, 3) - *std::next (Ubegin, 2))));
70 }
71 else {
72 if (ld > FLT(0.0)) {
73 N += ratio (ln * (*std::next(Ubegin, 2) - u),
74 ((*std::next(Ubegin, 2) - *std::next(Ubegin, 1)) * ld));
75 }
76 if (dd > FLT(0.0)) {
77 N += ratio (dn * (u - *std::next(Ubegin, 1)),
78 ((*std::next(Ubegin, 2) - *std::next(Ubegin, 1)) * dd));
79 }
80 }
81 }
82
83 else {
84
85 const FLT ld = *std::next (Uend, - 2) - *Ubegin;
86 const FLT dd = *std::prev (Uend) - *std::next (Ubegin);
87
88 if (ld > FLT(0.0)) {
89 const FLT ln = u - *Ubegin;
90 N += ln * onebasisfun (u, p-1, Ubegin, std::prev (Uend)) / ld;
91 }
92
93 if (dd > FLT(0.0)) {
94 const FLT dn = *std::prev (Uend) - u;
95 N += dn * onebasisfun (u, p-1, std::next (Ubegin), Uend) / dd;
96 }
97
98 //std::cout << "p = " << p << std::endl;
99 //std::cout << "u - *Ubegin = " << u - *Ubegin << " ld = " << ld << " ";
100
101 //std::cout << " *std::next (Uend, - 1) - *std::next (Ubegin , 1) = "
102 // << *std::next (Uend, - 1) - *std::next (Ubegin , 1)
103 // << " dd = " << dd << " N = " << N << std::endl;
104 }
105 }
106
107 //std::cout << " N = " << N << std::endl;
108 return N;
109 };
110
112
118 template<typename INT, typename FLT, typename ITERATOR>
119 FLT
120 onebasisfunder (FLT u, INT p, ITERATOR Ubegin, ITERATOR Uend)
121 {
122
123 FLT Nder{0.0};
124 const FLT Umin = *(std::min_element (Ubegin, Uend));
125 const FLT Umax = *(std::max_element (Ubegin, Uend));
126
127 if ((u >= Umin) && ( u <= Umax)) {
128
129 if (p == 0) {
130 Nder = FLT(0.0);
131 }
132 else {
133
134 const FLT ld = *std::next (Uend, -2) - *Ubegin;
135 if (std::abs (ld) > FLT(0.0)) {
136 Nder += ratio (p * onebasisfun (u, p-1, Ubegin, std::next (Uend, -1)), ld);
137 }
138
139 const FLT dd = *std::next (Uend, -1) - *std::next (Ubegin, 1);
140 if (std::abs (dd) > FLT(0.0)) {
141 Nder -= ratio (p * onebasisfun (u, p-1, std::next (Ubegin, 1), Uend), dd);
142 }
143
144 }
145 }
146
147 return Nder;
148 };
149
152
158
159 template<typename INT, typename ITERATOR, typename FLT=double>
160 std::vector<FLT>
161 open_knot_vector (ITERATOR const bb, ITERATOR const be, INT const p, INT const r) {
162
163 const INT Nb = std::distance (bb, be);
164 const INT Nk = (p - r) * (Nb - 2) + 2 * (p + 1); // (Nb - 2 + 2) *p
165
166 std::vector<FLT> k (Nk, *bb);
167
168
169 auto ki = std::next (k.begin (), p + 1);
170 for (auto bi = std::next (bb); bi != be; bi = std::next (bi)) {
171 ki = std::fill_n (ki, p - r, *bi);
172 }
173 std::fill (ki, k.end (), *(std::next (be, -1)));
174
175 return k;
176 };
177
178
179 template<typename INT, typename FLT, typename ITERATOR>
180 FLT
181 onebasisfun2d (FLT const u, FLT const v, INT const pu, INT const pv,
182 ITERATOR const Ubegin, ITERATOR const Uend,
183 ITERATOR const Vbegin, ITERATOR const Vend) {
184 FLT N = onebasisfun (u, pu, Ubegin, Uend);
185 N *= onebasisfun (v, pv, Vbegin, Vend);
186 return N;
187 }
188
189}
190
191#endif
192
193
Definition tbasisfun.h:10
FLT onebasisfun2d(FLT const u, FLT const v, INT const pu, INT const pv, ITERATOR const Ubegin, ITERATOR const Uend, ITERATOR const Vbegin, ITERATOR const Vend)
Definition tbasisfun.h:181
std::vector< FLT > open_knot_vector(ITERATOR const bb, ITERATOR const be, INT const p, INT const r)
create an uniform open knot vector given the list
Definition tbasisfun.h:161
FLT onebasisfunder(FLT u, INT p, ITERATOR Ubegin, ITERATOR Uend)
function to compute the derivative of a BSpline basis function.
Definition tbasisfun.h:120
FLT onebasisfun(FLT const u, INT const p, ITERATOR const Ubegin, ITERATOR const Uend)
function to compute the value of a BSpline basis function at a given point.
Definition tbasisfun.h:34
FLT ratio(const FLT num, const FLT denom)
Definition tbasisfun.h:14