Mantid
Loading...
Searching...
No Matches
GSL_Helpers.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2025 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
9#include <gsl/gsl_errno.h>
10#include <gsl/gsl_fft_halfcomplex.h>
11#include <gsl/gsl_fft_real.h>
12#include <gsl/gsl_spline.h>
13
15
16#include <memory>
17#include <span>
18#include <vector>
19
21
23struct GSLFree {
24 void operator()(gsl_fft_real_wavetable *p) { gsl_fft_real_wavetable_free(p); }
25 void operator()(gsl_fft_real_workspace *p) { gsl_fft_real_workspace_free(p); }
26 void operator()(gsl_fft_halfcomplex_wavetable *p) { gsl_fft_halfcomplex_wavetable_free(p); }
27};
28
29using real_wt_uptr = std::unique_ptr<gsl_fft_real_wavetable, GSLFree>;
30using real_ws_uptr = std::unique_ptr<gsl_fft_real_workspace, GSLFree>;
31using hc_wt_uptr = std::unique_ptr<gsl_fft_halfcomplex_wavetable, GSLFree>;
32
33inline real_wt_uptr make_gsl_real_wavetable(std::size_t dn) { return real_wt_uptr(gsl_fft_real_wavetable_alloc(dn)); }
34inline real_ws_uptr make_gsl_real_workspace(std::size_t dn) { return real_ws_uptr(gsl_fft_real_workspace_alloc(dn)); }
35inline hc_wt_uptr make_gsl_hc_wavetable(std::size_t dn) { return hc_wt_uptr(gsl_fft_halfcomplex_wavetable_alloc(dn)); }
36} // namespace Mantid::Kernel::fft
37
39
41constexpr unsigned int MIN_CSPLINE_POINTS{3};
42
44struct GSLFree {
45 void operator()(gsl_spline *spline) { gsl_spline_free(spline); }
46 void operator()(gsl_interp_accel *acc) { gsl_interp_accel_free(acc); }
47};
48
49using accel_uptr = std::unique_ptr<gsl_interp_accel, GSLFree>;
50using spline_uptr = std::unique_ptr<gsl_spline, GSLFree>;
51
53 accel_uptr acc(gsl_interp_accel_alloc());
54 if (!acc) {
55 throw std::runtime_error("Failed to allocate a GSL interpolation accelerator");
56 }
57 return acc;
58}
59
60template <typename X, typename Y>
61spline_uptr make_spline(std::span<X const> x, std::span<Y const> y, gsl_interp_type const *type) {
62 std::size_t N = x.size();
63 if (N != y.size()) {
64 throw std::runtime_error(Strings::strmakef("x and y lengths for spline don't match: %zu vs %zu", N, y.size()));
65 }
66 if (N == 0) {
67 throw std::runtime_error("A spline requires non-empty vectors");
68 }
69 spline_uptr spline(gsl_spline_alloc(type, N));
70 if (!spline) {
71 throw std::runtime_error(Strings::strmakef("Failed to allocate a GSL spline with %zu points", N));
72 }
73 int status = gsl_spline_init(spline.get(), x.data(), y.data(), N);
74 if (status != GSL_SUCCESS) {
75 throw std::runtime_error("Failed to initialize GSL spline: " + std::string(gsl_strerror(status)));
76 }
77 return spline;
78}
79
80template <typename X, typename Y> spline_uptr make_cubic_spline(std::span<X const> x, std::span<Y const> y) {
81 std::size_t N = x.size();
82 if (N < MIN_CSPLINE_POINTS) {
83 throw std::runtime_error(
84 Strings::strmakef("A cubic spline requires %u points, given vector with %zu points", MIN_CSPLINE_POINTS, N));
85 }
86 return make_spline(x, y, gsl_interp_cspline);
87}
88} // namespace Mantid::Kernel::spline
MANTID_KERNEL_DLL std::string strmakef(char const *const fmt,...)
This is the constructor that std::string needed to have.
Definition Strings.cpp:1205
real_wt_uptr make_gsl_real_wavetable(std::size_t dn)
Definition GSL_Helpers.h:33
std::unique_ptr< gsl_fft_halfcomplex_wavetable, GSLFree > hc_wt_uptr
Definition GSL_Helpers.h:31
std::unique_ptr< gsl_fft_real_workspace, GSLFree > real_ws_uptr
Definition GSL_Helpers.h:30
hc_wt_uptr make_gsl_hc_wavetable(std::size_t dn)
Definition GSL_Helpers.h:35
real_ws_uptr make_gsl_real_workspace(std::size_t dn)
Definition GSL_Helpers.h:34
std::unique_ptr< gsl_fft_real_wavetable, GSLFree > real_wt_uptr
Definition GSL_Helpers.h:29
std::unique_ptr< gsl_interp_accel, GSLFree > accel_uptr
Definition GSL_Helpers.h:49
spline_uptr make_cubic_spline(std::span< X const > x, std::span< Y const > y)
Definition GSL_Helpers.h:80
constexpr unsigned int MIN_CSPLINE_POINTS
Minimum number of points needed to fit a cubic spline in GSL.
Definition GSL_Helpers.h:41
spline_uptr make_spline(std::span< X const > x, std::span< Y const > y, gsl_interp_type const *type)
Definition GSL_Helpers.h:61
accel_uptr make_interp_accel()
Definition GSL_Helpers.h:52
std::unique_ptr< gsl_spline, GSLFree > spline_uptr
Definition GSL_Helpers.h:50
Functor to free GSL objects in a unique pointer.
Definition GSL_Helpers.h:23
void operator()(gsl_fft_real_workspace *p)
Definition GSL_Helpers.h:25
void operator()(gsl_fft_halfcomplex_wavetable *p)
Definition GSL_Helpers.h:26
void operator()(gsl_fft_real_wavetable *p)
Definition GSL_Helpers.h:24
Functor to free a GSL objects in a unique pointer.
Definition GSL_Helpers.h:44
void operator()(gsl_spline *spline)
Definition GSL_Helpers.h:45
void operator()(gsl_interp_accel *acc)
Definition GSL_Helpers.h:46