Skip to content

jgoizueta/solver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

solver

This numeric solver is an example of the use of Flt.

Examples

Solve equation 2*exp(x)-10=0 using Float, with a tolerance of 10 decimal places, using the SecantSolver algorithm and with initial guesses of 0, 10:

require 'solver'
equation = ->(x){ 2*exp(x)-10 }
algorithm = Flt::Solver::SecantSolver
tolerance = Flt::Tolerance(10, :decimals)
solver = algorithm.new(Float.context, tolerance, &equation)
puts solver.root(0, 10) # => 1.6094379124341003

Now, solve the same equation, with the same algorithm, but requiring greater accuracy and using a higher precision numeric type:

tolerance = Flt::Tolerance(25, :decimals)
solver = algorithm.new(Flt::DecNum.context(precision: 30), tolerance, &equation)
puts solver.root(0, 10) # => DecNum('1.609437912434100374600759333')

Let's compute the same using a different algorithm:

algorithm = Flt::Solver::RFSecantSolver
solver = algorithm.new(Flt::DecNum.context(precision: 30), tolerance, &equation)
puts solver.root(0, 10) # => DecNum('1.609437912434100374600759333')

The PSolver class can be used to define an equation with multiple parameters, then solve for any of them.

Let's define an equation to compute the Time Value of Money (i.e. compound interest):

tvm_equation = ->(future_value, time, present_value, payment, interest, payments_per_year) {
  i = interest/100/payments_per_year
  n = -time
  k = (i + 1)**n
  present_value + payment*(1-k)/i + future_value*k
}

Note that computing (i + 1)**n as in this example is not a good idea, see the TVM class for a better approach.

Now let's use PSolver to solve this equation for any of its paramters:

tvm_solver = Flt::Solver::PSolver.new(
  Flt::DecNum.context,
  Flt.Tolerance(2,:decimals),
  &tvm_equation
)

For example, let's compute the monthly payment of a loan of $150,000, to be paid in twenty years with a 7% interest rate:

pmt = tvm_solver.root(
  :payment,
  present_value: 150000,
  future_value: 0,
  time: 20*12,
  interest: 7,
  payments_per_year: 12
)
puts s.round(2) # => -1162.95

A better (more accurate) financial solver is implemented by the TVM class:

tvm = Flt::Solver::TVM.new(Flt.Tolerance(2,:decimals), Flt::DecNum.context)
solution = tvm.solve(t: 20*12, m0: 150000, m: 0, i: 7, p: 12)
puts solution[:pmt].round(2) # => -1162.95

Licensing

Copyright (c) 2010 Javier Goizueta. See LICENSE for details.

About

Numeric solver to exercise the Flt library

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages