ChebyRuby 0.0.1.pre → 0.0.2.pre
Sign up to get free protection for your applications and to get access to all the features.
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
|