Skip to content

Commit daa3962

Browse files
committed
Implement 'digitize' function
1 parent 188f2c8 commit daa3962

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/csaps.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <iostream>
2+
#include <cmath>
23

34
#include "csaps.h"
45

@@ -86,6 +87,17 @@ void UnivariateCubicSmoothingSpline::MakeSpline()
8687

8788
DoubleArray 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

src/csaps.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@
22
#ifndef CSAPS_H
33
#define CSAPS_H
44

5+
#include <limits>
6+
57
#include <Eigen/Dense>
68

79

810
namespace csaps
911
{
1012

1113
typedef Eigen::ArrayXd DoubleArray;
14+
typedef Eigen::Array<Eigen::DenseIndex, Eigen::Dynamic, 1> IndexArray;
15+
16+
typedef std::numeric_limits<double> DoubleLimits;
1217

1318

1419
class UnivariateCubicSmoothingSpline
@@ -27,8 +32,13 @@ class UnivariateCubicSmoothingSpline
2732

2833
void MakeSpline();
2934
DoubleArray Evaluate(const DoubleArray &xidata);
35+
36+
//! Calculate the 1-th discrete difference
3037
static DoubleArray Diff(const DoubleArray &vec);
3138

39+
//! Return the indices of the bins to which each value in input array belongs
40+
static IndexArray Digitize(const DoubleArray &arr, const DoubleArray &bins);
41+
3242
protected:
3343
DoubleArray m_xdata;
3444
DoubleArray m_ydata;

0 commit comments

Comments
 (0)