11#include < iostream>
2+ #include < cmath>
23
34#include " csaps.h"
45
@@ -86,6 +87,17 @@ void UnivariateCubicSmoothingSpline::MakeSpline()
8687
8788DoubleArray UnivariateCubicSmoothingSpline::Evaluate (const DoubleArray & xidata)
8889{
90+ const size_t pcount = m_xdata.size ();
91+
92+ auto mesh = m_xdata.segment (1 , pcount - 2 );
93+ DoubleArray edges (pcount);
94+
95+ edges (0 ) = -DoubleLimits::infinity ();
96+ edges.segment (1 , pcount - 2 ) = mesh;
97+ edges (pcount - 1 ) = DoubleLimits::infinity ();
98+
99+ auto indexes = Digitize (xidata, edges);
100+
89101 return DoubleArray ();
90102}
91103
@@ -95,4 +107,33 @@ DoubleArray UnivariateCubicSmoothingSpline::Diff(const DoubleArray &vec)
95107 return vec.tail (n) - vec.head (n);
96108}
97109
110+ IndexArray UnivariateCubicSmoothingSpline::Digitize (const DoubleArray &arr, const DoubleArray &bins)
111+ {
112+ // This code works if `arr` and `bins` are monotonically increasing
113+
114+ IndexArray indexes (arr.size ());
115+
116+ // Greater or equal (a >= b)
117+ auto ge = [](double a, double b)
118+ {
119+ return a > b || std::abs (a - b) < std::abs (std::min (a, b)) * 1 .e -8 ;
120+ };
121+
122+ Eigen::DenseIndex kstart = 1 ;
123+
124+ for (Eigen::DenseIndex i = 0 ; i < arr.size (); ++i) {
125+ double val = arr (i);
126+
127+ for (Eigen::DenseIndex k = kstart; k < bins.size (); ++k) {
128+ if (ge (val, bins (k - 1 )) && val < bins (k)) {
129+ indexes (i) = k;
130+ kstart = k;
131+ break ;
132+ }
133+ }
134+ }
135+
136+ return indexes;
137+ }
138+
98139} // namespace csaps
0 commit comments