Class: Xirr::NewtonMethod
- Inherits:
-
Object
- Object
- Xirr::NewtonMethod
- Includes:
- Base
- Defined in:
- lib/xirr/newton_method.rb
Overview
Plain Newton-Raphson: step from the guess by -xnpv/xnpv' until the step is
smaller than the tolerance. Fast when it converges, but with no bracketing it
can walk off to a non-root or below -100%; RtSafe is the safeguarded default
that avoids that. Kept for xirr(method: :newton_method).
Instance Attribute Summary
Attributes included from Base
Instance Method Summary collapse
-
#xirr(guess, options) ⇒ Float?
The rate rounded to
Xirr.config.precision, or nil.
Methods included from Base
#initialize, #periods_from_start, #xnpv, #xnpv_derivative
Instance Method Details
#xirr(guess, options) ⇒ Float?
Returns the rate rounded to Xirr.config.precision, or nil.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/xirr/newton_method.rb', line 14 def xirr(guess, ) limit = ( && [:iteration_limit]) || Xirr.config.iteration_limit rate = (guess || cf.irr_guess).to_f limit.times do derivative = xnpv_derivative(rate) return nil if derivative.zero? step = xnpv(rate).to_f / derivative rate -= step # Below -100% the discount base (1 + rate) turns negative and the next # xnpv raises it to a fractional power, producing a Complex. Bail first. return nil if rate.nan? || rate.infinite? || rate <= -1 break if step.abs < Xirr.config.eps end rate.nan? ? nil : rate.round(Xirr.config.precision) rescue FloatDomainError, Math::DomainError, RangeError nil end |