Skip to main content

High-performance LOWESS smoothing for Rust, Python, and R.

Project description

LOWESS Project

License Docs Crates.io PyPI Conda R-universe

The fastest, most robust, and most feature-complete language-agnostic LOWESS (Locally Weighted Scatterplot Smoothing) implementation for Rust, Python, and R.

Overview

This monorepo contains a complete ecosystem for LOWESS smoothing:

  • lowess - Core single-threaded implementation with no_std support
  • fastLowess - Parallel CPU and GPU-accelerated wrapper with ndarray integration
  • Python bindings - PyO3-based Python package
  • R bindings - extendr-based R package

Documentation

[!NOTE]

📚 View the full documentation

Why this package?

Speed

The lowess project crushes the competition in terms of speed, wether in single-threaded or multi-threaded parallel execution.

Speedup relative to Python's statsmodels.lowess (higher is better):

Category statsmodels R (stats) Serial Parallel GPU
Clustered 163ms 83× 203× 433× 32×
Constant Y 134ms 92× 212× 410× 18×
Delta (large–none) 105ms 16×
Extreme Outliers 489ms 106× 201× 388× 29×
Financial (500–10K) 106ms 105× 252× 293× 12×
Fraction (0.05–0.67) 221ms 104× 228× 391× 22×
Genomic (1K–50K) 1833ms 20× 95×
High Noise 435ms 133× 134× 375× 32×
Iterations (0–10) 204ms 115× 224× 386× 18×
Scale (1K–50K) 1841ms 264× 487× 581× 98×
Scientific (500–10K) 167ms 109× 205× 314× 15×
Scale Large* (100K–2M) 1.4× 0.3×

*Scale Large benchmarks are relative to Serial (statsmodels cannot handle these sizes)

The numbers are the average across a range of scenarios for each category (e.g., Delta from none, to small, medium, and large).

Robustness

This implementation is more robust than R's lowess and Python's statsmodels due to two key design choices:

MAD-Based Scale Estimation:

For robustness weight calculations, this crate uses Median Absolute Deviation (MAD) for scale estimation:

s = median(|r_i - median(r)|)

In contrast, statsmodels and R's lowess uses the median of absolute residuals (MAR):

s = median(|r_i|)
  • MAD is a breakdown-point-optimal estimator—it remains valid even when up to 50% of data are outliers.
  • The median-centering step removes asymmetric bias from residual distributions.
  • MAD provides consistent outlier detection regardless of whether residuals are centered around zero.

Boundary Padding:

This crate applies a range of different boundary policies at dataset edges:

  • Extend: Repeats edge values to maintain local neighborhood size.
  • Reflect: Mirrors data symmetrically around boundaries.
  • Zero: Pads with zeros (useful for signal processing).
  • NoBoundary: Original Cleveland behavior

statsmodels and R's lowess do not apply boundary padding, which can lead to:

  • Biased estimates near boundaries due to asymmetric local neighborhoods.
  • Increased variance at the edges of the smoothed curve.

Features

A variety of features, supporting a range of use cases:

Feature This package statsmodels R (stats)
Kernel 7 options only Tricube only Tricube
Robustness Weighting 3 options only Huber only Huber
Scale Estimation 2 options only MAR only MAR
Boundary Padding 4 options no padding no padding
Zero Weight Fallback 3 options no no
Auto Convergence yes no no
Online Mode yes no no
Streaming Mode yes no no
Confidence Intervals yes no no
Prediction Intervals yes no no
Cross-Validation 2 options no no
Parallel Execution yes no no
GPU Acceleration yes* no no
no-std Support yes no no

* GPU acceleration is currently in beta and may not be available on all platforms.

Validation

All implementations are numerical twins of R's lowess:

Aspect Status Details
Accuracy ✅ EXACT MATCH Max diff < 1e-12 across all scenarios
Consistency ✅ PERFECT Multiple scenarios pass with strict tolerance
Robustness ✅ VERIFIED Robust smoothing matches R exactly

Installation

Currently available for R, Python, and Rust:

R (from R-universe, recommended):

install.packages("rfastlowess", repos = "https://thisisamirv.r-universe.dev")

Python (from PyPI):

pip install fastlowess

Or from conda-forge:

conda install -c conda-forge fastlowess

