29class PieceWiseFunction
32 typedef posT result_type;
34 virtual ~PieceWiseFunction() {}
36 virtual posT kernel_length_left()
const = 0;
37 virtual int kernel_total_length()
const = 0;
38 posT kernel_length_right()
const {
return -this->kernel_length_left() + this->kernel_total_length(); }
40 virtual posT function_piece(
const posT x,
int p)
const = 0;
41 virtual posT derivative_piece(
const posT x,
int p)
const = 0;
42 virtual int find_piece(
const posT x)
const = 0;
43 virtual int find_highest_piece()
const = 0;
44 posT function(
const posT x)
const {
return this->function_piece(x, find_piece(x)); }
45 posT derivative(
const posT x)
const {
return this->derivative_piece(x, find_piece(x)); }
46 posT operator()(
const posT x)
const {
return this->function(x); }
47 posT operator()(
const posT p,
const BSplineType) {
return this->function(p); }
50template <BSplineType bspline_type,
class posT>
51class BSplineFunction :
public PieceWiseFunction<posT>
56class BSplineFunction<near_n, posT> :
public PieceWiseFunction<posT>
60 posT kernel_length_left()
const override {
return static_cast<posT
>(.5); }
61 BOOST_STATIC_CONSTANT(
int, kernel_total_length_value = 1);
62 int kernel_total_length()
const override {
return kernel_total_length_value; }
63 posT function_piece(
const posT x,
int p)
const override
68 return static_cast<posT
>(1);
74 posT derivative_piece(
const posT,
int)
const override {
return 0; }
76 int find_abs_piece(
const posT absx)
const {
return static_cast<int>(absx + .5); }
77 int find_piece(
const posT x)
const override
79 const int abs_p = this->find_abs_piece(fabs(x));
85 int find_highest_piece()
const override {
return 0; }
89class BSplineFunction<linear, posT> :
public PieceWiseFunction<posT>
93 posT kernel_length_left()
const override {
return static_cast<posT
>(1); }
94 BOOST_STATIC_CONSTANT(
int, kernel_total_length_value = 2);
95 int kernel_total_length()
const override {
return kernel_total_length_value; }
96 posT function_piece(
const posT x,
int p)
const override
108 posT derivative_piece(
const posT x,
int p)
const override
120 int find_piece(
const posT x)
const override {
return static_cast<int>(floor(x)); }
122 int find_highest_piece()
const override {
return 0; }
126class BSplineFunction<quadratic, posT> :
public PieceWiseFunction<posT>
130 posT kernel_length_left()
const override {
return static_cast<posT
>(1.5); }
131 BOOST_STATIC_CONSTANT(
int, kernel_total_length_value = 3);
132 int kernel_total_length()
const override {
return kernel_total_length_value; }
133 posT function_piece(
const posT x,
int p)
const override
138 return static_cast<posT
>(3) / 4 -
square(x);
140 const posT absx = std::fabs(x);
141 return square(2 * absx - 3) / 8;
147 posT derivative_piece(
const posT x,
int p)
const override
154 const int sign = x > 0 ? 1 : -1;
155 return x - sign *
static_cast<posT
>(1.5);
163 int find_abs_piece(
const posT absx)
const
166 return static_cast<int>(absx + .5);
171 else if (absx <= 1.5)
179 int find_piece(
const posT x)
const override
181 const int abs_p = this->find_abs_piece(fabs(x));
187 int find_highest_piece()
const override
193 posT function(
const posT x)
const
195 const posT absx = fabs(x);
200 return self_t::function_piece(absx,0);
202 return self_t::function_piece(absx,1);
210class BSplineFunction<cubic, posT> :
public PieceWiseFunction<posT>
214 posT kernel_length_left()
const override {
return static_cast<posT
>(2); }
215 BOOST_STATIC_CONSTANT(
int, kernel_total_length_value = 4);
216 int kernel_total_length()
const override {
return kernel_total_length_value; }
217 posT function_piece(
const posT x,
int p)
const override
219 const posT absx = std::fabs(x);
224 return 2. / 3. + (absx / 2 - 1) * absx * absx;
227 const posT tmp = 2 - absx;
228 return tmp * tmp * tmp / 6;
234 posT derivative_piece(
const posT x,
int p)
const override
239 return x * (1.5 * x - 2);
241 return -x * (1.5 * x + 2);
243 return -
square(x - 2) / 2;
250 int find_piece(
const posT x)
const override {
return static_cast<int>(floor(x)); }
251 int find_highest_piece()
const override {
return 1; }
255class BSplineFunction<oMoms, posT> :
public PieceWiseFunction<posT>
259 posT kernel_length_left()
const override {
return static_cast<posT
>(2); }
260 BOOST_STATIC_CONSTANT(
int, kernel_total_length_value = 4);
261 int kernel_total_length()
const override {
return kernel_total_length_value; }
262 posT function_piece(
const posT x,
int p)
const override
264 const posT absx = std::fabs(x);
269 return 13. / 21. + absx * (1. / 14. + absx * (absx / 2 - 1));
272 return 29. / 21. + absx * (-85. / 42. + absx * (1 - absx / 6));
277 posT derivative_piece(
const posT x,
int p)
const override
279 const posT absx = std::fabs(x);
280 const int sign = x > 0 ? 1 : -1;
285 return sign * (1 / 14. + absx * (-2 + 3 * absx / 2));
288 return sign * (-85 / 42. + absx * (2 - absx / 2));
293 int find_piece(
const posT x)
const override {
return static_cast<int>(floor(x)); }
294 int find_highest_piece()
const override {
return 1; }
297static const BSplineFunction<near_n, pos_type> near_n_BSpline_function;
298static const BSplineFunction<linear, pos_type> linear_BSpline_function;
299static const BSplineFunction<quadratic, pos_type> quadratic_BSpline_function;
300static const BSplineFunction<cubic, pos_type> cubic_BSpline_function;
301static const BSplineFunction<oMoms, pos_type> oMoms_BSpline_function;
303inline const PieceWiseFunction<pos_type>&
304bspline_function(BSplineType type)
309 return near_n_BSpline_function;
311 return linear_BSpline_function;
313 return quadratic_BSpline_function;
315 return cubic_BSpline_function;
317 return oMoms_BSpline_function;
319 std::cerr <<
"quartic,quantic to do\n";
321 return cubic_BSpline_function;
325template <
typename posT>
327cubic_BSplines_weight(
const posT relative_position)
329 const posT abs_relative_position = fabs(relative_position);
330 assert(abs_relative_position >= 0);
331 if (abs_relative_position < 1)
332 return 2. / 3. + (0.5 * abs_relative_position - 1) * abs_relative_position * abs_relative_position;
333 if (abs_relative_position >= 2)
335 const posT tmp = 2 - abs_relative_position;
336 return tmp * tmp * tmp / 6;
339template <
typename posT>
341oMoms_weight(
const posT relative_position)
343 const posT abs_relative_position = fabs(relative_position);
344 assert(abs_relative_position >= 0);
345 if (abs_relative_position >= 2)
347 if (abs_relative_position >= 1)
348 return 29. / 21. + abs_relative_position * (-85. / 42. + abs_relative_position * (1. - abs_relative_position / 6));
350 return 13. / 21. + abs_relative_position * (1. / 14. + abs_relative_position * (0.5 * abs_relative_position - 1.));
353template <
typename posT>
355cubic_BSplines_1st_der_weight(
const posT relative_position)
357 const posT abs_relative_position = fabs(relative_position);
358 if (abs_relative_position >= 2)
360 int sign = relative_position > 0 ? 1 : -1;
361 if (abs_relative_position >= 1)
362 return -0.5 * sign * (abs_relative_position - 2) * (abs_relative_position - 2);
363 return sign * abs_relative_position * (1.5 * abs_relative_position - 2.);
366template <
typename posT>
373 return cubic_BSplines_1st_der_weight(relative_position);
375 error(
"BSplines_1st_der_weight currently only implemented for cubic splines.");
381template <
typename posT>
383BSplines_weights(
const posT relative_position,
const BSplineType spline_type)
389 return cubic_BSplines_weight(relative_position);
391 if (fabs(relative_position) < 0.5)
393 if (fabs(relative_position) == 0.5)
399 if (fabs(relative_position) < 1)
400 return 1 - fabs(relative_position);
405 return BSplineFunction<quadratic, posT>().function(relative_position);
407 return (pow(std::max(0., -3. + relative_position), 5) - 6 * pow(std::max(0., -2. + relative_position), 5)
408 + 15 * pow(std::max(0., -1. + relative_position), 5)
409 - 20 * pow(std::max(
static_cast<posT
>(0), relative_position), 5) + 15 * pow(std::max(0., 1. + relative_position), 5)
410 - 6 * pow(std::max(0., 2. + relative_position), 5) + pow(std::max(0., 3. + relative_position), 5))
413 return oMoms_weight(relative_position);
415 error(
"Not implemented b-spline type");
Declaration of stir::error()
pos_type BSplines_1st_der_weight(const pos_type relative_position, const BSplineType spline_type)
return value of the first derivative of the spline
pos_type BSplines_weights(const pos_type relative_position, const BSplineType spline_type)
return spline value
void error(const char *const s,...)
Print error with format string a la printf and throw exception.
Definition error.cxx:42
NUMBER square(const NUMBER &x)
returns the square of a number, templated.
Definition common.h:154