In Files

Parent

Files

Bullshit::ContinuedFraction

This class implements a continued fraction of the form:

                           b_1

a_0 + ————————-

                           b_2
     a_1 + --------------------
                           b_3
          a_2 + ---------------
                           b_4
               a_3 + ----------
                           b_5
                    a_4 + -----
                           ...

Public Class Methods

for_a(arg = nil, &block) click to toggle source

Creates a ContinuedFraction instances and passes its arguments to a call to for_a.

# File lib/bullshit.rb, line 44
    def self.for_a(arg = nil, &block)
      new.for_a(arg, &block)
    end
for_b(arg = nil, &block) click to toggle source

Creates a ContinuedFraction instances and passes its arguments to a call to for_b.

# File lib/bullshit.rb, line 50
    def self.for_b(arg = nil, &block)
      new.for_b(arg, &block)
    end
new() click to toggle source

Creates a continued fraction instance. With the defaults for_a { 1 } and for_b { 1 } it approximates the golden ration phi if evaluated.

# File lib/bullshit.rb, line 37
    def initialize
      @a = proc { 1.0 }
      @b = proc { 1.0 }
    end

Public Instance Methods

[](x = nil, epsilon = 1E-16, max_iterations = 1 << 31) click to toggle source

Alias for call

a(n, x = nil) click to toggle source

Returns the value for a_n or a_n(x).

# File lib/bullshit.rb, line 87
    def a(n, x = nil)
      result = if x
        @a[n, x]
      else
        @a[n]
      end and result.to_f
    end
b(n, x = nil) click to toggle source

Returns the value for b_n or b_n(x).

# File lib/bullshit.rb, line 96
    def b(n, x = nil)
      result = if x
        @b[n, x]
      else
        @b[n]
      end and result.to_f
    end
call(x = nil, epsilon = 1E-16, max_iterations = 1 << 31) click to toggle source

Evaluates the continued fraction for the value x (if any) with the accuracy epsilon and max_iterations as the maximum number of iterations using the Wallis-method with scaling.

# File lib/bullshit.rb, line 107
    def call(x = nil, epsilon = 1E-16, max_iterations = 1 << 31)
      c_0, c_1 = 1.0, a(0, x)
      c_1 == nil and return 0 / 0.0
      d_0, d_1 = 0.0, 1.0
      result = c_1 / d_1
      n = 0
      error = 1 / 0.0
      $DEBUG and warn "n=%u, a=%f, b=nil, c=%f, d=%f result=%f, error=nil" %
        [ n, c_1, c_1, d_1, result ]
      while n < max_iterations and error > epsilon
        n += 1
        a_n, b_n = a(n, x), b(n, x)
        a_n and b_n or break
        c_2 = a_n * c_1 + b_n * c_0
        d_2 = a_n * d_1 + b_n * d_0
        if c_2.infinite? or d_2.infinite?
          if a_n != 0
            c_2 = c_1 + (b_n / a_n * c_0)
            d_2 = d_1 + (b_n / a_n * d_0)
          elsif b_n != 0
            c_2 = (a_n / b_n * c_1) + c_0
            d_2 = (a_n / b_n * d_1) + d_0
          else
            raise Errno::ERANGE
          end
        end
        r = c_2 / d_2
        error = (r / result - 1).abs

        result = r

        $DEBUG and warn "n=%u, a=%f, b=%f, c=%f, d=%f, result=%f, error=%.16f" %
          [ n, a_n, b_n, c_1, d_1, result, error ]

        c_0, c_1 = c_1, c_2
        d_0, d_1 = d_1, d_2
      end
      n >= max_iterations and raise Errno::ERANGE
      result
    end
Also aliased as: []
for_a(arg = nil, &block) click to toggle source

This method either takes a block or an argument arg. The argument arg has to respond to an integer index n >= 0 and return the value a_n. The block has to return the value for a_n when n is passed as the first argument to the block. If a_n is dependent on an x value (see the call method) the x will be the second argument of the block.

# File lib/bullshit.rb, line 59
    def for_a(arg = nil, &block)
      if arg and !block
        @a = arg
      elsif block and !arg
        @a = block
      else
        raise ArgumentError, "exactly one argument or one block required"
      end
      self
    end
for_b(arg = nil, &block) click to toggle source

This method either takes a block or an argument arg. The argument arg has to respond to an integer index n >= 1 and return the value b_n. The block has to return the value for b_n when n is passed as the first argument to the block. If b_n is dependent on an x value (see the call method) the x will be the second argument of the block.

# File lib/bullshit.rb, line 75
    def for_b(arg = nil, &block)
      if arg and !block
        @b = arg
      elsif block and !arg
        @b = block
      else
        raise ArgumentError, "exactly one argument or one block required"
      end
      self
    end
to_proc() click to toggle source

Returns this continued fraction as a Proc object which takes the same arguments like its call method does.

# File lib/bullshit.rb, line 152
    def to_proc
      proc { |*a| call(*a) }
    end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.