14 #ifndef SRC_INCLUDE_LOWESS_H_    15 #define SRC_INCLUDE_LOWESS_H_    33 void lowest(
const T *x, 
const T *y, 
size_t n, T xs, T &ys, 
size_t nleft,
    34             size_t nright, T *w, 
bool userw, T *rw, 
bool &ok) {
    41   const auto range = x[
n] - x[1];
    42   const auto h = std::max(xs - x[nleft], x[nright] - xs);
    43   const auto h9 = 0.999 * h;
    44   const auto h1 = 0.001 * h;
    52     const auto r = std::abs(x[j] - xs);
    57         const auto d = (r / h) * (r / h) * (r / h);
    58         w[j] = (1. - d) * (1. - d) * (1. - d);
    63     } 
else if (x[j] > xs) {
    70   const auto nrt = j - 1;
    76     for (j = nleft; j <= nrt; j++)
    81       for (j = nleft; j <= nrt; j++)
    85       for (j = nleft; j <= nrt; j++)
    86         c += w[j] * (x[j] - a) * (x[j] - a);
    87       if (std::sqrt(c) > 0.001 * range) {
    90         for (j = nleft; j <= nrt; j++)
    91           w[j] *= (b * (x[j] - a) + 1.);
    95     for (j = nleft; j <= nrt; j++)
   105 template <
typename T>
   107   for (
size_t pL = 0, pR = n - 1; pL < pR;) {
   111     for (i = pL, j = pR; i <= j;) {
   138 template <
typename T>
   139 void lowess(
const T *x, 
const T *y, 
size_t n, T *ys, T span, 
size_t iter,
   140             T delta, T *rw, T *res) {
   152   constexpr 
size_t two = 2;
   154       std::max(two, std::min(n, static_cast<size_t>(span * n + 1e-7)));
   158   while (iiter <= iter + 1) {
   167         const auto d1 = x[i] - x[nleft];
   168         const auto d2 = x[nright + 1] - x[i];
   180       const bool iterg1 = iiter > 1;
   182       lowest(&x[1], &y[1], n, x[i], ys[i], nleft, nright, res, iterg1, rw, ok);
   188         const auto denom = x[i] - x[last];
   191         for (
auto j = last + 1; j < i; j++) {
   192           const auto alpha = (x[j] - x[last]) / denom;
   193           ys[j] = alpha * ys[i] + (1. - alpha) * ys[last];
   201       const auto cut = x[last] + delta;
   202       for (i = last + 1; i <= 
n; i++) {
   205         if (x[i] == x[last]) {
   210       i = std::max(last + 1, i - 1);
   216     for (i = 0; i < 
n; i++)
   217       res[i] = y[i + 1] - ys[i + 1];
   222     for (i = 0; i < 
n; i++)
   223       rw[i] = std::abs(res[i]);
   226     const auto m1 = n / 2;
   232       const auto m2 = n - m1 - 1;
   234       cmad = 3. * (rw[m1] + rw[m2]);
   239     const auto c9 = 0.999 * cmad;
   240     const auto c1 = 0.001 * cmad;
   241     for (i = 0; i < 
n; i++) {
   249       const auto r = std::abs(res[i]);
   254         rw[i] = (1. - (r / cmad) * (r / cmad)) * (1. - (r / cmad) * (r / cmad));
   288 template <
typename T>
   289 std::vector<T> 
smooth(
const std::vector<T> &x, 
const std::vector<T> &y,
   290                       T span = 2. / 3, 
size_t iter = 3, T delta = 0) {
   291   assert(x.size() == y.size());
   292   std::vector<T> result;
   293   result.resize(x.size());
   297   res.resize(x.size());
   298   lowess::lowess(&x.front(), &y.front(), x.size(), &result.front(), span, iter,
   299                  delta, &rw.front(), &res.front());
   305 #endif  // SRC_INCLUDE_LOWESS_H_ void lowest(const T *x, const T *y, size_t n, T xs, T &ys, size_t nleft, size_t nright, T *w, bool userw, T *rw, bool &ok)
Fit value at x[i] Based on R function lowest: Translated to C++ by C. 
 
constexpr int h1
h₁(1170). 
 
void lowess(const T *x, const T *y, size_t n, T *ys, T span, size_t iter, T delta, T *rw, T *res)
Lowess regression smoother. 
 
std::vector< T > smooth(const std::vector< T > &x, const std::vector< T > &y, T span=2./3, size_t iter=3, T delta=0)
Apply the LOWESS smoother (see the reference below) to the given data (x, y). 
 
void psort(T *x, size_t n, size_t k)
Partial sort.