2#include "LinAlg/include.hpp"
3#include "qip/Vector.hpp"
4#include <gsl/gsl_bspline.h>
5#include <gsl/gsl_version.h>
12#ifdef GSL_MAJOR_VERSION
13#if GSL_MAJOR_VERSION == 1
17#if GSL_MAJOR_VERSION <= 2 && GSL_MINOR_VERSION < 8
18#define GSL_VERSION_PRIOR_2_8
55 gsl_bspline_workspace *gsl_bspl_work{
nullptr};
59 gsl_bspline_deriv_workspace *gsl_bspl_deriv_work{
nullptr};
82 BSpline(std::size_t n, std::size_t k,
double x0,
double xmax,
84 : m_K(k), m_N(n), m_xmax(xmax) {
85 assert(m_N > m_K &&
"Require N>K for B-splines");
86 assert(xmax > x0 && x0 > 0.0 && xmax > 0.0 &&
"xmax>x0 and both positive");
89 const std::size_t n_break = m_N - m_K + 2;
90 gsl_bspl_work = gsl_bspline_alloc(m_K, n_break);
94 gsl_bspl_deriv_work = gsl_bspline_deriv_alloc(m_K);
97 set_knots(x0, xmax, n_break, kd);
100#ifdef GSL_VERSION_PRIOR_2_8
102 assert(gsl_bspline_ncoeffs(gsl_bspl_work) == m_N);
104 assert(gsl_bspline_ncontrol(gsl_bspl_work) == m_N);
106 assert(gsl_bspline_order(gsl_bspl_work) == m_K);
107 assert(gsl_bspline_nbreak(gsl_bspl_work) == n_break);
116 gsl_bspline_free(gsl_bspl_work);
118 gsl_bspline_deriv_free(gsl_bspl_deriv_work);
124 std::size_t
K() {
return m_K; }
126 std::size_t
d() {
return m_K - 1; }
128 std::size_t
N() {
return m_N; }
135 for (std::size_t i = 0; i < m_N; ++i) {
136 if (gsl_vector_get(gsl_bspl_work->knots, i + m_K) > x) {
146 std::vector<double>
get(
double x) {
147 std::vector<double> b(m_N);
148 gsl_vector_view b_gsl = gsl_vector_view_array(b.data(), b.size());
149 if (x >= 0.0 && x <= m_xmax) {
151#ifdef GSL_VERSION_PRIOR_2_8
153 gsl_bspline_eval(x, &b_gsl.vector, gsl_bspl_work);
155 gsl_bspline_eval_basis(x, &b_gsl.vector, gsl_bspl_work);
181 std::pair<std::size_t, LinAlg::Matrix<double>>
183 std::pair<std::size_t, LinAlg::Matrix<double>> out{0, {m_K, n_deriv + 1}};
185 if (x >= 0.0 && x <= m_xmax) {
189 auto &i0 = out.first;
190 auto &bij = out.second;
191 gsl_matrix_view b_gsl = bij.as_gsl_view();
195 gsl_bspline_deriv_eval_nonzero(x, n_deriv, &b_gsl.matrix, &i0, &i_end,
196 gsl_bspl_work, gsl_bspl_deriv_work);
197#elif defined GSL_VERSION_PRIOR_2_8
199 gsl_bspline_deriv_eval_nonzero(x, n_deriv, &b_gsl.matrix, &i0, &i_end,
202 gsl_bspline_basis_deriv(x, n_deriv, &b_gsl.matrix, &i0, gsl_bspl_work);
213 std::size_t n_cols_to_print = 4;
214 std::cout <<
"Knots:\n ";
215 std::size_t count = 0;
216 while (count < m_N + m_K) {
217 auto t = gsl_bspl_work->knots->data[count];
220 if (count % n_cols_to_print == 0)
223 if (count % n_cols_to_print != 0)
229 void set_knots(
double x0,
double xmax, std::size_t n_break,
KnotDistro kd) {
244 std::vector<double>{};
246 breaks.insert(breaks.begin(), 0.0);
248 auto gsl_break_vec = gsl_vector_view_array(breaks.data(), breaks.size());
250#ifdef GSL_VERSION_PRIOR_2_8
252 gsl_bspline_knots(&gsl_break_vec.vector, gsl_bspl_work);
254 gsl_bspline_init_augment(&gsl_break_vec.vector, gsl_bspl_work);
Basis of N B-splines of order K (degree K-1), defined over [0, xmax].
Definition BSpline.hpp:46
std::size_t d()
Degree of the splines, d := K-1.
Definition BSpline.hpp:126
BSpline(std::size_t n, std::size_t k, double x0, double xmax, KnotDistro kd=KnotDistro::logarithmic)
Construct a basis of N B-splines of order K over [0, xmax].
Definition BSpline.hpp:82
KnotDistro
Distribution of internal knot points.
Definition BSpline.hpp:64
@ logarithmic
Knots on a logarithmic scale (default; suits bound-state grids)
@ linear
Knots evenly spaced.
@ loglinear
Log-linear blend; midpoint at xmax/2.
BSpline & operator=(const BSpline &)=delete
Copy assignment deleted: GSL workspace is not copyable.
void print_knots() const
Prints the full knot vector to stdout (N+K values).
Definition BSpline.hpp:211
std::size_t find_i0(double x)
Returns the index i0 of the first non-zero spline at x. Spline indices run [0, N); at most K splines ...
Definition BSpline.hpp:134
std::pair< std::size_t, LinAlg::Matrix< double > > get_nonzero(double x, std::size_t n_deriv)
Returns the non-zero splines and their derivatives at x.
Definition BSpline.hpp:182
std::vector< double > get(double x)
Returns all N spline values {b_0(x), b_1(x), ..., b_{N-1}(x)}. Returns a vector of zeros if x is outs...
Definition BSpline.hpp:146
std::size_t K()
Order of the splines, K.
Definition BSpline.hpp:124
std::size_t N()
Number of splines, N.
Definition BSpline.hpp:128
BSpline(const BSpline &)=delete
Copy construction deleted: GSL workspace is not copyable.
std::vector< T > logarithmic_range(T first, T last, N number)
Returns a logarithmically distributed range [first, last] with number points.
Definition Vector.hpp:283
std::vector< T > uniform_range(T first, T last, N number)
Returns a uniformly distributed range [first, last] with number points.
Definition Vector.hpp:252
std::vector< T > loglinear_range(T first, T last, T b, N number)
Returns a log-linear distributed range [first, last] with number points.
Definition Vector.hpp:316