Class: MoreMath::ContinuedFraction
- Defined in:
- lib/more_math/continued_fraction.rb
Overview
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 + -----
...
Class Method Summary collapse
-
.for_a(arg = nil, &block) ⇒ Object
Creates a ContinuedFraction instances and passes its arguments to a call to for_a.
-
.for_b(arg = nil, &block) ⇒ Object
Creates a ContinuedFraction instances and passes its arguments to a call to for_b.
Instance Method Summary collapse
-
#a(n, x = nil) ⇒ Object
Returns the value for a_n or a_n(x).
-
#b(n, x = nil) ⇒ Object
Returns the value for b_n or b_n(x).
-
#call(x = nil, epsilon = 1E-16, max_iterations = 1 << 31) ⇒ Object
(also: #[])
Evaluates the continued fraction for the value
x
(if any) with the accuracyepsilon
andmax_iterations
as the maximum number of iterations using the Wallis-method with scaling. -
#for_a(arg = nil, &block) ⇒ Object
This method either takes a block or an argument
arg
. -
#for_b(arg = nil, &block) ⇒ Object
This method either takes a block or an argument
arg
. -
#initialize ⇒ ContinuedFraction
constructor
Creates a continued fraction instance.
-
#to_proc ⇒ Object
Returns this continued fraction as a Proc object which takes the same arguments like its call method does.
Constructor Details
#initialize ⇒ ContinuedFraction
Creates a continued fraction instance. With the defaults for_a { 1 } and for_b { 1 } it approximates the golden ration phi if evaluated.
21 22 23 24 |
# File 'lib/more_math/continued_fraction.rb', line 21 def initialize @a = proc { 1.0 } @b = proc { 1.0 } end |
Class Method Details
.for_a(arg = nil, &block) ⇒ Object
Creates a ContinuedFraction instances and passes its arguments to a call to for_a.
28 29 30 |
# File 'lib/more_math/continued_fraction.rb', line 28 def self.for_a(arg = nil, &block) new.for_a(arg, &block) end |
.for_b(arg = nil, &block) ⇒ Object
Creates a ContinuedFraction instances and passes its arguments to a call to for_b.
34 35 36 |
# File 'lib/more_math/continued_fraction.rb', line 34 def self.for_b(arg = nil, &block) new.for_b(arg, &block) end |
Instance Method Details
#a(n, x = nil) ⇒ Object
Returns the value for a_n or a_n(x).
71 72 73 74 75 76 77 |
# File 'lib/more_math/continued_fraction.rb', line 71 def a(n, x = nil) result = if x @a[n, x] else @a[n] end and result.to_f end |
#b(n, x = nil) ⇒ Object
Returns the value for b_n or b_n(x).
80 81 82 83 84 85 86 |
# File 'lib/more_math/continued_fraction.rb', line 80 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) ⇒ Object Also known as: []
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.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/more_math/continued_fraction.rb', line 91 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 |
#for_a(arg = nil, &block) ⇒ Object
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.
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/more_math/continued_fraction.rb', line 43 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) ⇒ Object
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.
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/more_math/continued_fraction.rb', line 59 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 ⇒ Object
Returns this continued fraction as a Proc object which takes the same arguments like its call method does.
136 137 138 |
# File 'lib/more_math/continued_fraction.rb', line 136 def to_proc proc { |*a| call(*a) } end |