ChebyRuby 0.0.1.pre → 0.0.2.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce9e90673dcb994d2b9e512a949a173a875c3264
|
4
|
+
data.tar.gz: bd39e0f58ac5668df89c99ae1f255c1eea25458c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25c353b12eee3bc7c9799b319fe04c469d53b9c3db0cc80eae5f4d97b1d7f2a7606c78ebe780d617e2f5b027f3ae2047248ae03a53efcbcc9d28830fcf46409a
|
7
|
+
data.tar.gz: 053d27aac92aed0404ee6c49f4700917ac609594a9e18263c46c22af27745b5e22a967f6d96adc6ee3d3084b1ef34919140a9664ef01eea0945de4da3a8df76d
|
@@ -1,5 +1,18 @@
|
|
1
|
+
# Module/Mixin for numeric differentiation methods.
|
2
|
+
# As of right now it is only mixed-in to @see [FiniteDifferencing]
|
3
|
+
# but will likely be mixed into more in the future.
|
1
4
|
module ChebyRuby::Differentiation
|
5
|
+
|
6
|
+
# A crude method to calculate the "slope" of a function over the
|
7
|
+
# span of two points.
|
8
|
+
# The formula used is:
|
9
|
+
# <pre>(f(b) - f(a))/(b - a)</pre>
|
10
|
+
#
|
11
|
+
# @param [UnivariateFunction] func the univariate function to be used.
|
12
|
+
# @param [Numeric] a one of the values in the domain of func
|
13
|
+
# @param [Numeric] b the other value in the domain of func
|
14
|
+
# @return [Float] the slope as described above
|
2
15
|
def slope(func, a, b)
|
3
|
-
(func.value(b) - func.value(a))/(b-a)
|
16
|
+
(func.value(b) - func.value(a))/(b-a).to_f
|
4
17
|
end
|
5
18
|
end
|
@@ -1,13 +1,40 @@
|
|
1
1
|
require_relative 'differentiation'
|
2
|
+
|
3
|
+
# This is the class for finite differencing.
|
4
|
+
# Finite differencing is a popular method of finding a numeric
|
5
|
+
# derivative. There are three different implementations of the finite
|
6
|
+
# differencing method. There is the forward and backward implementations,
|
7
|
+
# both with an order of accuracy of O(h) and central differencing with an
|
8
|
+
# order of accuracy of O(h^2).
|
9
|
+
#
|
10
|
+
# @attr func [UnivariateFunction] the function to which differentiation will be applied
|
2
11
|
class ChebyRuby::FiniteDifferencing
|
3
12
|
include Differentiation
|
4
13
|
|
5
14
|
attr_accessor :func
|
6
15
|
|
16
|
+
# Basic constructor for FiniteDifferencing. It can be implemented in two ways.
|
17
|
+
# It can either have a UnivariateFunction passed to it or a proc.
|
18
|
+
#
|
19
|
+
# @param [UnivariateFunction||Proc] func the function to implement
|
7
20
|
def initialize(func)
|
8
|
-
|
21
|
+
if func.is_a? Proc
|
22
|
+
@func = UnivariateFunction.new(&func)
|
23
|
+
else
|
24
|
+
@func = func
|
25
|
+
end
|
9
26
|
end
|
10
27
|
|
28
|
+
# This does forward finite differencing.
|
29
|
+
# The formula being used is:
|
30
|
+
# <pre> Sum[(-1)^i * Binom(n i) * f(x + (n-i) * h), {i, 0, n}]/(h^n) </pre>
|
31
|
+
#
|
32
|
+
# @param [Numeric] x the value at which to find the derivative
|
33
|
+
# @param [Numeric] h the value to use for the differencing (generally
|
34
|
+
# the smaller the better with exceptions especially when considering
|
35
|
+
# underflow).
|
36
|
+
# @param [Integer] order the order of the derivative. (Ex. 1 for f', 2 for f'', etc.)
|
37
|
+
# @return [Float] the forward finite differencing approximation of f^(n) (x)
|
11
38
|
def forward(x, h = 0.1, order = 1)
|
12
39
|
(0..order).map do |i|
|
13
40
|
(-1)**i * FiniteDifferencing::binomial(order, i) *
|
@@ -15,6 +42,16 @@ class ChebyRuby::FiniteDifferencing
|
|
15
42
|
end.inject(:+) / (h**order).to_f
|
16
43
|
end
|
17
44
|
|
45
|
+
# This does backward finite differencing.
|
46
|
+
# The formula being used is:
|
47
|
+
# <pre> Sum[(-1)^i * Binom(n i) * f(x - i*h), {i, 0, n}]/(h^n) </pre>
|
48
|
+
#
|
49
|
+
# @param [Numeric] x the value at which to find the derivative
|
50
|
+
# @param [Numeric] h the value to use for the differencing (generally
|
51
|
+
# the smaller the better with exceptions especially when considering
|
52
|
+
# underflow).
|
53
|
+
# @param [Integer] order the order of the derivative. (Ex. 1 for f', 2 for f'', etc.)
|
54
|
+
# @return [Float] the backward finite differencing approximation of f^(n) (x)
|
18
55
|
def backward(x, h = 0.1, order = 1)
|
19
56
|
(0..order).map do |i|
|
20
57
|
(-1)**i * FiniteDifferencing::binomial(order, i) *
|
@@ -22,6 +59,16 @@ class ChebyRuby::FiniteDifferencing
|
|
22
59
|
end.inject(:+) / (h**order).to_f
|
23
60
|
end
|
24
61
|
|
62
|
+
# This does central finite differencing.
|
63
|
+
# The formula being used is:
|
64
|
+
# <pre> Sum[(-1)^i * Binom(n i) * f(x + (n/2-i) * h), {i, 0, n}]/(h^n) </pre>
|
65
|
+
#
|
66
|
+
# @param [Numeric] x the value at which to find the derivative
|
67
|
+
# @param [Numeric] h the value to use for the differencing (generally
|
68
|
+
# the smaller the better with exceptions especially when considering
|
69
|
+
# underflow).
|
70
|
+
# @param [Integer] order the order of the derivative. (Ex. 1 for f', 2 for f'', etc.)
|
71
|
+
# @return [Float] the central finite differencing approximation of f^(n) (x)
|
25
72
|
def central(x, h = 0.1, order = 1)
|
26
73
|
(0..order).map do |i|
|
27
74
|
(-1)**i * FiniteDifferencing::binomial(order, i) *
|
@@ -30,6 +77,11 @@ class ChebyRuby::FiniteDifferencing
|
|
30
77
|
end
|
31
78
|
|
32
79
|
private
|
80
|
+
# Used to calculate the binomial coefficient.
|
81
|
+
#
|
82
|
+
# @param [Integer] n the upper binomial value
|
83
|
+
# @param [Integer] k the lowe binomial value
|
84
|
+
# @return [Float] Binom(n k)
|
33
85
|
def FiniteDifferencing.binomial(n, k)
|
34
86
|
(1..k).map do |i|
|
35
87
|
(n + 1 - i)/i.to_f
|
@@ -1,4 +1,17 @@
|
|
1
|
+
# Module/Mixin for integration.
|
2
|
+
#
|
3
|
+
# It is currently mixed into Romberg and Simpson's
|
1
4
|
module ChebyRuby::Integration
|
5
|
+
|
6
|
+
# This method returns the trapezoid integration estimate.
|
7
|
+
#
|
8
|
+
# @param [UnivariateFunction] func the univariate function to integrate
|
9
|
+
# @param [Numeric] a the lower bounds of the integral
|
10
|
+
# @param [Numeric] b the upper bounds of the integral
|
11
|
+
# @param [Integer] iterations the number of iterations/subregions requested.
|
12
|
+
# While a higher number will be more accurate, it will also take longer.
|
13
|
+
# @return [Float] the trapezoidal estimation of the integral of func from
|
14
|
+
# a to b.
|
2
15
|
def trap_integrate(func, a, b, iterations = 32)
|
3
16
|
h = (b - a)/iterations.to_f
|
4
17
|
mesh = (a..b).step(h).to_a[1...-1]
|
@@ -7,6 +20,13 @@ module ChebyRuby::Integration
|
|
7
20
|
(b - a)/(2.0 * iterations) * summand
|
8
21
|
end
|
9
22
|
|
23
|
+
# This method compares the accuate of certain methods to each other.
|
24
|
+
#
|
25
|
+
# @param [Numeric] a the lower bounds of the integral
|
26
|
+
# @param [Numeric] b the upper bounds of the integral
|
27
|
+
# @param [String] method the method being used
|
28
|
+
# @param [String] cm the method to compare to
|
29
|
+
# @return [Float] the absolute difference between the two methods.
|
10
30
|
def accuracy_comparison(a, b, method = 'Trapezoid', cm = 'Trapezoid')
|
11
31
|
case method
|
12
32
|
when 'Trapezoid' then (integrate(a, b) - trap_integrate(func, a, b)).abs
|
@@ -15,7 +35,14 @@ module ChebyRuby::Integration
|
|
15
35
|
end
|
16
36
|
end
|
17
37
|
|
38
|
+
# Singleton class for mixin purposes.
|
18
39
|
class << self
|
40
|
+
# This method provides a singleton implementation of an
|
41
|
+
# integration method in an integration class.
|
42
|
+
#
|
43
|
+
# @param [UnivariateFunction] func the function over which to integrate
|
44
|
+
# @param [Numeric] a the lower bounds of the integral
|
45
|
+
# @param [Numeric] b the upper bounds of the integral
|
19
46
|
def sintegrate(func, a, b)
|
20
47
|
self.new(func).integrate(a, b)
|
21
48
|
end
|
@@ -1,14 +1,33 @@
|
|
1
1
|
require_relative 'integration'
|
2
2
|
|
3
|
+
# This class is for Romberg integration. The Romberg integration method
|
4
|
+
# involves using Richardson extrapolation combined with the trapezoid
|
5
|
+
# method to get a more accurate integration method. It was published by
|
6
|
+
# Werner Romberg in 1955.
|
7
|
+
#
|
8
|
+
# @attr func [UnivariateFunction] the function over which to integrate.
|
3
9
|
class ChebyRuby::RombergIntegration
|
4
10
|
include ChebyRuby::Integration
|
5
11
|
|
6
12
|
attr_accessor :func
|
7
13
|
|
14
|
+
# Basic constructor for RombergIntegration. It can be implemented in two ways.
|
15
|
+
# It can either have a UnivariateFunction passed to it or a proc.
|
16
|
+
#
|
17
|
+
# @param [UnivariateFunction||Proc] func the function to implement
|
8
18
|
def initialize(func)
|
9
|
-
|
19
|
+
if func.is_a? Proc
|
20
|
+
@func = UnivariateFunction.new(&func)
|
21
|
+
else
|
22
|
+
@func = func
|
23
|
+
end
|
10
24
|
end
|
11
25
|
|
26
|
+
# This method integrates the function parameter using romberg integration.
|
27
|
+
#
|
28
|
+
# @param [Numeric] a the lower bounds of the integral
|
29
|
+
# @param [Numeric] b the upper bounds of the integral
|
30
|
+
# @param [Integer] iterations the number of iterations to be used for integration.
|
12
31
|
def integrate(a, b, iterations = 8)
|
13
32
|
t = Array.new(iterations)
|
14
33
|
iterations.times do |i|
|
@@ -23,7 +42,13 @@ class ChebyRuby::RombergIntegration
|
|
23
42
|
t.last.last
|
24
43
|
end
|
25
44
|
|
45
|
+
# This method compares the accuate of Romberg to other methods.
|
46
|
+
#
|
47
|
+
# @param [Numeric] a the lower bounds of the integral
|
48
|
+
# @param [Numeric] b the upper bounds of the integral
|
49
|
+
# @param [String] method the method to compare to
|
50
|
+
# @return [Float] the absolute difference between the two methods.
|
26
51
|
def accuracy_comparison(a, b, method = 'Trapezoid')
|
27
|
-
super.accuracy_comparison(a, b, method, '
|
52
|
+
super.accuracy_comparison(a, b, method, 'Romberg')
|
28
53
|
end
|
29
54
|
end
|
@@ -1,14 +1,32 @@
|
|
1
1
|
require_relative 'integration'
|
2
2
|
|
3
|
+
# This class is for the composite Simpson's rule. The Composite Simpson's rule
|
4
|
+
# involves summing Simpson's rule being calculated over a fine mesh.
|
5
|
+
#
|
6
|
+
# @attr func [UnivariateFunction] the function over which to integrate.
|
3
7
|
class ChebyRuby::SimpsonsIntegration
|
4
8
|
include ChebyRuby::Integration
|
5
9
|
|
6
10
|
attr_accessor :func
|
7
11
|
|
12
|
+
# Basic constructor for SimpsonsIntegration. It can be implemented in two ways.
|
13
|
+
# It can either have a UnivariateFunction passed to it or a proc.
|
14
|
+
#
|
15
|
+
# @param [UnivariateFunction||Proc] func the function to implement
|
8
16
|
def initialize(func)
|
9
|
-
|
17
|
+
if func.is_a? Proc
|
18
|
+
@func = UnivariateFunction.new(&func)
|
19
|
+
else
|
20
|
+
@func = func
|
21
|
+
end
|
10
22
|
end
|
11
23
|
|
24
|
+
# This method integrates the function parameter using
|
25
|
+
# the composite simpsons rule.
|
26
|
+
#
|
27
|
+
# @param [Numeric] a the lower bounds of the integral
|
28
|
+
# @param [Numeric] b the upper bounds of the integral
|
29
|
+
# @param [Integer] iterations the number of iterations to be used for integration.
|
12
30
|
def integrate(a, b, iterations = 32)
|
13
31
|
h = (b - a) / iterations.to_f
|
14
32
|
mesh = (a..b).step(h).to_a[1...-1]
|
@@ -19,7 +37,13 @@ class ChebyRuby::SimpsonsIntegration
|
|
19
37
|
(h / 3.0) * summand
|
20
38
|
end
|
21
39
|
|
40
|
+
# This method compares the accuate of Simpsons to other methods.
|
41
|
+
#
|
42
|
+
# @param [Numeric] a the lower bounds of the integral
|
43
|
+
# @param [Numeric] b the upper bounds of the integral
|
44
|
+
# @param [String] method the method to compare to
|
45
|
+
# @return [Float] the absolute difference between the two methods.
|
22
46
|
def accuracy_comparison(a, b, method = 'Trapezoid')
|
23
|
-
super.accuracy_comparison(a, b, method, '
|
24
|
-
end
|
47
|
+
super.accuracy_comparison(a, b, method, 'Simpsons')
|
48
|
+
end
|
25
49
|
end
|