Rust (lowess, no_std compatible):

[dependencies]
lowess = "0.99"

Rust (fastLowess, parallel + GPU):

[dependencies]
fastLowess = { version = "0.99", features = ["cpu"] }

Quick Example

R:

library(rfastlowess)

x <- c(1, 2, 3, 4, 5)
y <- c(2.0, 4.1, 5.9, 8.2, 9.8)

result <- fastlowess(x, y, fraction = 0.5, iterations = 3)
print(result$y)

Python:

import fastlowess as fl
import numpy as np

x = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
y = np.array([2.0, 4.1, 5.9, 8.2, 9.8])

result = fl.smooth(x, y, fraction=0.5, iterations=3)
print(result["y"])

Rust:

use lowess::prelude::*;

let x = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let y = vec![2.0, 4.1, 5.9, 8.2, 9.8];

let model = Lowess::new()
    .fraction(0.5)
    .iterations(3)
    .adapter(Batch)
    .build()?;

let result = model.fit(&x, &y)?;
println!("{}", result);

API Reference

R:

fastlowess(
    x, y,
    fraction = 0.5,
    iterations = 3L,
    delta = 0.01,
    weight_function = "tricube",
    robustness_method = "bisquare",
    zero_weight_fallback = "use_local_mean",
    boundary_policy = "extend",
    confidence_intervals = 0.95,
    prediction_intervals = 0.95,
    return_diagnostics = TRUE,
    return_residuals = TRUE,
    return_robustness_weights = TRUE,
    cv_fractions = c(0.3, 0.5, 0.7),
    cv_method = "kfold",
    cv_k = 5L,
    auto_converge = 1e-4,
    parallel = TRUE
)

Python:

fastlowess.smooth(
    x, y,
    fraction=0.5,
    iterations=3,
    delta=0.01,
    weight_function="tricube",
    robustness_method="bisquare",
    zero_weight_fallback="use_local_mean",
    boundary_policy="extend",
    confidence_intervals=0.95,
    prediction_intervals=0.95,
    return_diagnostics=True,
    return_residuals=True,
    return_robustness_weights=True,
    cv_fractions=[0.3, 0.5, 0.7],
    cv_method="kfold",
    cv_k=5,
    auto_converge=1e-4,
    parallel=True
)

Rust:

Lowess::new()
    .fraction(0.5)              // Smoothing span (0, 1]
    .iterations(3)              // Robustness iterations
    .delta(0.01)                // Interpolation threshold
    .weight_function(Tricube)   // Kernel selection
    .robustness_method(Bisquare)
    .zero_weight_fallback(UseLocalMean)
    .boundary_policy(Extend)
    .confidence_intervals(0.95)
    .prediction_intervals(0.95)
    .return_diagnostics()
    .return_residuals()
    .return_robustness_weights()
    .cross_validate(KFold(5, &[0.3, 0.5, 0.7]).seed(123))
    .auto_converge(1e-4)
    .adapter(Batch)             // or Streaming, Online
    .parallel(true)             // fastLowess only
    .backend(CPU)               // fastLowess only: CPU or GPU
    .build()?;

Result Structure

R:

result$x, result$y, result$standard_errors
result$confidence_lower, result$confidence_upper
result$prediction_lower, result$prediction_upper
result$residuals, result$robustness_weights
result$diagnostics, result$iterations_used
result$fraction_used, result$cv_scores

Python:

result.x, result.y, result.standard_errors
result.confidence_lower, result.confidence_upper
result.prediction_lower, result.prediction_upper
result.residuals, result.robustness_weights
result.diagnostics, result.iterations_used
result.fraction_used, result.cv_scores

Rust:

pub struct LowessResult<T> {
    pub x: Vec<T>,                           // Sorted x values
    pub y: Vec<T>,                           // Smoothed y values
    pub standard_errors: Option<Vec<T>>,
    pub confidence_lower: Option<Vec<T>>,
    pub confidence_upper: Option<Vec<T>>,
    pub prediction_lower: Option<Vec<T>>,
    pub prediction_upper: Option<Vec<T>>,
    pub residuals: Option<Vec<T>>,
    pub robustness_weights: Option<Vec<T>>,
    pub diagnostics: Option<Diagnostics<T>>,
    pub iterations_used: Option<usize>,
    pub fraction_used: T,
    pub cv_scores: Option<Vec<T>>,
}

