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.6094379124341003Now, 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.95A 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.95Licensing
Copyright (c) 2010 Javier Goizueta. See LICENSE for details.