|
WeightedLowess
A C++ library for LOWESS with various weighting schemes
|
Namespace for LOWESS functions. More...
Classes | |
| struct | AssignedSegments |
| Assigned segments. More... | |
| struct | Options |
Options for compute(). More... | |
| struct | PrecomputedWindows |
| Precomputed windows for LOWESS smoothing. More... | |
| struct | Results |
| Results of the LOWESS smoother. More... | |
| class | SortBy |
| Utility class for sorting on a covariate. More... | |
Functions | |
| template<typename Data_ > | |
| void | compute (const std::size_t num_points, const Data_ *const x, const PrecomputedWindows< Data_ > &windows, const Data_ *const y, Data_ *const fitted, Data_ *robust_weights, const Options< Data_ > &opt) |
| template<typename Data_ > | |
| void | compute (const std::size_t num_points, const Data_ *const x, const Data_ *const y, Data_ *const fitted, Data_ *const robust_weights, const Options< Data_ > &opt) |
| template<typename Data_ > | |
| Results< Data_ > | compute (const std::size_t num_points, const Data_ *const x, const Data_ *const y, const Options< Data_ > &opt) |
| template<typename Data_ > | |
| AssignedSegments | assign_to_segments (const Data_ *const x_fit, const PrecomputedWindows< Data_ > &windows_fit, const std::size_t num_points_out, const Data_ *const x_out) |
| std::pair< std::size_t, std::size_t > | get_interpolation_boundaries (const AssignedSegments &assigned_out) |
| template<typename Data_ > | |
| void | interpolate (const Data_ *const x_fit, const PrecomputedWindows< Data_ > &windows_fit, const Data_ *const fitted_fit, const Data_ *const x_out, const AssignedSegments &assigned_out, Data_ *const fitted_out, int num_threads) |
| template<typename Data_ > | |
| std::pair< std::size_t, std::size_t > | interpolate (const Data_ *const x_fit, const PrecomputedWindows< Data_ > &windows_fit, const Data_ *const fitted_fit, const std::size_t num_points_out, const Data_ *const x_out, Data_ *const fitted_out, int num_threads) |
| template<typename Task_ , class Run_ > | |
| void | parallelize (const int num_workers, const Task_ num_tasks, Run_ run_task_range) |
| template<typename Data_ > | |
| PrecomputedWindows< Data_ > | define_windows (const std::size_t num_points, const Data_ *const x, const Options< Data_ > &opt) |
Namespace for LOWESS functions.
| AssignedSegments WeightedLowess::assign_to_segments | ( | const Data_ *const | x_fit, |
| const PrecomputedWindows< Data_ > & | windows_fit, | ||
| const std::size_t | num_points_out, | ||
| const Data_ *const | x_out ) |
Assign points-to-be-interpolated to their corresponding segments between anchors, for use in interpolate(). Segments are defined as the line between two adjacent anchors, to be used for linear interpolation of any intervening points.
| Data_ | Floating-point type of the data. |
| [in] | x_fit | Pointer to an array of x-coordinates for the fitted trend from compute(). This should be sorted in increasing order. |
| windows_fit | Precomputed windows for anchor points, created by calling define_windows() on x_fit. | |
| num_points_out | Number of points to be interpolated. | |
| [in] | x_out | Pointer to an array of x-coordinates of the points to be interpolated. This should be sorted in increasing order and have length equal to num_points_out. |
x_out to its corresponding segment, where possible. This can be re-used for multiple interpolate() calls with different fitted values. | Results< Data_ > WeightedLowess::compute | ( | const std::size_t | num_points, |
| const Data_ *const | x, | ||
| const Data_ *const | y, | ||
| const Options< Data_ > & | opt ) |
Overload of compute() that allocates storage for the results of the smoothing.
| Data_ | Floating-point type of the data. |
| num_points | Number of points. | |
| [in] | x | Pointer to an array of num_points x-coordinates, sorted in increasing order. (Consider using SortBy to permute x in-place. Note that the same permutation should be applied to y and, if present, weights in Options::weights.) |
| [in] | y | Pointer to an array of num_points y-coordinates. |
| opt | Further options. |
Results object containing the fitted values and robustness weights. | void WeightedLowess::compute | ( | const std::size_t | num_points, |
| const Data_ *const | x, | ||
| const Data_ *const | y, | ||
| Data_ *const | fitted, | ||
| Data_ *const | robust_weights, | ||
| const Options< Data_ > & | opt ) |
Overload of compute() that computes the windows around each anchor point.
| Data_ | Floating-point type of the data. |
| num_points | Number of points. | |
| [in] | x | Pointer to an array of num_points x-coordinates, sorted in increasing order. (Consider using SortBy to permute x in-place. Note that the same permutation should be applied to y and, if present, weights in Options::weights.) |
| [in] | y | Pointer to an array of num_points y-coordinates. |
| [out] | fitted | Pointer to an output array of length num_points, in which the fitted values of the smoother can be stored. |
| [out] | robust_weights | Pointer to an output array of length num_points, in which the robustness weights can be stored. This may be NULL if the robustness weights are not needed. |
| opt | Further options. |
| void WeightedLowess::compute | ( | const std::size_t | num_points, |
| const Data_ *const | x, | ||
| const PrecomputedWindows< Data_ > & | windows, | ||
| const Data_ *const | y, | ||
| Data_ *const | fitted, | ||
| Data_ * | robust_weights, | ||
| const Options< Data_ > & | opt ) |
Run the LOWESS algorithm for non-parametric smoothing.
First, we identify anchor points that have (roughly) evenly-spaced x-coordinates. For each anchor point, we identify a window of neighboring points and compute a weight for each neighbor based on its distance to the anchor. We perform a weighted linear regression to obtain a fitted value for the anchor. For all non-anchor points, we compute a fitted value via linear interpolation of the surrounding anchor points. We then compute robustness weights for each point based on their deviation from the fitted value; the regressions are then repeated with robustness weights for the specified number of iterations.
| Data_ | Floating-point type of the data. |
| num_points | Number of points. | |
| [in] | x | Pointer to an array of num_points x-coordinates, sorted in increasing order. (Consider using SortBy to permute x in-place. Note that the same permutation should be applied to y and, if present, weights in Options::weights.) |
| windows | Precomputed windows around the anchor points, created by calling define_windows() with num_points, x and opt. This can be re-used across multiple calls to compute() with different y. | |
| [in] | y | Pointer to an array of num_points y-coordinates. |
| [out] | fitted | Pointer to an output array of length num_points, in which the fitted values of the smoother can be stored. |
| [out] | robust_weights | Pointer to an output array of length num_points, in which the robustness weights can be stored. This may be NULL if the robustness weights are not needed. |
| opt | Further options. This should be the same object that is used in define_windows(). Note that only a subset of options are actually used in this overload, namely Options::weights and Options::iterations. |
| PrecomputedWindows< Data_ > WeightedLowess::define_windows | ( | const std::size_t | num_points, |
| const Data_ *const | x, | ||
| const Options< Data_ > & | opt ) |
Identify anchor points and precompute the associated windows prior to LOWESS smoothing via compute(). This avoids wasting time in unnecessarily recomputing the same windows for the same x but different y in multiple compute() calls.
| Data_ | Floating-point type of the data. |
| num_points | Number of points. | |
| [in] | x | Pointer to an array of num_points x-coordinates, sorted in increasing order. (Consider using SortBy to permute the array in-place before calling this function.) |
| opt | Further options. Only a subset of options are actually used here, namely Options::delta, Options::anchors, Options::weights, Options::frequency_weights, Options::span, Options::span_as_proportion, and Options::minimum_width. |
|
inline |
| assigned_out | Assignment of each point-to-be-interpolated to a inter-anchor segment, produced by assign_to_segments(). |
x_out that can be safely interpolated, i.e., do not lie beyond x_fit. | void WeightedLowess::interpolate | ( | const Data_ *const | x_fit, |
| const PrecomputedWindows< Data_ > & | windows_fit, | ||
| const Data_ *const | fitted_fit, | ||
| const Data_ *const | x_out, | ||
| const AssignedSegments & | assigned_out, | ||
| Data_ *const | fitted_out, | ||
| int | num_threads ) |
Interpolate the fitted values for a set of points, based on a pre-existing trend fitted by compute().
In compute(), the LOWESS algorithm calculates fitted values exactly for anchor points and then interpolates the fitted values for all intervening points. This function applies the same interpolation to a separate set of points based only on their x-coordinates.
| Data_ | Floating-point type of the data. |
| [in] | x_fit | Pointer to an array of x-coordinates for the fitted trend from compute(). This should be sorted in increasing order. |
| windows_fit | Precomputed windows for anchor points, created by calling define_windows() on x_fit. | |
| [in] | fitted_fit | Pointer to an array of fitted values from calling compute() with x_fit and windows_fit. This should have the same length as x_fit. |
| [in] | x_out | Pointer to an array of x-coordinates of the points to be interpolated. This should be sorted in increasing order. |
| [in] | assigned_out | Assignment of points-to-be-interpolated to each inter-anchor segment. This should be created by calling assign_to_segment() on x_fit, windows_fit and x_out. |
| [out] | fitted_out | Pointer to an array of same length as x_out. On output, this stores the interpolated fitted value for each entry of x_out that lies within the interpolation boundaries (see get_interpolation_boundaries()). No value is stored for points that lie beyond the interpolation boundaries. |
| num_threads | Number of threads to use. |
| std::pair< std::size_t, std::size_t > WeightedLowess::interpolate | ( | const Data_ *const | x_fit, |
| const PrecomputedWindows< Data_ > & | windows_fit, | ||
| const Data_ *const | fitted_fit, | ||
| const std::size_t | num_points_out, | ||
| const Data_ *const | x_out, | ||
| Data_ *const | fitted_out, | ||
| int | num_threads ) |
Overload of interpolate() that calls assign_to_segments() automatically.
| Data_ | Floating-point type of the data. |
| [in] | x_fit | Pointer to an array of x-coordinates for the fitted trend from compute(). This should be sorted in increasing order. |
| windows_fit | Precomputed windows for anchor points, created by calling define_windows() on x_fit. | |
| [in] | fitted_fit | Pointer to an array of fitted values from calling compute() with x_fit and windows_fit. This should have the same length as x_fit. |
| num_points_out | Number of points to be interpolated. | |
| [in] | x_out | Pointer to an array of x-coordinates of the points to be interpolated. This should be sorted in increasing order. |
| [out] | fitted_out | Pointer to an array of same length as x_out. On output, this stores the interpolated fitted value for each entry of x_out that lies within the interpolation boundaries. No value is stored for points that lie beyond the interpolation boundaries. |
| num_threads | Number of threads to use. |
get_interpolation_boundaries() for details. | void WeightedLowess::parallelize | ( | const int | num_workers, |
| const Task_ | num_tasks, | ||
| Run_ | run_task_range ) |
| Task_ | Integer type of the number of tasks. |
| Run_ | Function to execute a range of tasks. |
| num_workers | Number of workers. |
| num_tasks | Number of tasks. |
| run_task_range | Function to iterate over a range of tasks within a worker. |
By default, this is an alias to subpar::parallelize_range(). However, if the WEIGHTEDLOWESS_CUSTOM_PARALLEL function-like macro is defined, it is called instead. Any user-defined macro should accept the same arguments as subpar::parallelize_range().