linear-ransac

Crates.iolinear-ransac
lib.rslinear-ransac
version0.1.0
created_at2025-11-19 15:28:26.272862+00
updated_at2025-11-19 15:28:26.272862+00
descriptionA simple 2D line-fitting RANSAC implementation inspired by scikit-learn's RANSACRegressor.
homepagehttps://github.com/beneficial01/linear-ransac
repositoryhttps://github.com/beneficial01/linear-ransac
max_upload_size
id1940263
size25,134
Mahmoud (Beneficial01)

documentation

https://docs.rs/linear-ransac

README

linear-ransac 🚀

linear-ransac is a Rust implementation of RANSAC (RANdom SAmple Consensus) for fitting a 1D linear model (a line in 2D: y = ax + b), inspired by scikit‑learn’s RANSACRegressor.

It’s built for noisy data with nasty outliers, with automatic thresholding and iteration control so you don’t have to hand‑tune.

Highlights

  • Robust line fitting – estimate slope and intercept from 2D points even when a big chunk of them are garbage.
  • Auto threshold via MAD – inlier cutoff is computed from the median absolute deviation of y, similar in spirit to scikit‑learn’s default.
  • Auto iteration stopping – adapts the max number of RANSAC trials from the current inlier ratio and a stop_probability, while enforcing a configurable minimum so one lucky bad model can’t stop the search early.
  • Final OLS refit – once a consensus set is found, refit the line with ordinary least squares on inliers.

Today it targets 1D linear regression; the design is ready to grow to N‑dimensional linear models later on.

Install

[dependencies]
linear-ransac = "0.1"

Quick start

use linear_ransac::{Point, RansacSolver};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let data = vec![
        Point::new(0.0, 0.0),
        Point::new(1.0, 1.0),
        Point::new(2.0, 2.0),
        Point::new(3.0, 3.0),
    ];

    let model = RansacSolver::new().fit(&data)?;

    println!("slope = {} intercept = {}", model.slope, model.intercept);
    Ok(())
}

With outliers:

use linear_ransac::{Point, RansacSolver};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut data = vec![
        Point::new(0.0, 0.0),
        Point::new(1.0, 1.0),
        Point::new(2.0, 2.0),
        Point::new(3.0, 3.0),
        Point::new(4.0, 4.0),
    ];

    // obvious outliers
    data.push(Point::new(1.5, 100.0));
    data.push(Point::new(2.5, -50.0));

    let model = RansacSolver::new().fit(&data)?;

    println!("slope = {} intercept = {}", model.slope, model.intercept);
    Ok(())
}

Tuning

  • RansacSolver::new() – defaults tuned for typical use.
  • with_seed(u64) – deterministic runs.
  • with_min_trials(usize) – guarantee at least this many iterations.

Internally the solver:

  • derives an inlier threshold from a plain MAD of y values,
  • adapts the iteration budget from the inlier ratio and stop_probability,
  • and refits the final line with OLS on the inliers.

Errors

RansacSolver::fit returns a Result<LinearModel, RansacError>:

  • InsufficientData – not enough points to define a line,
  • ModelFittingFailed – degenerate/numerically unstable data,
  • NoConsensusFound – no good consensus set within the trial budget.

License

MIT. See LICENSE.

Commit count: 0

cargo fmt