20#ifndef __stir_numerics_BSplinesDetail_inl_
21# define __stir_numerics_BSplinesDetail_inl_
29template <
typename constantsT>
31set_BSpline_values(constantsT& z1, constantsT& z2, constantsT& lambda,
const BSplineType spline_type)
36 z1 =
static_cast<constantsT
>(0);
37 z2 =
static_cast<constantsT
>(0);
40 z1 =
static_cast<constantsT
>(0);
41 z2 =
static_cast<constantsT
>(0);
44 z1 =
static_cast<constantsT
>(sqrt(8.) - 3);
45 z2 =
static_cast<constantsT
>(0);
48 z1 =
static_cast<constantsT
>(sqrt(3.) - 2);
49 z2 =
static_cast<constantsT
>(0);
52 z1 =
static_cast<constantsT
>(sqrt(664. - sqrt(438976.)) + sqrt(304.) - 19.);
53 z2 =
static_cast<constantsT
>(sqrt(664. - sqrt(438976.)) - sqrt(304.) - 19.);
56 z1 =
static_cast<constantsT
>(0.5 * (sqrt(270. - sqrt(70980.)) + sqrt(105.) - 13.));
57 z2 =
static_cast<constantsT
>(0.5 * (sqrt(270. - sqrt(70980.)) - sqrt(105.) - 13.));
60 z1 =
static_cast<constantsT
>((sqrt(105.) - 13.) / 8.);
61 z2 =
static_cast<constantsT
>(0);
64 lambda =
static_cast<constantsT
>((1. - z1) * (1. - (1. / z1)));
65 if (z2 !=
static_cast<constantsT
>(0))
66 lambda *=
static_cast<constantsT
>((1. - z2) * (1. - (1. / z2)));
70template <
typename out_elemT,
typename in_elemT,
typename constantsT>
72set_coef(Array<1, out_elemT>& coeffs,
73 const Array<1, in_elemT>& input,
74 const BasicCoordinate<1, constantsT>& z1s,
75 const BasicCoordinate<1, constantsT>& z2s,
76 const BasicCoordinate<1, constantsT>& lambdas)
78 BSplines_coef(coeffs.begin(), coeffs.end(), input.begin(), input.end(), z1s[1], z2s[1], lambdas[1]);
81template <
int num_dimensions,
typename out_elemT,
typename in_elemT,
typename constantsT>
83set_coef(Array<num_dimensions, out_elemT>& coeffs,
84 const Array<num_dimensions, in_elemT>& input,
85 const BasicCoordinate<num_dimensions, constantsT>& z1s,
86 const BasicCoordinate<num_dimensions, constantsT>& z2s,
87 const BasicCoordinate<num_dimensions, constantsT>& lambdas)
89 Array<num_dimensions, out_elemT> temp(input.get_index_range());
90 BSplines_coef(temp.begin(), temp.end(), input.begin(), input.end(), z1s[1], z2s[1], lambdas[1]);
92 for (
int i = coeffs.get_min_index(); i <= coeffs.get_max_index(); ++i)
99 template <
typename pos_type>
103 pos_type operator()(
const pos_type p,
const BSplineType type)
109 template <
typename pos_type>
113 pos_type operator()(
const pos_type p,
const BSplineType type)
119template <
typename pos_type>
123 pos_type operator()(
const pos_type pos,
int piece,
const PieceWiseFunction<pos_type>& f)
125 return f.function_piece(pos, piece);
129template <
typename pos_type>
133 pos_type operator()(
const pos_type pos,
int piece,
const PieceWiseFunction<pos_type>& f)
135 return f.derivative_piece(pos, piece);
145template <
int num_dimensions,
int num_dimensions2,
typename T,
typename FunctionT,
typename SplineFunctionT>
146inline typename SplineFunctionT::result_type
147spline_convolution(
const Array<num_dimensions, T>& coeffs,
148 const BasicCoordinate<num_dimensions2, pos_type>& relative_positions,
149 const BasicCoordinate<num_dimensions2, BSplineType>& spline_types,
153 const int current_dimension = num_dimensions2 - num_dimensions + 1;
154 const PieceWiseFunction<pos_type>& bspline = bspline_function(spline_types[current_dimension]);
156 typename SplineFunctionT::result_type value;
158 const int kmin =
static_cast<int>(std::ceil(relative_positions[current_dimension] - bspline.kernel_length_right()));
159 const int kmax = kmin + bspline.kernel_total_length() - 1;
161 pos_type current_pos = relative_positions[current_dimension] - k;
167 int p = bspline.find_piece(current_pos);
172 for (; k <= kmax; ++k, --current_pos DECR_P)
175 if (k < coeffs.get_min_index())
176 index = 2 * coeffs.get_min_index() - k;
177 else if (k > coeffs.get_max_index())
178 index = 2 * coeffs.get_max_index() - k;
181 assert(coeffs.get_min_index() <= index && index <= coeffs.get_max_index());
182 value +=
static_cast<typename SplineFunctionT::result_type
>(g(coeffs[index], relative_positions, spline_types) *
184 f(current_pos, p, bspline)
186 f(current_pos, spline_types[current_dimension])
193template <
int num_dimensions2,
typename T,
typename FunctionT>
195spline_convolution(
const Array<1, T>& coeffs,
196 const BasicCoordinate<num_dimensions2, pos_type>& relative_positions,
197 const BasicCoordinate<num_dimensions2, BSplineType>& spline_types,
200 const int current_dimension = num_dimensions2;
201 const PieceWiseFunction<pos_type>& bspline = bspline_function(spline_types[current_dimension]);
205 const int kmin =
static_cast<int>(std::ceil(relative_positions[current_dimension] - bspline.kernel_length_right()));
206 const int kmax = kmin + bspline.kernel_total_length() - 1;
208 pos_type current_pos = relative_positions[current_dimension] - k;
213 int p = bspline.find_piece(current_pos);
218 for (; k <= kmax; ++k, --current_pos DECR_P)
221 if (k < coeffs.get_min_index())
222 index = 2 * coeffs.get_min_index() - k;
223 else if (k > coeffs.get_max_index())
224 index = 2 * coeffs.get_max_index() - k;
227 assert(coeffs.get_min_index() <= index && index <= coeffs.get_max_index());
228 value +=
static_cast<T
>(coeffs[index] *
230 f(current_pos, p, bspline)
233 f(current_pos, spline_types[current_dimension])
240template <
int num_dimensions,
int num_dimensions2,
typename T>
241struct compute_BSplines_value
243 typedef T result_type;
244 T operator()(
const Array<num_dimensions, T>& coeffs,
245 const BasicCoordinate<num_dimensions2, pos_type>& relative_positions,
246 const BasicCoordinate<num_dimensions2, BSplineType>& spline_types)
const
248 return spline_convolution(coeffs,
253 compute_BSplines_value<num_dimensions - 1, num_dimensions2, T>());
257template <
typename T,
int num_dimensions2>
258struct compute_BSplines_value<1, num_dimensions2, T>
260 typedef T result_type;
261 T operator()(
const Array<1, T>& coeffs,
262 const BasicCoordinate<num_dimensions2, pos_type>& relative_positions,
263 const BasicCoordinate<num_dimensions2, BSplineType>& spline_types)
const
265 return spline_convolution(coeffs, relative_positions, spline_types, BW<pos_type>()
271template <
int num_dimensions,
int num_dimensions2,
typename T>
272struct compute_BSplines_gradient
274 typedef BasicCoordinate<num_dimensions, T> result_type;
276 BasicCoordinate<num_dimensions, T> operator()(
const Array<num_dimensions, T>& coeffs,
277 const BasicCoordinate<num_dimensions2, pos_type>& relative_positions,
278 const BasicCoordinate<num_dimensions2, BSplineType>& spline_types)
const
280 const T first_value = spline_convolution(coeffs,
285 compute_BSplines_value<num_dimensions - 1, num_dimensions2, T>());
286 const BasicCoordinate<num_dimensions - 1, T> rest_value
287 = spline_convolution(coeffs,
292 compute_BSplines_gradient<num_dimensions - 1, num_dimensions2, T>());
293 return join(first_value, rest_value);
297template <
int num_dimensions2,
typename T>
298struct compute_BSplines_gradient<1, num_dimensions2, T>
300 typedef BasicCoordinate<1, T> result_type;
302 BasicCoordinate<1, T> operator()(
const Array<1, T>& coeffs,
303 const BasicCoordinate<num_dimensions2, pos_type>& relative_positions,
304 const BasicCoordinate<num_dimensions2, BSplineType>& spline_types)
const
306 BasicCoordinate<1, T> result;
307 result[1] = spline_convolution(coeffs, relative_positions, spline_types, Bder<pos_type>()
defines the stir::assign function to assign values to different data types
pos_type BSplines_1st_der_weight(const pos_type relative_position, const BSplineType spline_type)
return value of the first derivative of the spline
double pos_type
The type used for relative positions between the grid points.
Definition BSplines.h:32
pos_type BSplines_weights(const pos_type relative_position, const BSplineType spline_type)
return spline value
BasicCoordinate< num_dimensions+1, coordT > join(const coordT &a, const BasicCoordinate< num_dimensions, coordT > &c)
make a longer BasicCoordinate, by prepending c with the single coordT
Definition BasicCoordinate.inl:447
BasicCoordinate< num_dimensions - 1, coordT > cut_first_dimension(const BasicCoordinate< num_dimensions, coordT > &c)
make a shorter BasicCoordinate, by cutting the first element from c
Definition BasicCoordinate.inl:477
void BSplines_coef(RandIterOut c_begin_iterator, RandIterOut c_end_iterator, IterT input_begin_iterator, IterT input_end_iterator, const constantsT z1, const constantsT z2, const constantsT lambda)
compute BSpline coefficients that gives the BSpline that interpolates the given data
Definition BSplines_coef.inl:56