Low commit activity in last 3 years
Descriptive statistics, linear interpolation, rounding modes, and moving averages. Lightweight math toolkit with zero dependencies.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

philiprehberger-math_kit

Tests Gem Version Last updated

Statistics, regression, interpolation, rounding modes, and moving averages for Ruby

Requirements

  • Ruby >= 3.1

Installation

Add to your Gemfile:

gem "philiprehberger-math_kit"

Or install directly:

gem install philiprehberger-math_kit

Usage

require "philiprehberger/math_kit"

Statistics

Philiprehberger::MathKit::Stats.mean([1, 2, 3, 4, 5])       # => 3.0
Philiprehberger::MathKit::Stats.median([3, 1, 4, 1, 5])      # => 3.0
Philiprehberger::MathKit::Stats.mode([1, 2, 2, 3])            # => [2]
Philiprehberger::MathKit::Stats.variance([2, 4, 4, 4, 5, 5, 7, 9])  # => 4.0
Philiprehberger::MathKit::Stats.stddev([2, 4, 4, 4, 5, 5, 7, 9])    # => 2.0
Philiprehberger::MathKit::Stats.percentile([1, 2, 3, 4, 5], 50)      # => 3.0
Philiprehberger::MathKit::Stats.sum([1, 2, 3])                # => 6
Philiprehberger::MathKit::Stats.range([1, 5, 3, 9, 2])        # => 8
Philiprehberger::MathKit::Stats.sum_of_squares([1, 2, 3])     # => 2.0

Interquartile Range

Philiprehberger::MathKit::Stats.iqr([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])  # => 4.5

Summary Statistics

Philiprehberger::MathKit::Stats.describe([1, 2, 3, 4, 5])
# => { count: 5, mean: 3.0, median: 3.0, min: 1.0, max: 5.0,
#      stddev: 1.58..., variance: 2.5, p25: 2.0, p50: 3.0, p75: 4.0 }

Weighted Mean

Philiprehberger::MathKit::Stats.weighted_mean([10, 20, 30], weights: [3, 1, 1])
# => 16.0

Histogram

Philiprehberger::MathKit::Stats.histogram([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], bins: 5)
# => [{ min: 1.0, max: 2.8, count: 2 }, { min: 2.8, max: 4.6, count: 2 }, ...]

Skewness and Kurtosis

Philiprehberger::MathKit::Stats.skewness([1, 1, 1, 2, 5, 10])  # => positive (right-skewed)
Philiprehberger::MathKit::Stats.kurtosis([2, 3, 4, 5, 6, 7])   # => near 0 (normal-like)

Confidence Intervals

data = [10, 12, 14, 16, 18]
lower, upper = Philiprehberger::MathKit::Stats.confidence_interval(data, level: 0.95)
# => [9.87, 18.13] (approximate)

Correlation and Covariance

Philiprehberger::MathKit::Stats.correlation([1, 2, 3, 4], [2, 4, 6, 8])  # => 1.0
Philiprehberger::MathKit::Stats.covariance([1, 2, 3, 4], [2, 4, 6, 8])   # => 3.333...

Data Normalization

Philiprehberger::MathKit::Stats.normalize([10, 20, 30])       # => [0.0, 0.5, 1.0]
Philiprehberger::MathKit::Stats.standardize([10, 20, 30, 40]) # => z-scores (mean=0, stddev=1)

Robust Statistics

Philiprehberger::MathKit::Stats.median_absolute_deviation([1, 1, 2, 2, 4, 6, 9])  # => 1.0
Philiprehberger::MathKit::Stats.trimmed_mean([1, 2, 3, 4, 100], trim: 0.2)        # => 3.0
Philiprehberger::MathKit::Stats.winsorized_mean([1, 2, 3, 4, 100], trim: 0.2)     # => less affected by outlier

Linear Regression

result = Philiprehberger::MathKit::Regression.linear([1, 2, 3, 4], [2, 4, 6, 8])
result.slope      # => 2.0
result.intercept  # => 0.0
result.r_squared  # => 1.0
result.predict(5) # => 10.0

Interpolation