LOESS vs. LOWESS

Feature LOESS (This Crate) LOWESS
Polynomial Degree Linear, Quadratic, Cubic, Quartic Linear (Degree 1)
Dimensions Multivariate (n-D support) Univariate (1-D only)
Flexibility High (Distance metrics) Standard
Complexity Higher (Matrix inversion) Lower (Weighted average/slope)

[!TIP] Note: For a LOESS implementation, use loess-project.


Contributing

Contributions are welcome! Please see the CONTRIBUTING.md file for more information.

License

Licensed under either of:

at your option.

References

  • Cleveland, W.S. (1979). "Robust Locally Weighted Regression and Smoothing Scatterplots". JASA.
  • Cleveland, W.S. (1981). "LOWESS: A Program for Smoothing Scatterplots". The American Statistician.

Citation

If you use this software in your research, please cite it using the CITATION.cff file or the BibTeX entry below:

@software{lowess_project,
  author = {Valizadeh, Amir},
  title = {LOWESS Project: High-Performance Locally Weighted Scatterplot Smoothing},
  year = {2026},
  url = {https://github.com/thisisamirv/lowess-project},
  license = {MIT OR Apache-2.0}
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastlowess-0.99.5.tar.gz (117.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fastlowess-0.99.5-cp38-abi3-win_amd64.whl (324.8 kB view details)

Uploaded CPython 3.8+Windows x86-64

fastlowess-0.99.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (451.8 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

fastlowess-0.99.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (437.0 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

fastlowess-0.99.5-cp38-abi3-macosx_11_0_arm64.whl (399.8 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

fastlowess-0.99.5-cp38-abi3-macosx_10_12_x86_64.whl (425.7 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file fastlowess-0.99.5.tar.gz.

File metadata

  • Download URL: fastlowess-0.99.5.tar.gz
  • Upload date:
  • Size: 117.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastlowess-0.99.5.tar.gz
Algorithm Hash digest
SHA256 fcebcc128fc717e4740782892b9306a3c0c0a60025baa2502cd7622ccdb8fc68
MD5 54d4f5284f8bc2856cc736efa9c6060c
BLAKE2b-256 ccfe3b89a4f2b439be6f5e1cab1eacdb746b9ccd3450ccb238cd0aa4707814dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.5.tar.gz:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.5-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: fastlowess-0.99.5-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 324.8 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastlowess-0.99.5-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4d3afe79d3bac4ea48c899a784e212fac8363c3df41799a8ed459636587e67f2
MD5 ffb17be0b9e3fc8917f59d207289c58c
BLAKE2b-256 3290a58bc7c2406ade6568874261fd0b1bd26b52d726fbac444152461ee1335d

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.5-cp38-abi3-win_amd64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 554f46294f5f93cd064f9819da135ecbe62db0b05a8a6bc2c76099d235e42f84
MD5 12661d8631a53a84c60a2c94a92f6c16
BLAKE2b-256 c2076e75daf48e75aaf24a0f9e7ce457eecccc0a59906258223756892d68a7ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 ed1fb101c70e40a605637df8a1f303f688249020b5565774ec6078c3991a794c
MD5 653b9c1d9d5d0d9d94c9fae29cf49a99
BLAKE2b-256 13d47f118671dbe96020777581eeec59c92d8b85acd859421476e336f9a53639

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.5-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.5-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 56fd672595e6b2f4d537c86f849a9f45dd6ae79d96d44863d5808118374e03d8
MD5 7ebeb86a0238bca19e63b3d2f632da69
BLAKE2b-256 6a90689d64e4a890f8f7232596e9c25d4f9ec98b6f130d778dbfa59323fc44cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.5-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fastlowess-0.99.5-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for fastlowess-0.99.5-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fb73892fbe68b67b9276c3e1733cccf099e1b66798f6feed59959da35afd5a8f
MD5 a55a81d993e0c683cc82ca2a0241b99d
BLAKE2b-256 3a22f34ead28bb89e045f98aac57249fc9c8fa19630828dd822891ac8e07970b

See more details on using hashes here.

Provenance

The following attestation bundles were made for fastlowess-0.99.5-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on thisisamirv/lowess-project

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page