Project

solver

0.0
No commit activity in last 3 years
No release in over 3 years
This numeric solver is an example of the use of Flt.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

~> 1.5
 Project Readme

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.