Class: Flt::Solver::PSolver

Inherits:
Object
  • Object
show all
Defined in:
lib/solver/psolver.rb

Overview

Solver with equation parameters passed in a hash

Example: a simple TVM (Time Value of Money) solver

# ln(x+1)
def lnp1(x)
  v = x + 1
  (v == 1) ? x : (x*ln(v) / (v - 1))
end

tvm = Flt::Solver::PSolver.new(Float.context, Flt.Tolerance(3,:decimals)) do |m, t, m0, pmt, i, p|
  i /= 100
  i /= p
  n = -t
  k = exp(lnp1(i)*n) # (i+1)**n
  # Equation: -m*k = m0 + pmt*(1-k)/i
  m0 + pmt*(Num(1)-k)/i + m*k
end
tvm.default_guesses = 1,2
sol = tvm.root :pmt, :t=>240, :m0=>10000, :m=>0, :i=>3, :p=>12 #, :pmt=>[1,2]
puts sol.inspect # => -55.45975978539105

Instance Method Summary collapse

Constructor Details

#initialize(*args, &blk) ⇒ PSolver

Returns a new instance of PSolver.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/solver/psolver.rb', line 27

def initialize(*args, &blk)
  options = Base.extract_options(*args, &blk)

  @solver_class = options[:solver_class] || RFSecantSolver
  @eqn = options[:equation]
  @vars = Function.parameters(@eqn)
  # alternatively, we could keep @eqn = Function[@eqn] and dispense with @vars

  @default_guesses = options[:default_guesses]

  @context = options[:context]
  @tol = options[:tolerance]
  @solver = nil
end

Instance Method Details

#default_guesses=(*g) ⇒ Object



42
43
44
45
# File 'lib/solver/psolver.rb', line 42

def default_guesses=(*g)
  @default_guesses = g
  @solver = nil
end

#equation_value(v) ⇒ Object



55
56
57
58
59
60
# File 'lib/solver/psolver.rb', line 55

def equation_value(v)
  values = @parameters.merge(@var=>v)
  #@context.math(*values.values_at(*@vars).map{|v| @context.Num(v)}, &@eqn)
  @context.math(*@vars.map{|v| values[v] && @context.Num(values[v])}.compact, &@eqn)
  # equivalent to: @context.math(values, &Function[@eqn]) # which doesn't need @vars
end

#root(var, parameters) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/solver/psolver.rb', line 47

def root(var, parameters)
  init_solver
  @var = var
  @parameters = parameters
  guesses = Array(parameters[var])
  @solver.root *guesses
end