Module: MoreMath::Functions

Extended by:
Math
Included in:
ChiSquareDistribution, NormalDistribution, NumberifyStringFunction, TDistribution
Defined in:
lib/more_math/functions.rb

Overview

Provides mathematical functions and special functions for scientific computing.

This module includes implementations of various mathematical functions commonly used in statistics, numerical analysis, and scientific computing. It extends Ruby’s built-in Math module with additional functionality and provides specialized implementations for better accuracy and performance.

Examples:

Using mathematical functions

include MoreMath::Functions

# Gamma function calculation
gamma(5)        # => ~ 24.0 (4!)
gamma(0.5)      # => ~ 1.772 (sqrt(pi))

# Beta function calculation
beta(2, 3)      # => ~ 0.083 (B(2,3) = Gamma(2)*Gamma(3)/Gamma(5))

# Error function
erf(1)          # => ~ 0.843

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.beta(a, b) ⇒ Float

Returns the value of the beta function for (a, b), +a > 0, b > 0’.

The beta function B(a,b) = Gamma(a)*Gamma(b)/Gamma(a+b) is used in statistical distributions and probability theory.

Parameters:

  • a (Numeric)

    First parameter (must be > 0)

  • b (Numeric)

    Second parameter (must be > 0)

Returns:

  • (Float)

    The beta function value at (a,b)



101
102
103
104
105
106
107
# File 'lib/more_math/functions.rb', line 101

def beta(a, b)
  if a > 0 && b > 0
    exp(log_beta(a, b))
  else
    0.0 / 0
  end
end

.beta_regularized(x, a, b, epsilon: 1E-16, max_iterations: 1 << 16) ⇒ Float

Return an approximation value of Euler’s regularized beta function for x, a, and b with an error <= epsilon, but only iterate max_iterations-times.

The regularized incomplete beta function I_x(a,b) = B(x;a,b)/B(a,b) is used in statistics to compute probabilities for the beta distribution.

Parameters:

  • x (Numeric)

    The upper limit of integration (0 <= x <= 1)

  • a (Numeric)

    First shape parameter (a > 0)

  • b (Numeric)

    Second shape parameter (b > 0)

  • epsilon (Float) (defaults to: 1E-16)

    Convergence tolerance (default: 1E-16)

  • max_iterations (Integer) (defaults to: 1 << 16)

    Maximum number of iterations (default: 65536)

Returns:

  • (Float)

    Regularized incomplete beta function value



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/more_math/functions.rb', line 122

def beta_regularized(x, a, b, epsilon: 1E-16, max_iterations: 1 << 16)
  x, a, b = x.to_f, a.to_f, b.to_f
  case
  when a.nan? || b.nan? || x.nan? || a <= 0 || b <= 0 || x < 0 || x > 1
    0 / 0.0
  when x > (a + 1) / (a + b + 2)
    1 - beta_regularized(1 - x, b, a, epsilon: epsilon, max_iterations: max_iterations)
  else
    fraction = ContinuedFraction.for_b do |n, y|
      if n % 2 == 0
        m = n / 2.0
        (m * (b - m) * y) / ((a + (2 * m) - 1) * (a + (2 * m)))
      else
        m = (n - 1) / 2.0
        -((a + m) * (a + b + m) * y) / ((a + 2 * m) * (a + 2 * m + 1))
      end
    end
    exp(a * log(x) + b * log(1.0 - x) - log(a) - log_beta(a, b)) /
      fraction[x, epsilon: epsilon, max_iterations: max_iterations]
  end
rescue Errno::ERANGE, Errno::EDOM
  0 / 0.0
end

.cantor_pairing(*xs) ⇒ Integer

Returns Cantor’s tuple function for the tuple *xs (the size must be at least 2).

The Cantor pairing function uniquely encodes pairs of natural numbers into a single natural number. This implementation extends it to tuples.

Parameters:

  • xs (Array<Integer>)

    Array of integers to encode

Returns:

  • (Integer)

    Unique natural number representing the tuple



308
309
310
# File 'lib/more_math/functions.rb', line 308

def cantor_pairing(*xs)
  CantorPairingFunction.cantor_pairing(*xs)
end

.cantor_pairing_inv(c, n = 2) ⇒ Array<Integer>

Returns the inverse of Cantor’s tuple function for the value c. n is the length of the tuple (defaults to 2, a pair).

Decodes a natural number back into its original tuple representation.

Parameters:

  • c (Integer)

    The encoded natural number

  • n (Integer) (defaults to: 2)

    Length of the original tuple (default: 2)

Returns:

  • (Array<Integer>)

    Original tuple as array of integers



320
321
322
# File 'lib/more_math/functions.rb', line 320

def cantor_pairing_inv(c, n = 2)
  CantorPairingFunction.cantor_pairing_inv(c, n)
