54 const std::vector<Real>& q_values,
55 std::vector<Real>& result) {
56 result.assign(q_values.size(), 0.0);
57 if (samples.size() < 2 || spacing <= 0.0)
60 const Real parity_sign = (angular_momentum % 2 == 0) ? 1.0 : -1.0;
61 auto sample_at = [&samples, parity_sign](
long index) ->
Real {
63 return parity_sign * samples[
static_cast<size_t>(-index)];
64 if (index >=
static_cast<long>(samples.size()))
66 return samples[
static_cast<size_t>(index)];
69 const Real last_q =
static_cast<Real>(samples.size() - 1) * spacing;
70 for (
size_t point = 0; point < q_values.size(); point++) {
71 Real q_value = q_values[point];
72 if (q_value < 0.0 || q_value > last_q)
75 Real scaled = q_value / spacing;
76 auto lower =
static_cast<long>(scaled);
77 if (lower >=
static_cast<long>(samples.size()) - 1)
78 lower =
static_cast<long>(samples.size()) - 2;
79 Real fraction = scaled -
static_cast<Real>(lower);
81 Real previous = sample_at(lower - 1);
82 Real current = sample_at(lower);
83 Real next = sample_at(lower + 1);
84 Real after = sample_at(lower + 2);
87 Real a = -0.5 * previous + 1.5 * current - 1.5 * next + 0.5 * after;
88 Real b = previous - 2.5 * current + 2.0 * next - 0.5 * after;
89 Real c = -0.5 * previous + 0.5 * next;
90 result[point] = ((a * fraction + b) * fraction + c) * fraction + current;