points = [[0, 0], [5, 10], [10, 20]]
Philiprehberger::MathKit::Interpolation.linear(points, 2.5)  # => 5.0
Philiprehberger::MathKit::Interpolation.linear(points, 7.5)  # => 15.0

Rounding

Philiprehberger::MathKit::Round.bankers(2.5)                  # => 2.0 (round half to even)
Philiprehberger::MathKit::Round.bankers(3.5)                  # => 4.0
Philiprehberger::MathKit::Round.ceiling(2.1)                  # => 3.0
Philiprehberger::MathKit::Round.floor(2.9)                    # => 2.0
Philiprehberger::MathKit::Round.truncate(2.9)                 # => 2.0
Philiprehberger::MathKit::Round.bankers(2.55, precision: 1)   # => 2.6

Moving Averages

Philiprehberger::MathKit::MovingAverage.simple([1, 2, 3, 4, 5], window: 3)      # => [2.0, 3.0, 4.0]
Philiprehberger::MathKit::MovingAverage.exponential([1, 2, 3, 4, 5], alpha: 0.5) # => [1.0, 1.5, 2.25, 3.125, 4.0625]

Numeric Helpers

Philiprehberger::MathKit::Numeric.factorial(5)      # => 120
Philiprehberger::MathKit::Numeric.fibonacci(10)     # => 55
Philiprehberger::MathKit::Numeric.gcd(12, 18)       # => 6
Philiprehberger::MathKit::Numeric.lcm(4, 6)         # => 12
Philiprehberger::MathKit::Numeric.clamp(42, 0, 10)  # => 10

API

Stats

Method Description
.mean(values) Arithmetic mean
.median(values) Median (middle value or average of two middle)
.mode(values) Mode(s) as array
.variance(values, population: true) Population or sample variance
.stddev(values, population: true) Standard deviation
.percentile(values, p) Percentile (0-100) with linear interpolation
.iqr(values) Interquartile range (Q3 - Q1)
.sum(values) Sum of values
.sum_of_squares(values) Sum of squared deviations from the mean (0.0 for empty/single input)
.range(values) Max - min
.skewness(values) Sample skewness (Fisher-Pearson)
.kurtosis(values) Sample excess kurtosis (Fisher definition)
.confidence_interval(values, level: 0.95) Confidence interval for the mean
.correlation(xs, ys) Pearson correlation coefficient
.covariance(xs, ys) Sample covariance
.normalize(values) Min-max normalization to 0..1
.standardize(values) Z-score standardization (mean=0, stddev=1)
.median_absolute_deviation(values) Median absolute deviation
.trimmed_mean(values, trim: 0.1) Trimmed mean (remove fraction from each end)
.winsorized_mean(values, trim: 0.1) Winsorized mean (clamp extremes)
.describe(values) Summary statistics hash (count, mean, median, min, max, stddev, percentiles)
.histogram(values, bins: 10) Frequency distribution as array of bin hashes
.weighted_mean(values, weights:) Weighted arithmetic mean

Regression

Method Description
.linear(xs, ys) Ordinary least squares linear regression
Result#slope Slope of the fitted line
Result#intercept Y-intercept of the fitted line
Result#r_squared Coefficient of determination (0 to 1)
Result#predict(x) Predict y for a given x

Interpolation

Method Description
.linear(points, x) Linear interpolation between sorted points

Round

Method Description
.bankers(value, precision: 0) Banker's rounding (round half to even)
.ceiling(value, precision: 0) Round up
.floor(value, precision: 0) Round down
.truncate(value, precision: 0) Truncate toward zero

MovingAverage

Method Description
.simple(values, window:) Simple moving average
.exponential(values, alpha:) Exponential moving average

Numeric

Method Description
.factorial(n) Factorial of a non-negative integer
.fibonacci(n) N-th Fibonacci number (0-indexed)
.gcd(a, b) Greatest common divisor of two integers
.lcm(a, b) Least common multiple of two integers
.clamp(value, min, max) Clamp a numeric value between min and max

Development

bundle install
bundle exec rspec
bundle exec rubocop

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT