In Files

Parent

Files

Bullshit::NewtonBisection

This class is used to find the root of a function with Newton’s bisection method.

Attributes

function[R]

The function, passed into the constructor.

Public Class Methods

new(&function) click to toggle source

Creates a NewtonBisection instance for function, a one-argument block.

# File lib/bullshit.rb, line 610
    def initialize(&function)
      @function = function
    end

Public Instance Methods

bracket(range = -1..1, n = 50, factor = 1.6) click to toggle source

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.

# File lib/bullshit.rb, line 620
    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) click to toggle source

Find the root of function in range and return it. The method raises a BullshitException, if no such root could be found after n tries and in the epsilon environment.

# File lib/bullshit.rb, line 638
    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 ArgumentError, "bracket could not be determined"
      end
      f = @function[x1]
      fmid = @function[x2]
      f * fmid >= 0 and raise ArgumentError, "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 BullshitException, "too many iterations (#{n})"
    end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.