double PiecewiseLinearInterpolation::getValue(double pnt_to_interpolate) const { // search interval that has the point inside std::size_t interval_idx(std::numeric_limits<std::size_t>::max()); if (pnt_to_interpolate <= _supp_pnts.front()) { interval_idx = 0; } else { if (_supp_pnts.back() <= pnt_to_interpolate) { interval_idx = _supp_pnts.size() - 2; } else { auto const& it(std::lower_bound(_supp_pnts.begin(), _supp_pnts.end(), pnt_to_interpolate)); interval_idx = std::distance(_supp_pnts.begin(), it) - 1; } } if (pnt_to_interpolate > _supp_pnts.back()){ return _values_at_supp_pnts[_supp_pnts.size() - 1]; } if (pnt_to_interpolate < _supp_pnts.front()){ return _values_at_supp_pnts[0]; } // compute linear interpolation polynom: y = m * (x - support[i]) + value[i] const double m((_values_at_supp_pnts[interval_idx + 1] - _values_at_supp_pnts[interval_idx]) / (_supp_pnts[interval_idx + 1] - _supp_pnts[interval_idx])); return m * (pnt_to_interpolate - _supp_pnts[interval_idx]) + _values_at_supp_pnts[interval_idx]; }
double PiecewiseLinearInterpolation::getValue(double pnt_to_interpolate) { // search interval that has the point inside size_t interval_idx(std::numeric_limits<size_t>::max()); for (size_t k(1); k < _supporting_points.size() && interval_idx == std::numeric_limits<size_t>::max(); k++) if (_supporting_points[k - 1] <= pnt_to_interpolate && pnt_to_interpolate <= _supporting_points[k]) interval_idx = k - 1; // compute linear interpolation polynom: y = m * x + n long double m((_values_at_supp_pnts[interval_idx + 1] - _values_at_supp_pnts[interval_idx]) / (_supporting_points[interval_idx + 1] - _supporting_points[interval_idx])); // double m ((_values_at_supp_pnts[interval_idx] - _values_at_supp_pnts[interval_idx+1]) / //(_supporting_points[interval_idx] - _supporting_points[interval_idx+1])); // double n (_values_at_supp_pnts[interval_idx+1] - m * _supporting_points[interval_idx+1]); long double n(_values_at_supp_pnts[interval_idx] - m * _supporting_points[interval_idx]); return m * pnt_to_interpolate + n; }
double PiecewiseLinearInterpolation::GetCurveDerivative(double pnt_to_interpolate) const { std::size_t interval_max(std::numeric_limits<std::size_t>::max());//anz std::size_t interval_idx(std::numeric_limits<std::size_t>::max());//anz interval_max = _supp_pnts.size(); if (pnt_to_interpolate <= _supp_pnts.front()) { interval_idx = 0; } else { if (_supp_pnts.back() <= pnt_to_interpolate) { interval_idx = _supp_pnts.size() - 2; } else { auto const& it(std::lower_bound(_supp_pnts.begin(), _supp_pnts.end(), pnt_to_interpolate)); interval_idx = std::distance(_supp_pnts.begin(), it) - 1; } } double sw = getValue(pnt_to_interpolate); if (sw < _values_at_supp_pnts[interval_max - 1]){ sw = _values_at_supp_pnts[interval_max - 1]; interval_idx = interval_max - 1; } else if (sw > _values_at_supp_pnts[0]){ sw = _values_at_supp_pnts[0]; interval_idx = 1; } //interval_idx = interval_max - 1 - interval_idx; if (interval_idx > 1 && interval_idx < interval_max - 2){ double s1 = (0.5*_supp_pnts[interval_idx] - 0.5*_supp_pnts[interval_idx + 2]) / (0.5*_values_at_supp_pnts[interval_idx] - 0.5*_values_at_supp_pnts[interval_idx + 2]); double s2 = (0.5*_supp_pnts[interval_idx-1] - 0.5*_supp_pnts[interval_idx + 1]) / (0.5*_values_at_supp_pnts[interval_idx-1] - 0.5*_values_at_supp_pnts[interval_idx + 1]); double w = (sw - _values_at_supp_pnts[interval_idx + 1]) / (_values_at_supp_pnts[interval_idx] - _values_at_supp_pnts[interval_idx + 1]); return (1. - w) * s1 + w * s2; } else{ if (std::fabs(_values_at_supp_pnts[interval_idx] - _values_at_supp_pnts[interval_idx + 1])>DBL_MIN) return (_supp_pnts[interval_idx] - _supp_pnts[interval_idx + 1]) / (_values_at_supp_pnts[interval_idx] - _values_at_supp_pnts[interval_idx + 1]); else return 1 / DBL_EPSILON; } }
double PiecewiseLinearInterpolation::getSlope(double pnt_to_interpolate) const { std::size_t interval_idx(std::numeric_limits<std::size_t>::max()); //double eps = 1e-9; if (pnt_to_interpolate <= _supp_pnts.front()) { interval_idx = 0; } else { if (_supp_pnts.back() <= pnt_to_interpolate) { interval_idx = _supp_pnts.size() - 2; } else { auto const& it(std::lower_bound(_supp_pnts.begin(), _supp_pnts.end(), pnt_to_interpolate)); interval_idx = std::distance(_supp_pnts.begin(), it) - 1; } } const double m((_values_at_supp_pnts[interval_idx + 1] - _values_at_supp_pnts[interval_idx]) / (_supp_pnts[interval_idx + 1] - _supp_pnts[interval_idx])); //double m_test = (getValue(pnt_to_interpolate + eps) - getValue(pnt_to_interpolate - eps)) / 2 / eps; return m; }