14 #ifndef SRC_INCLUDE_SMASH_LOWESS_H_ 
   15 #define SRC_INCLUDE_SMASH_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());
 
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.
 
void psort(T *x, size_t n, size_t k)
Partial sort.
 
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.
 
constexpr int h1
h₁(1170).
 
const PdgCode d(PdgCode::from_decimal(1000010020))
Deuteron.
 
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).