4 #if !defined(__clang_major__) || __clang_major__ < 5
5 # include <ext/algorithm>
7 #include <utl/TabulatedFunction.h>
8 #include <utl/AugerException.h>
9 #include <utl/ErrorLogger.h>
18 TabulatedFunction::FillTable(
const Array& xValues,
21 const unsigned int xSize = xValues.size();
23 if (xSize != yValues.size()) {
25 err <<
"Size of x and y arrays are different.";
33 if (is_sorted(fX.begin(), fX.end()))
37 for (
unsigned int i = 0; i < xSize; ++i) {
38 unsigned int mini = i;
40 for (
unsigned int j = i+1; j < xSize; ++j) {
41 const double x = fX[j];
49 swap(fX[i], fX[mini]);
50 swap(fY[i], fY[mini]);
57 TabulatedFunction::PushBack(
const double x,
const double y)
63 warn <<
"Refusing to push the same x value " << x <<
" twice (y = " << y <<
')';
76 TabulatedFunction::LinearInterpolateY(
double x)
79 const unsigned int size = fX.size();
83 msg <<
"No points in table.";
91 if (x < fX[0] || x > fX[size-1]) {
93 if (x < fX[0] && (fX[0] - x) / (fX[1] - fX[2]) < fBoundaryTolerance)
95 else if (x > fX[size-1] &&
96 (x - fX[size-1]) / (fX[size-1] - fX[size-2]) < fBoundaryTolerance)
99 boost::format err(
"Value x=%.10f is out of table bounds [%.10f, %.12f].");
100 err % x % fX[0] % fX[size-1];
107 const Array::const_iterator xBegin = fX.begin();
108 const Array::const_iterator xIt = upper_bound(xBegin, fX.end(), x);
109 int index = xIt - xBegin - 1;
110 const double x1 = fX[index];
111 const double y1 = fY[index];
115 const double x2 = fX[index];
116 const double y2 = fY[index];
118 return y1 + (y2 - y1)*(x - x1)/(x2 - x1);
123 TabulatedFunction::InterpolateY(
const double x,
const unsigned int polyDegree)
126 const int nn = fX.size();
128 if (nn == 1 && x == fX.front())
131 if (nn < 2 || polyDegree < 1) {
133 msg <<
"Not enough points in table or wrong polynomial degree.";
138 const unsigned int mmax = 10;
139 const int m = min(min(polyDegree, mmax), (
unsigned int)(nn-1));
142 return LinearInterpolateY(x);
147 const Array::const_iterator xBegin = fX.begin();
148 const int ix = upper_bound(xBegin, fX.end(), x) - xBegin - 1;
150 const int mplus = m + 1;
154 int npts = m + 2 - m % 2;
157 for (
int ip = 1, i = 1; ip < npts; ++i)
158 for (
int sign = 1; sign >= -1 && ip < npts; sign -= 2) {
159 const int isub = ix + i*sign;
160 if (0 <= isub && isub < nn) {
168 const bool extra = (npts != mplus);
171 for (
int i = 1; i <=
m; ++i) {
173 const int isub = mplus - i;
174 d[mplus] = (d[mplus] - d[m - 1]) / (t[mplus] - t[isub - 1]);
176 for (
int k = mplus; k > i; --k) {
177 const int k1 = k - 1;
178 const int isub = k - i;
179 d[k1] = (d[k1] - d[k - 2]) / (t[k1] - t[isub - 1]);
187 sum = (sum + d[mplus])/2;
188 for (
int j = m; j; --j)
189 sum = d[j - 1] + (x - t[j - 1])*sum;
196 TabulatedFunction::FindX(
const double x)
199 const Array::const_iterator xBegin = fX.begin();
200 const Array::const_iterator xEnd = fX.end();
201 const Array::const_iterator xIt = lower_bound(xBegin, xEnd, x);
202 if (xIt != xEnd && x == *xIt) {
203 const Array::const_iterator yIt = fY.begin() + (xIt - xBegin);
211 TabulatedFunction::FindY(
const double y)
214 const Array::const_iterator yIt = find(fY.begin(), fY.end(), y);
215 const Array::const_iterator xIt = yIt != fY.end() ?
216 fX.begin() + (yIt - fY.begin()) : fX.end();
222 TabulatedFunction::Insert(
const double x,
const double y)
224 const Array::iterator xIt = lower_bound(fX.begin(), fX.end(), x);
225 const Array::iterator yIt = fY.begin() + (xIt - fX.begin());
226 const Array::iterator ixIt = fX.insert(xIt, x);
227 const Array::iterator iyIt = fY.insert(yIt, y);
void swap(utl::Trace< T > &t1, utl::Trace< T > &t2)
Exception for reporting variable out of valid range.
std::vector< double > Array
#define WARNING(message)
Macro for logging warning messages.
#define ERROR(message)
Macro for logging error messages.
TabulatedPDF::Array Array