end

.gamma(x) ⇒ Float

Returns the value of the gamma function, extended to a negative domain.

The gamma function is defined for all complex numbers except non-positive integers. For positive real numbers, it extends the factorial: Gamma(n) = (n-1)!

Parameters:

  • x (Numeric)

    The input value for which to calculate gamma

Returns:

  • (Float)

    The gamma function value at x

Raises:

  • (ZeroDivisionError)

    When x is a non-positive integer



71
72
73
74
75
76
77
# File 'lib/more_math/functions.rb', line 71

def gamma(x)
  if x < 0.0
    return PI / (sin(PI * x) * exp(log_gamma(1 - x)))
  else
    exp(log_gamma(x))
  end
end

.gammaP_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16) ⇒ Float

Return an approximation of the regularized gammaP function for x and a with an error of <= epsilon, but only iterate max_iterations-times.

The regularized lower incomplete gamma function P(a,x) = γ(a,x)/Γ(a) where γ(a,x) is the lower incomplete gamma function. This is used in statistics to compute probabilities for the gamma distribution.

Parameters:

  • x (Numeric)

    Upper limit of integration (x >= 0)

  • a (Numeric)

    Shape parameter (a > 0)

  • epsilon (Float) (defaults to: 1E-16)

    Convergence tolerance (default: 1E-16)

  • max_iterations (Integer) (defaults to: 1 << 16)

    Maximum number of iterations (default: 65536)

Returns:

  • (Float)

    Regularized lower incomplete gamma function value



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/more_math/functions.rb', line 159

def gammaP_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16)
  x, a = x.to_f, a.to_f
  case
  when a.nan? || x.nan? || a <= 0 || x < 0
    0 / 0.0
  when x == 0
    0.0
  when 1 <= a && a < x
    1 - gammaQ_regularized(x, a, epsilon: epsilon, max_iterations: max_iterations)
  else
    n = 0
    an = 1 / a
    sum = an
    while an.abs > epsilon && n < max_iterations
      n += 1
      an *= x / (a + n)
      sum += an
    end
    if n >= max_iterations
      raise Errno::ERANGE
    else
      exp(-x + a * log(x) - log_gamma(a)) * sum
    end
  end
rescue Errno::ERANGE, Errno::EDOM
  0 / 0.0
end

.gammaQ_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16) ⇒ Float

Return an approximation of the regularized gammaQ function for x and a with an error of <= epsilon, but only iterate max_iterations-times.

The regularized upper incomplete gamma function Q(a,x) = Γ(a,x)/Γ(a) where Γ(a,x) is the upper incomplete gamma function. This is used in statistics to compute probabilities for the gamma distribution.

Parameters:

  • x (Numeric)

    Upper limit of integration (x >= 0)

  • a (Numeric)

    Shape parameter (a > 0)

  • epsilon (Float) (defaults to: 1E-16)

    Convergence tolerance (default: 1E-16)

  • max_iterations (Integer) (defaults to: 1 << 16)

    Maximum number of iterations (default: 65536)

Returns:

  • (Float)

    Regularized upper incomplete gamma function value



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/more_math/functions.rb', line 200

def gammaQ_regularized(x, a, epsilon: 1E-16, max_iterations: 1 << 16)
  x, a = x.to_f, a.to_f
  case
  when a.nan? || x.nan? || a <= 0 || x < 0
    0 / 0.0
  when x == 0
    1.0
  when a > x || a < 1
    1 - gammaP_regularized(x, a, epsilon: epsilon, max_iterations: max_iterations)
  else
    fraction = ContinuedFraction.for_a do |n, y|
      (2 * n + 1) - a + y
    end.for_b do |n, y|
      n * (a - n)
    end
    exp(-x + a * log(x) - log_gamma(a)) *
      fraction[x, epsilon: epsilon, max_iterations: max_iterations] ** -1
  end
rescue Errno::ERANGE, Errno::EDOM
  0 / 0.0
end

.log_beta(a, b) ⇒ Float

Returns the natural logarithm of the beta function value for (a, b).

The beta function is defined as B(a,b) = Gamma(a)*Gamma(b)/Gamma(a+b) and is commonly used in statistics and probability theory.

Parameters:

  • a (Numeric)

    First parameter of the beta function

  • b (Numeric)

    Second parameter of the beta function

Returns:

  • (Float)

    Natural logarithm of the beta function at (a,b)



87
88
89
90
91
# File 'lib/more_math/functions.rb', line 87

def log_beta(a, b)
  log_gamma(a) + log_gamma(b) - log_gamma(a + b)
rescue Errno::ERANGE, Errno::EDOM
  0 / 0.0
end

.log_ceil(n, b = 2) ⇒ Integer

Computes the ceiling of the base b logarithm of n.

Returns the smallest integer k such that b^k >= n.

Parameters:

  • n (Integer)

    The number to compute log for (must be > 0)

  • b (Integer) (defaults to: 2)

    The base of the logarithm (must be > 1)

Returns:

  • (Integer)

    Ceiling of log_b(n)

Raises:

  • (ArgumentError)

    If n <= 0 or b <= 1



260
261
262
263
264
265
266
267
268
269
# File 'lib/more_math/functions.rb', line 260

def log_ceil(n, b = 2)
  raise ArgumentError, "n is required to be > 0" unless n > 0
  raise ArgumentError, "b is required to be > 1" unless b > 1
  e, result = 1, 0
  until e >= n
    e *= b
    result += 1
  end
  result
end

.log_floor(n, b = 2) ⇒ Integer

Computes the floor of the base b logarithm of n.

Returns the largest integer k such that b^k <= n.

Parameters:

  • n (Integer)

    The number to compute log for (must be > 0)

  • b (Integer) (defaults to: 2)

    The base of the logarithm (must be > 1)

Returns:

  • (Integer)

    Floor of log_b(n)

Raises:

  • (ArgumentError)

    If n <= 0 or b <= 1



279
280
281
282
283
284
285
286
287
288
# File 'lib/more_math/functions.rb', line 279

def log_floor(n, b = 2)
  raise ArgumentError, "n is required to be > 0" unless n > 0
  raise ArgumentError, "b is required to be > 1" unless b > 1
  e, result = 1, 0
  until e * b > n
    e *= b
    result += 1
  end
  result
end

.logb(x, b = 2) ⇒ Float

Returns the base b logarithm of the number x. b defaults to base 2, binary logarithm.

Parameters:

  • x (Numeric)

    The number to compute log for (must be > 0)

  • b (Numeric) (defaults to: 2)

    The base of the logarithm (default: 2)

Returns:

  • (Float)

    Logarithm of x in base b



296
297
298
# File 'lib/more_math/functions.rb', line 296

def logb(x, b = 2)
  Math.log(x) / Math.log(b)
end

.numberify_string(string, alphabet = 'a'..'z') ⇒ Integer

Computes a Gödel number from string in the alphabet and returns it.

Implements Gödel numbering to convert strings into unique natural numbers.

Parameters:

  • string (String)

    The input string

  • alphabet (Array<String>, Range<String>) (defaults to: 'a'..'z')

    The alphabet to use for conversion

Returns:

  • (Integer)

    Unique Gödel number representing the string



331
332
333
# File 'lib/more_math/functions.rb', line 331

def numberify_string(string, alphabet = 'a'..'z')
  NumberifyStringFunction.numberify_string(string, alphabet)
end

.stringify_number(number, alphabet = 'a'..'z') ⇒ String

Computes the string in the alphabet from a Gödel number number and returns it. This is the inverse function of numberify_string.

Converts a natural number back to its original string representation.

Parameters:

  • number (Integer)

    The Gödel number to convert

  • alphabet (Array<String>, Range<String>) (defaults to: 'a'..'z')

    The alphabet to use for conversion

Returns:

  • (String)

    Original string represented by the number



343
344
345
# File 'lib/more_math/functions.rb', line 343

def stringify_number(number, alphabet = 'a'..'z')
  NumberifyStringFunction.stringify_number(number, alphabet)
end

Instance Method Details

#erf(x) ⇒ Float

Returns an approximate value for the error function’s value for x unless provided by Ruby.

The error function erf(x) = (2/sqrt(pi)) * ∫₀ˣ e^(-t²) dt is used in probability, statistics, and partial differential equations.

Parameters:

  • x (Numeric)

    Input value

Returns:

  • (Float)

    Error function value at x



231
232
233
234
235
# File 'lib/more_math/functions.rb', line 231

def erf(x)
  erf_a = MoreMath::Constants::FunctionsConstants::ERF_A
  r = sqrt(1 - exp(-x ** 2 * (4 / Math::PI + erf_a * x ** 2) / (1 + erf_a * x ** 2)))
  x < 0 ? -r : r
end

#erfc(x) ⇒ Float

Returns the complementary error function value for x unless provided by Ruby.

The complementary error function erfc(x) = 1 - erf(x) is used in probability and statistics when computing tail probabilities.

Parameters:

  • x (Numeric)

    Input value

Returns:

  • (Float)

    Complementary error function value at x



247
248
249
# File 'lib/more_math/functions.rb', line 247

def erfc(x)
  1.0 - erf(x)
end

#log_gamma(x) ⇒ Object

Returns the natural logarithm of Euler gamma function value for x using the Lanczos approximation if not provided by Ruby.



37
38
39
# File 'lib/more_math/functions.rb', line 37

def log_gamma(x)
  lgamma(x).first
end