module Rical

Constants

VERSION

Public Instance Methods

inv_for(f:, fargs: nil, y: 0.0, **args)
Alias for: inverse_for
inverse_for(f:, fargs: nil, y: 0.0, **args) click to toggle source
# File lib/rical.rb, line 24
def inverse_for f:, fargs: nil, y: 0.0, **args
  f_1 = compute_f_1 f, fargs, y
  root_for f: f_1, fargs: fargs, **args
end
Also aliased as: inv_for
root_for(f:, fargs: nil, df: nil, dfargs: nil, x0: 0.0, x1: 1.0, method:, num: 100, err: 1e-6) click to toggle source
# File lib/rical.rb, line 7
def root_for f:, fargs: nil,
             df: nil, dfargs: nil,
             x0: 0.0, x1: 1.0, method:, num: 100, err: 1e-6
  raise ArgumentError, 'f must respond_to call'    unless f.respond_to? :call

  case method
  when :n, :newton, :newton_raphson
    raise ArgumentError, 'df is required'          unless df
    raise ArgumentError, 'df must respond_to call' unless df.respond_to? :call
    newton_raphson_root_for f, fargs, df, dfargs, Float(x0), num, err
  when :s, :sec, :secant
    secant_root_for f, fargs, Float(x0), Float(x1), num, err
  else
    raise ArgumentError, 'unexpected method (allowed :newton, :secant)'
  end
end

Private Instance Methods

compute(f, x, fargs) click to toggle source
# File lib/rical.rb, line 57
def compute f, x, fargs
  return f.call(x         ) unless fargs
  return f.call(x, **fargs) if     fargs.is_a? Hash
  return f.call(x,  *fargs)
end
compute_f_1(f, fargs, y) click to toggle source
# File lib/rical.rb, line 63
def compute_f_1 f, fargs, y
  return -> (x       ) { f.call(x)          - Float(y) } unless fargs
  return -> (x, **arg) { f.call(x, **fargs) - Float(y) } if     fargs.is_a? Hash
  return -> (x,  *arg) { f.call(x,  *fargs) - Float(y) }
end
newton_raphson_root_for(f, fargs, df, dfargs, x, n, err) click to toggle source
# File lib/rical.rb, line 31
def newton_raphson_root_for f, fargs, df, dfargs, x, n, err
  n.times do
    fx    = compute  f, x, fargs
    slope = compute df, x, dfargs
    slope = 10 * err if slope == 0
    x = x - fx / slope
    return x if compute(f, x, fargs).abs < err
  end
  raise NoConvergenceError
end
secant_root_for(f, fargs, x0, x1, n, err) click to toggle source
# File lib/rical.rb, line 42
def secant_root_for f, fargs, x0, x1, n, err
  n.times do
    fx0 = compute f, x0, fargs
    fx1 = compute f, x1, fargs
    delta = x1 - x0
    delta = 10 * err if delta == 0
    slope = (fx1 - fx0) / delta
    slope = 10 * err if slope == 0
    x = x1 - fx1 / slope
    return x if compute(f, x, fargs).abs < err
    x0, x1 = x1, x
  end
  raise NoConvergenceError
end