Class: MoreMath::NewtonBisection
- Includes:
- Exceptions
- Defined in:
- lib/more_math/newton_bisection.rb
Overview
This class is used to find the root of a function with Newton’s bisection method.
Instance Attribute Summary collapse
-
#function ⇒ Object
readonly
The function, passed into the constructor.
Instance Method Summary collapse
-
#bracket(range = -1..1, n = 50, factor = 1.6) ⇒ Object
Return a bracket around a root, starting from the initial
range
. -
#initialize(&function) ⇒ NewtonBisection
constructor
Creates a NewtonBisection instance for
function
, a one-argument block. -
#solve(range = nil, n = 1 << 16, epsilon = 1E-16) ⇒ Object
Find the root of function in
range
and return it.
Constructor Details
#initialize(&function) ⇒ NewtonBisection
Creates a NewtonBisection instance for function
, a one-argument block.
10 11 12 |
# File 'lib/more_math/newton_bisection.rb', line 10 def initialize(&function) @function = function end |
Instance Attribute Details
#function ⇒ Object (readonly)
The function, passed into the constructor.
15 16 17 |
# File 'lib/more_math/newton_bisection.rb', line 15 def function @function end |
Instance Method Details
#bracket(range = -1..1, n = 50, factor = 1.6) ⇒ Object
Return a bracket around a root, starting from the initial range
. The method returns nil, if no such bracket around a root could be found after n
tries with the scaling factor
.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/more_math/newton_bisection.rb', line 20 def bracket(range = -1..1, n = 50, factor = 1.6) x1, x2 = range.first.to_f, range.last.to_f x1 >= x2 and raise ArgumentError, "bad initial range #{range}" f1, f2 = @function[x1], @function[x2] n.times do f1 * f2 < 0 and return x1..x2 if f1.abs < f2.abs f1 = @function[x1 += factor * (x1 - x2)] else f2 = @function[x2 += factor * (x2 - x1)] end end return end |
#solve(range = nil, n = 1 << 16, epsilon = 1E-16) ⇒ Object
Find the root of function in range
and return it. The method raises a DivergentException, if no such root could be found after n
tries and in the epsilon
environment.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/more_math/newton_bisection.rb', line 38 def solve(range = nil, n = 1 << 16, epsilon = 1E-16) if range x1, x2 = range.first.to_f, range.last.to_f x1 >= x2 and raise ArgumentError, "bad initial range #{range}" elsif range = bracket x1, x2 = range.first, range.last else raise DivergentException, "bracket could not be determined" end f = @function[x1] fmid = @function[x2] f * fmid >= 0 and raise DivergentException, "root must be bracketed in #{range}" root = if f < 0 dx = x2 - x1 x1 else dx = x1 - x2 x2 end n.times do fmid = @function[xmid = root + (dx *= 0.5)] fmid < 0 and root = xmid dx.abs < epsilon or fmid == 0 and return root end raise DivergentException, "too many iterations (#{n})" end |