40 "Extrapolation error."
44 char err_mesg_buf[4096];
45 va_start(args, fmt_string);
46 std::vsnprintf(err_mesg_buf,
sizeof(err_mesg_buf), fmt_string, args);
49 this->
err_mesg = std::string(err_mesg_buf);
59 std::vector<double>& a,
bool check_lin,
bool check_loglin,
bool check_sign
61 std::size_t N = a.size();
64 std::vector<double> diff_a(N - 1);
65 for (std::size_t i = 0; i < N - 1; i++) {
66 diff_a[i] = a[i + 1] - a[i];
72 std::vector<double> diff_loga(N - 1);
73 std::feclearexcept(FE_ALL_EXCEPT);
74 for (std::size_t i = 0; i < N - 1; i++) {
75 diff_loga[i] = std::log(a[i + 1] / a[i]);
76 if (std::fetestexcept(FE_DIVBYZERO) || std::fetestexcept(FE_INVALID)) {
84 for (std::size_t i = 0; i < N - 1; i++) {
85 if (a[i] * a[i + 1] <= 0.0) {
return 3;}
93 std::vector<double>& a,
int N_ext, std::vector<double>& a_ext
97 int N_notch_left = N_ext;
98 int N_notch_right = N_ext + N;
99 int N_extrap = N_ext + N + N_ext;
101 a_ext.resize(N_extrap);
104 double da_left = a[1] - a[0];
105 for (
int i = 0; i < N_notch_left; i++) {
106 a_ext[i] = a.front() + (i - N_notch_left) * da_left;
110 for (
int i = N_notch_left; i < N_notch_right; i++) {
111 a_ext[i] = a[i - N_notch_left];
115 double da_right = a[N - 1] - a[N - 2];
116 for (
int i = N_notch_right; i < N_extrap; i++) {
117 a_ext[i] = a.back() + (i - (N_notch_right - 1)) * da_right;
122 std::vector<double>& a,
int N_ext, std::vector<double>& a_ext
124 std::feclearexcept(FE_ALL_EXCEPT);
128 int N_notch_left = N_ext;
129 int N_notch_right = N_ext + N;
130 int N_extrap = N_ext + N + N_ext;
133 throw std::invalid_argument(
134 "Sign change or zeros detected in the input array."
138 a_ext.resize(N_extrap);
141 double dlna_left = std::log(a[1] / a[0]);
142 if (std::isnan(dlna_left)) {
143 throw std::invalid_argument(
144 "NaN detected at lower-end log-linear spacing."
148 for (
int i = 0; i < N_notch_left; i++) {
149 a_ext[i] = a.front() * std::exp((i - N_notch_left) * dlna_left);
150 if (std::fetestexcept(FE_DIVBYZERO) || std::fetestexcept(FE_INVALID)) {
151 throw std::invalid_argument(
152 "NaN detected at lower-end log-linear extrapolation."
158 for (
int i = N_notch_left; i < N_notch_right; i++) {
159 a_ext[i] = a[i - N_ext];
163 double dlna_right = std::log(a[N - 1] / a[N - 2]);
164 if (std::isnan(dlna_right)) {
165 throw std::invalid_argument(
166 "NaN detected at upper-end log-linear spacing."
170 for (
int i = N_notch_right; i < N_extrap; i++) {
171 a_ext[i] = a.back() * std::exp((i - (N_notch_right - 1)) * dlna_right);
172 if (std::fetestexcept(FE_DIVBYZERO) || std::fetestexcept(FE_INVALID)) {
173 throw std::invalid_argument(
174 "NaN detected at upper-end log-linear extrapolation."
181 std::vector<double>& a,
182 int N_ext,
double c_lower,
double c_upper,
183 std::vector<double>& a_ext
186 int N_notch_left = N_ext;
187 int N_notch_right = N_ext + N;
188 int N_extrap = N_ext + N + N_ext;
190 a_ext.resize(N_extrap);
192 for (
int i = 0; i < N_notch_left; i++) {
195 for (
int i = N_notch_left; i < N_notch_right; i++) {
196 a_ext[i] = a[i - N_notch_left];
198 for (
int i = N_notch_right; i < N_extrap; i++) {
204 std::vector< std::vector<double> >& a,
205 int N_row_ext,
int N_col_ext,
206 std::vector< std::vector<double> >& a_ext
210 "Function `extrap2d_lin` is not yet implemented in the C++ backend."
215 std::vector< std::vector<double> >& a,
216 int N_row_ext,
int N_col_ext,
217 std::vector< std::vector<double> >& a_ext
221 "Function `extrap2d_loglin` is not yet implemented in the C++ backend."
226 std::vector< std::vector<double> >& a,
227 int N_row_ext,
int N_col_ext,
228 double c_row_lower,
double c_row_upper,
229 double c_col_lower,
double c_col_upper,
230 std::vector< std::vector<double> >& a_ext
234 "Function `extrap2d_pad` is not yet implemented in the C++ backend."
245 std::vector<int> indices(sorting_vector.size());
248#if defined(__GNUC__) && !defined(__clang__)
249#pragma omp parallel for simd
251#pragma omp parallel for
254 for (
int i = 0; i < int(sorting_vector.size()); i++) {
259 std::sort(indices.begin(), indices.end(), [&](
int a,
int b) {
260 return sorting_vector[a] < sorting_vector[b];;
Exception raised when a function or method is unimplemented.
int check_1d_array(std::vector< double > &a, bool check_lin, bool check_loglin, bool check_sign)
Check the linearity or log-linearity of a 1-d array.
std::vector< int > get_sorted_indices(std::vector< int > sorting_vector)
Get the sorted indices.
bool check_isclose(const std::vector< T > &arr, const T val, T atol=1.e-8, T rtol=1.e-5)
Check if all elements of a 1-d array are close to a given value.
void extrap2d_loglin(std::vector< std::vector< double > > &a, int N_row_ext, int N_col_ext, std::vector< std::vector< double > > &a_ext)
Extrapolate a 2-d array bi-exponentially (i.e. log-bilinearly).
void extrap_loglin(std::vector< double > &a, int N_ext, std::vector< double > &a_ext)
Extrapolate a 1-d array exponentially (i.e. log-linearly).
void extrap2d_pad(std::vector< std::vector< double > > &a, int N_row_ext, int N_col_ext, double c_row_lower, double c_row_upper, double c_col_lower, double c_col_upper, std::vector< std::vector< double > > &a_ext)
Extrapolate a 2-d array by constant padding.
void extrap2d_lin(std::vector< std::vector< double > > &a, int N_row_ext, int N_col_ext, std::vector< std::vector< double > > &a_ext)
Extrapolate a 2-d array bi-linearly.
void extrap_lin(std::vector< double > &a, int N_ext, std::vector< double > &a_ext)
Extrapolate a 1-d array linearly.
void extrap_pad(std::vector< double > &a, int N_ext, double c_lower, double c_upper, std::vector< double > &a_ext)
Extrapolate a 1-d array by constant padding.