Volume Cartographer 2.27.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
Derivative.hpp
Go to the documentation of this file.
1#pragma once
2
9#include <array>
10#include <cassert>
11#include <cstddef>
12#include <vector>
13
15{
16
17// To be used later on when this is more parameterized
18// clang-format off
23static constexpr std::array<std::array<double, 9>, 4> D1_CENTRAL_DIFF_COEFFS = {
24 0, 0, 0, -1/2, 0, 1/2, 0, 0, 0,
25 0, 0, 1/12, -2/3, 0, 2/3, -1/12, 0, 0,
26 0, -1/60, 3/20, -3/4, 0, 3/4, -3/20, 1/60, 0,
27 1/280, -4/105, 1/5, -4/5, 0, 4/5, -1/5, 4/105, -1/280
28};
29
34static constexpr std::array<std::array<double, 9>, 4> D2_CENTRAL_DIFF_COEFFS = {
35 0, 0, 0, 1, -2, 1, 0, 0, 0,
36 0, 0, -1/12, 4/3, -5/2, 4/3, -1/12, 0, 0,
37 0, 1/90, -3/20, 3/2, -49/18, 3/2, -3/20, 1/90, 0,
38 -1/560, 8/315, -1/5, 8/5, -205/72, 8/5, -1/5, 8/315, -1/560
39};
40// clang-format on
41
52template <typename T>
53T D1Forward(const std::vector<T>& vs, int index, int hstep = 1)
54{
55 assert(index >= 0 && index < int(vs.size()) && "index not in range of vs");
56 assert(index <= int(vs.size()) && "index must not be last point");
57 return (-vs[index] + vs[std::size_t(index) + hstep]) / double(hstep);
58}
59
70template <typename T>
71T D1Backward(const std::vector<T>& vs, int index, int hstep = 1)
72{
73 assert(index >= 0 && index < int(vs.size()) && "index not in range of vs");
74 assert(index >= hstep && "index must not be first point");
75 return (-vs[index - hstep] + vs[index]) / double(hstep);
76}
77
88template <typename T>
89T D1Central(const std::vector<T>& vs, int index, int hstep = 1)
90{
91 assert(index >= 0 && index < int(vs.size()) && "index not in range of vs");
92 assert(index - hstep >= 0 && "index out of range");
93 assert(index + hstep < int(vs.size()) && "index out of range");
94 return ((-0.5) * vs[index - hstep] +
95 (0.5) * vs[std::size_t(index) + hstep]) /
96 double(hstep);
97}
98
99// TODO(skarlage): #187
111template <typename T>
112T D1FivePointStencil(const std::vector<T>& vs, int index, int hstep = 1)
113{
114 assert(index >= 0 && index < int(vs.size()) && "index not in range of vs");
115 assert(index - 2 * hstep >= 0 && "index out of range\n");
116 assert(index - 1 * hstep >= 0 && "index out of range\n");
117 assert(index + 1 * hstep < int(vs.size()) && "index out of range\n");
118 assert(index + 2 * hstep < int(vs.size()) && "index out of range\n");
119 // clang-format off
120 return (
121 (1.0/12) * vs[index - 2 * hstep] +
122 (-2.0/3) * vs[index - hstep] +
123 (2.0/3) * vs[std::size_t(index) + hstep] +
124 (-1.0/12) * vs[std::size_t(index) + 2 * hstep]) /
125 double(hstep);
126 // clang-format on
127}
128
140template <typename T>
141T D1At(const std::vector<T>& vs, int index, int hstep = 1)
142{
143 if (index - hstep < 0) {
144 return D1Forward(vs, index, hstep);
145 } else if (index + hstep > int(vs.size()) - 1) {
146 return D1Backward(vs, index, hstep);
147 } else if (
148 index - hstep < hstep || index + hstep >= int(vs.size()) - hstep) {
149 return D1Central(vs, index, hstep);
150 } else {
151 return D1FivePointStencil(vs, index, hstep);
152 }
153}
154
163template <typename T>
164std::vector<T> D1(const std::vector<T>& vs, int hstep = 1)
165{
166 std::vector<T> dvs;
167 dvs.reserve(vs.size());
168 for (std::size_t i = 0; i < vs.size(); ++i) {
169 dvs.push_back(D1At(vs, i, hstep));
170 }
171 return dvs;
172}
173
180template <typename T>
181T D2Forward(const std::vector<T>& vs, int index, int hstep = 1)
182{
183 assert(index >= 0 && index < int(vs.size()) && "index out of range");
184 assert(index + hstep < int(vs.size()) && "index out of range");
185 assert(index + 2 * hstep < int(vs.size()) && "index out of range");
186 return (vs[index] + (-2.0) * vs[std::size_t(index) + hstep] +
187 vs[std::size_t(index) + 2 * hstep]) /
188 double(hstep * hstep);
189}
190
197template <typename T>
198T D2Backward(const std::vector<T>& vs, int index, int hstep = 1)
199{
200 assert(index >= 0 && index < int(vs.size()) && "index out of range");
201 assert(index - 2 * hstep >= 0 && "index out of range");
202 assert(index - 1 * hstep >= 0 && "index out of range");
203 return (vs[index - 2 * hstep] + (-2.0) * vs[index - hstep] + vs[index]) /
204 double(hstep * hstep);
205}
206
213template <typename T>
214T D2Central(const std::vector<T>& vs, int index, int hstep = 1)
215{
216 assert(index >= 0 && index < int(vs.size()) && "index not in range of vs");
217 assert(index - hstep >= 0 && "index out of range");
218 assert(index + hstep < int(vs.size()) && "index out of range");
219 return (vs[index - hstep] + (-2.0) * vs[index] +
220 vs[std::size_t(index) + hstep]) /
221 double(hstep * hstep);
222}
223
224// TODO(skarlage): #187
232template <typename T>
233T D2FivePointStencil(const std::vector<T>& vs, int index, int hstep = 1)
234{
235 assert(index >= 0 && index < int(vs.size()) && "index not in range of vs");
236 assert(index - 2 * hstep >= 0 && "index out of range");
237 assert(index - 1 * hstep >= 0 && "index out of range");
238 assert(index + 1 * hstep < int(vs.size()) && "index out of range");
239 assert(index + 2 * hstep < int(vs.size()) && "index out of range");
240 // clang-format off
241 return (
242 (-1.0/12) * vs[index - 2 * hstep] +
243 (4.0/3) * vs[index - hstep] +
244 (-5.0/2) * vs[index] +
245 (4.0/3) * vs[std::size_t(index) + hstep] +
246 (-1.0/12) * vs[std::size_t(index) + 2 * hstep]) /
247 double(hstep * hstep);
248 // clang-format on
249}
250
262template <typename T>
263T D2At(const std::vector<T>& vs, int index, int hstep = 1)
264{
265 if (index - hstep < 0) {
266 return D2Forward(vs, index, hstep);
267 } else if (index + hstep > int(vs.size()) - 1) {
268 return D2Backward(vs, index, hstep);
269 } else if (
270 index - hstep < hstep || index + hstep >= int(vs.size()) - hstep) {
271 return D2Central(vs, index, hstep);
272 } else {
273 return D2FivePointStencil(vs, index, hstep);
274 }
275}
276
282template <typename T>
283std::vector<T> D2(const std::vector<T>& vs, int hstep = 1)
284{
285 std::vector<T> dvs;
286 dvs.reserve(vs.size());
287 for (std::size_t i = 0; i < vs.size(); ++i) {
288 dvs.push_back(D2At(vs, i, hstep));
289 }
290 return dvs;
291}
292} // namespace volcart::segmentation
std::vector< T > D2(const std::vector< T > &vs, int hstep=1)
Calculate the second derivative for a vector of sampled points.
Definition: Derivative.hpp:283
T D2At(const std::vector< T > &vs, int index, int hstep=1)
Calculate the second derivative for a sampled point.
Definition: Derivative.hpp:263
T D1Forward(const std::vector< T > &vs, int index, int hstep=1)
Calculate the first derivative for a sampled point.
Definition: Derivative.hpp:53
static constexpr std::array< std::array< double, 9 >, 4 > D1_CENTRAL_DIFF_COEFFS
Definition: Derivative.hpp:23
T D1At(const std::vector< T > &vs, int index, int hstep=1)
Calculate the first derivative for a sampled point.
Definition: Derivative.hpp:141
std::vector< T > D1(const std::vector< T > &vs, int hstep=1)
Calculate the first derivative for a vector of sampled points.
Definition: Derivative.hpp:164
T D2Central(const std::vector< T > &vs, int index, int hstep=1)
Calculate the second derivative for a sampled point.
Definition: Derivative.hpp:214
static constexpr std::array< std::array< double, 9 >, 4 > D2_CENTRAL_DIFF_COEFFS
Definition: Derivative.hpp:34
T D1Central(const std::vector< T > &vs, int index, int hstep=1)
Calculate the first derivative for a sampled point.
Definition: Derivative.hpp:89
T D1Backward(const std::vector< T > &vs, int index, int hstep=1)
Calculate the first derivative for a sampled point.
Definition: Derivative.hpp:71
T D2Backward(const std::vector< T > &vs, int index, int hstep=1)
Calculate the second derivative for a sampled point.
Definition: Derivative.hpp:198
T D1FivePointStencil(const std::vector< T > &vs, int index, int hstep=1)
Calculate the first derivative for a sampled point using a five-point stencil.
Definition: Derivative.hpp:112
T D2FivePointStencil(const std::vector< T > &vs, int index, int hstep=1)
Calculate the second derivative for a sampled point using a five-point stencil.
Definition: Derivative.hpp:233
T D2Forward(const std::vector< T > &vs, int index, int hstep=1)
Calculate the second derivative for a sampled point.
Definition: Derivative.hpp:181
Segmentation algorithms and utilities library