silicium 0.0.2 → 0.0.14

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -3
  3. data/.travis.yml +14 -25
  4. data/Gemfile +0 -4
  5. data/README.md +0 -2
  6. data/Rakefile +0 -7
  7. data/lib/silicium/version.rb +1 -1
  8. data/lib/silicium.rb +1 -0
  9. data/silicium.gemspec +37 -39
  10. metadata +4 -92
  11. data/.codeclimate.yml +0 -4
  12. data/Makefile +0 -269
  13. data/docs/Object.html +0 -117
  14. data/docs/README_md.html +0 -142
  15. data/docs/Silicium/Combinatorics.html +0 -270
  16. data/docs/Silicium/Dice/Polyhedron.html +0 -315
  17. data/docs/Silicium/Dice/PolyhedronSet.html +0 -321
  18. data/docs/Silicium/Dice.html +0 -99
  19. data/docs/Silicium/Error.html +0 -106
  20. data/docs/Silicium/Geometry/Line2dCanon.html +0 -243
  21. data/docs/Silicium/Geometry/VariablesOrderException.html +0 -106
  22. data/docs/Silicium/Geometry.html +0 -940
  23. data/docs/Silicium/Graphs/GraphError.html +0 -106
  24. data/docs/Silicium/Graphs/OrientedGraph.html +0 -775
  25. data/docs/Silicium/Graphs/UnorientedGraph.html +0 -284
  26. data/docs/Silicium/Graphs.html +0 -164
  27. data/docs/Silicium/IntegralDoesntExistError.html +0 -106
  28. data/docs/Silicium/NumericalIntegration.html +0 -521
  29. data/docs/Silicium/Optimization.html +0 -639
  30. data/docs/Silicium/Plotter/Image.html +0 -297
  31. data/docs/Silicium/Plotter.html +0 -186
  32. data/docs/Silicium.html +0 -101
  33. data/docs/created.rid +0 -9
  34. data/docs/css/fonts.css +0 -167
  35. data/docs/css/rdoc.css +0 -619
  36. data/docs/fonts/Lato-Light.ttf +0 -0
  37. data/docs/fonts/Lato-LightItalic.ttf +0 -0
  38. data/docs/fonts/Lato-Regular.ttf +0 -0
  39. data/docs/fonts/Lato-RegularItalic.ttf +0 -0
  40. data/docs/fonts/SourceCodePro-Bold.ttf +0 -0
  41. data/docs/fonts/SourceCodePro-Regular.ttf +0 -0
  42. data/docs/images/add.png +0 -0
  43. data/docs/images/arrow_up.png +0 -0
  44. data/docs/images/brick.png +0 -0
  45. data/docs/images/brick_link.png +0 -0
  46. data/docs/images/bug.png +0 -0
  47. data/docs/images/bullet_black.png +0 -0
  48. data/docs/images/bullet_toggle_minus.png +0 -0
  49. data/docs/images/bullet_toggle_plus.png +0 -0
  50. data/docs/images/date.png +0 -0
  51. data/docs/images/delete.png +0 -0
  52. data/docs/images/find.png +0 -0
  53. data/docs/images/loadingAnimation.gif +0 -0
  54. data/docs/images/macFFBgHack.png +0 -0
  55. data/docs/images/package.png +0 -0
  56. data/docs/images/page_green.png +0 -0
  57. data/docs/images/page_white_text.png +0 -0
  58. data/docs/images/page_white_width.png +0 -0
  59. data/docs/images/plugin.png +0 -0
  60. data/docs/images/ruby.png +0 -0
  61. data/docs/images/tag_blue.png +0 -0
  62. data/docs/images/tag_green.png +0 -0
  63. data/docs/images/transparent.png +0 -0
  64. data/docs/images/wrench.png +0 -0
  65. data/docs/images/wrench_orange.png +0 -0
  66. data/docs/images/zoom.png +0 -0
  67. data/docs/index.html +0 -132
  68. data/docs/js/darkfish.js +0 -84
  69. data/docs/js/navigation.js +0 -105
  70. data/docs/js/navigation.js.gz +0 -0
  71. data/docs/js/search.js +0 -110
  72. data/docs/js/search_index.js +0 -1
  73. data/docs/js/search_index.js.gz +0 -0
  74. data/docs/js/searcher.js +0 -229
  75. data/docs/js/searcher.js.gz +0 -0
  76. data/docs/table_of_contents.html +0 -608
  77. data/lib/geometry.rb +0 -236
  78. data/lib/graph.rb +0 -164
  79. data/lib/numerical_integration.rb +0 -147
  80. data/lib/optimization.rb +0 -144
  81. data/lib/plotter.rb +0 -96
  82. data/lib/theory_of_probability.rb +0 -227
data/lib/geometry.rb DELETED
@@ -1,236 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Silicium
4
-
5
- module Geometry
6
-
7
- ##
8
- # Represents a point as two coordinates
9
- # in two-dimensional space
10
- Point = Struct.new(:x, :y)
11
-
12
- ##
13
- # Represents a point as three coordinates
14
- # in three-dimensional space
15
- Point3d = Struct.new(:x, :y, :z)
16
-
17
- ##
18
- #Calculates the distance from given points in two-dimensional space
19
- def distance_point_to_point2d(a, b)
20
- Math.sqrt((b.x - a.x)**2 + (b.y - a.y)**2)
21
- end
22
-
23
- # Class represents a line as equation y = k*x +b
24
- # k - slope
25
- # b - free_term
26
- # in two-dimensional space
27
- class Line2dCanon
28
- attr_reader :slope
29
- attr_reader :free_term
30
-
31
- def initialize(p1, p2)
32
- if (p1.x == p2.x) && (p1.y == p2.y)
33
- raise ArgumentError, "You need 2 diffrent points"
34
- end
35
- if (p1.x == p2.x)
36
- raise ArgumentError, "The straight line equation cannot be written in canonical form"
37
- end
38
- @slope = (p2.y - p1.y) / (p2.x - p1.x).to_f
39
- @free_term = (p2.x * p1.y - p2.y * p1.x) / (p2.x - p1.x).to_f
40
- end
41
-
42
- ##
43
- # Checks the point lies on the line or not
44
- def point_is_on_line?(p1)
45
- p1.y == @slope * p1.x + @free_term
46
- end
47
- end
48
-
49
-
50
- ##
51
- # Calculates the distance from given points in three-dimensional space
52
- def distance_point_to_point3d(a, b)
53
- Math.sqrt((b.x - a.x)**2 + (b.y - a.y)**2 + (b.z - a.z)**2)
54
- end
55
-
56
- ##
57
- # The distance from a point to a line on a plane
58
- # The line is defined by two points
59
- # https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
60
- def distance_point_line2d(p1, p2, a)
61
- line_segment_length = distance_point_to_point2d(p1, p2)
62
- ((p2.y - p1.y) * a.x - (p2.x - p1.x) * a.y + p2.x * p1.y - p2.y * p1.x).abs / (line_segment_length * 1.0)
63
- end
64
-
65
- ##
66
- # The distance from a point to a line on a plane
67
- # Line defined by an equation
68
- # return 0 if the equation does not define a line.
69
- def distance_point_line_equation2d(a, b, c, p)
70
- if a == 0 and b == 0
71
- return 0
72
- end
73
- (a * p.x + b * p.y + c).abs / Math.sqrt(a**2 + b**2)
74
- end
75
-
76
- def oriented_area(a, b, c)
77
- a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)
78
- end
79
-
80
- ##
81
- # Determines if a clockwise crawl is performed
82
- # for defined order of points
83
- def clockwise(a, b, c)
84
- oriented_area(a, b, c).negative?
85
- end
86
-
87
- ##
88
- # Determines if a counter-clockwise crawl is
89
- # performed for defined order of points
90
- def counter_clockwise(a, b, c)
91
- oriented_area(a, b, c).positive?
92
- end
93
-
94
- def not_polygon?(points)
95
- points.empty? || points.size == 1 || points.size == 2
96
- end
97
-
98
- def put_point_in_part(part, point, direction)
99
- direction = method(direction)
100
- while part.size >= 2 && !direction.call(part[part.size - 2], part[part.size - 1], point)
101
- part.pop
102
- end
103
- part.push(point)
104
- end
105
-
106
- ##
107
- # Returns an array containing points that are included
108
- # in the minimal convex hull for a given array of points
109
- # https://e-maxx.ru/algo/convex_hull_graham
110
- def minimal_convex_hull_2d(points)
111
- return points if not_polygon?(points)
112
-
113
- points.sort_by! { |p| [p.x, p.y] }
114
- first = points[0]
115
- last = points.last
116
- up = [first]
117
- down = [first]
118
-
119
- (1...points.size).each do |i|
120
- point = points[i]
121
- is_last = i == points.size - 1
122
- if is_last || clockwise(first, point, last)
123
- put_point_in_part(up, point, :clockwise)
124
- end
125
- if is_last || counter_clockwise(first, point, last)
126
- put_point_in_part(down, point, :counter_clockwise)
127
- end
128
- end
129
-
130
- hull = up
131
- (1..(down.size - 2)).reverse_each do |j|
132
- hull.push(down[j])
133
- end
134
- hull
135
- end
136
-
137
- def process_cf(line_equation, variable)
138
- if line_equation.include?(variable)
139
- before = line_equation.index('/') + 1
140
- after = line_equation.index('=')
141
- line_equation.slice(before..after).gsub('=', '').sub('*', '').gsub('(', '').gsub(')', '').to_f
142
- else
143
- 0.0
144
- end
145
- end
146
-
147
- def cut_by_eq(line_equation)
148
- line_equation.slice(line_equation.index('='), line_equation.length).sub('=', '')
149
- end
150
-
151
- def process_line_by_coordinates(line_equation, func)
152
- copy_line = insert_eq(line_equation)
153
- func = method(func)
154
- res = []
155
- res[0] = func.call(copy_line, 'x')
156
- copy_line = cut_by_eq(copy_line)
157
- res[1] = func.call(copy_line, 'y')
158
- copy_line = cut_by_eq(copy_line)
159
- res[2] = func.call(copy_line, 'z')
160
- res
161
- end
162
-
163
- ##
164
- # Creates an array- directing vector in three-dimensional space .
165
- # The equation is specified in the canonical form.
166
- # Example, (x-0) / 26 = (y + 300) / * (- 15) = (z-200) / 51
167
- #
168
- # Important: mandatory order of variables: x, y, z
169
- def directing_vector3d(line_equation)
170
- process_line_by_coordinates(line_equation, :process_cf)
171
- end
172
-
173
- class VariablesOrderException < Exception
174
- end
175
-
176
- def needed_variables_order?(before, after)
177
- before < after
178
- end
179
-
180
- def process_free_member(line_equation, variable)
181
- if line_equation.include?(variable)
182
- before = line_equation.index(variable) + 1
183
- after = line_equation.index('/')
184
-
185
- unless needed_variables_order?(before, after)
186
- throw VariablesOrderException
187
- end
188
-
189
- line_equation.slice(before..after).gsub('/', '').to_f * (-1)
190
- else
191
- 0.0
192
- end
193
- end
194
-
195
- ##
196
- # Creates an array of coordinates of the point ([x, y, z] on the line
197
- # given by the equation in the canonical form.
198
- # Example, (x-0) / 26 = (y + 300) / * (- 15) = (z-200) / 51
199
- #
200
- # Important: mandatory order of variables: x, y, z
201
- def height_point_3d(line_equation)
202
- process_line_by_coordinates(line_equation, :process_free_member)
203
- end
204
-
205
- def vectors_product(v1, v2)
206
- res = Array.new(3)
207
- (0..2).each do |i|
208
- res[i] = v1[(i + 1) % 3] * v2[(i + 2) % 3] - v1[(i + 2) % 3] * v2[(i + 1) % 3]
209
- end
210
- res
211
- end
212
-
213
- def vector_length(vector)
214
- Math.sqrt(vector[0]**2 + vector[1]**2 + vector[2]**2)
215
- end
216
-
217
- ##
218
- # Calculates the distance from a point given by a Point3d structure
219
- # to a straight line given by a canonical equation.
220
- # Example, (x-0) / 26 = (y + 300) / * (- 15) = (z-200) / 51
221
- #
222
- # Important: mandatory order of variables: x, y, z
223
- def point_to_line_distance_3d(point, line_eq)
224
- dir_vector = directing_vector3d(line_eq)
225
- line_point = height_point_3d(line_eq)
226
- height_vector = [line_point[0] - point.x, line_point[1] - point.y, line_point[2] - point.z]
227
-
228
- height_on_dir = vectors_product(height_vector, dir_vector)
229
- vector_length(height_on_dir) / vector_length(dir_vector)
230
- end
231
-
232
- def insert_eq(line_equation)
233
- line_equation.gsub(' ', '').insert(line_equation.length, '=')
234
- end
235
- end
236
- end
data/lib/graph.rb DELETED
@@ -1,164 +0,0 @@
1
- #require 'set'
2
- #require 'silicium'
3
-
4
- module Silicium
5
- module Graphs
6
- Pair = Struct.new(:first, :second)
7
-
8
- class GraphError < Error
9
-
10
- end
11
-
12
- class OrientedGraph
13
- def initialize(initializer = [])
14
- @vertices = {}
15
- @edge_labels = {}
16
- @vertex_labels = {}
17
- initializer.each do |v|
18
- add_vertex!(v[:v])
19
- v[:i].each { |iv| add_edge_force!(v[:v], iv)}
20
- end
21
- end
22
-
23
- def add_vertex!(vertex_id)
24
- if @vertices.has_key?(vertex_id)
25
- return
26
- end
27
- @vertices[vertex_id] = [].to_set
28
- end
29
-
30
- def add_edge!(from, to)
31
- if @vertices.has_key?(from) && @vertices.has_key?(to)
32
- @vertices[from] << to
33
- end
34
- end
35
-
36
- # should only be used in constructor
37
- def add_edge_force!(from, to)
38
- add_vertex!(from)
39
- add_vertex!(to)
40
- add_edge!(from, to)
41
- end
42
-
43
- def adjacted_with(vertex)
44
- unless @vertices.has_key?(vertex)
45
- raise GraphError.new("Graph does not contain vertex #{vertex}")
46
- end
47
-
48
- @vertices[vertex].clone
49
- end
50
-
51
- def label_edge!(from, to, label)
52
- unless @vertices.has_key?(from) && @vertices[from].include?(to)
53
- raise GraphError.new("Graph does not contain edge (#{from}, #{to})")
54
- end
55
-
56
- @edge_labels[Pair.new(from, to)] = label
57
- end
58
-
59
- def label_vertex!(vertex, label)
60
- unless @vertices.has_key?(vertex)
61
- raise GraphError.new("Graph does not contain vertex #{vertex}")
62
- end
63
-
64
- @vertex_labels[vertex] = label
65
- end
66
-
67
- def get_edge_label(from, to)
68
- if !@vertices.has_key?(from) || ! @vertices[from].include?(to)
69
- raise GraphError.new("Graph does not contain edge (#{from}, #{to})")
70
- end
71
-
72
- @edge_labels[Pair.new(from, to)]
73
- end
74
-
75
- def get_vertex_label(vertex)
76
- unless @vertices.has_key?(vertex)
77
- raise GraphError.new("Graph does not contain vertex #{vertex}")
78
- end
79
-
80
- @vertex_labels[vertex]
81
- end
82
-
83
- def vertex_number
84
- @vertices.count
85
- end
86
-
87
- def edge_number
88
- res = 0
89
- @vertices.values.each do |item|
90
- res += item.count
91
- end
92
- res
93
- end
94
-
95
- def vertex_label_number
96
- @vertex_labels.count
97
- end
98
-
99
- def edge_label_number
100
- @edge_labels.count
101
- end
102
-
103
- def has_vertex?(vertex)
104
- @vertices.has_key?(vertex)
105
- end
106
-
107
- def has_edge?(from, to)
108
- @vertices.has_key?(from) && @vertices[from].include?(to)
109
- end
110
-
111
- def delete_vertex!(vertex)
112
- if has_vertex?(vertex)
113
- @vertices.keys.each do |key|
114
- delete_edge!(key, vertex)
115
- end
116
- @vertices.delete(vertex)
117
- @vertex_labels.delete(vertex)
118
-
119
- @vertices.keys.each do |key|
120
- @edge_labels.delete(Pair.new(vertex, key))
121
- end
122
- end
123
- end
124
-
125
- def delete_edge!(from, to)
126
- if has_edge?(from, to)
127
- @vertices[from].delete(to)
128
- @edge_labels.delete(Pair.new(from, to))
129
- end
130
- end
131
-
132
- end
133
-
134
- class UnorientedGraph < OrientedGraph
135
- def add_edge!(from, to)
136
- super(from, to)
137
- super(to, from)
138
- end
139
-
140
- def label_edge!(from, to, label)
141
- super(from, to, label)
142
- super(to, from, label)
143
- end
144
-
145
- def delete_edge!(from, to)
146
- super(from, to)
147
- super(to, from)
148
- end
149
-
150
- def edge_number
151
- res = 0
152
- @vertices.each do |from, tos|
153
- tos.each {|to| res += (to == from ? 2 : 1)}
154
- end
155
- res / 2
156
- end
157
- end
158
-
159
- def dijkstra_algorythm(graph, starting_vertex)
160
- #
161
- end
162
- end
163
-
164
- end
@@ -1,147 +0,0 @@
1
- module Silicium
2
- class IntegralDoesntExistError < RuntimeError
3
-
4
- end
5
- ##
6
- # A class providing numerical integration methods
7
- class NumericalIntegration
8
-
9
- # Computes integral from +a+ to +b+ of +block+ with accuracy +eps+
10
- def self.three_eights_integration(a, b, eps = 0.0001, &block)
11
- wrapper_method([a, b], eps, :three_eights_integration_n, &block)
12
- end
13
-
14
- # Computes integral from +a+ to +b+ of +block+ with +n+ segmentations
15
- def self.three_eights_integration_n(a, b, n, &block)
16
- dx = (b - a) / n.to_f
17
- result = 0
18
- x = a
19
- n.times do
20
- result +=
21
- (block.call(x) + 3 * block.call((2 * x + x + dx) / 3.0) +
22
- 3 * block.call((x + 2 * (x + dx)) / 3.0) + block.call(x + dx)) / 8.0 * dx
23
- x += dx
24
- end
25
- result
26
- end
27
-
28
-
29
- # Simpson integration with a segment
30
- def self.simpson_integration_with_a_segment(a, b, n, &block)
31
- dx = (b - a) / n.to_f
32
- result = 0
33
- i = 0
34
- while i < n
35
- result += (block.call(a + i * dx) + 4 * block.call(((a + i * dx) +
36
- (a + (i + 1) * dx)) / 2.0) + block.call(a + (i + 1) * dx)) / 6.0 * dx
37
- i += 1
38
- end
39
- result
40
- end
41
-
42
- # Simpson integration with specified accuracy
43
- def self.simpson_integration(a, b, eps = 0.0001, &block)
44
- wrapper_method([a, b], eps, :simpson_integration_with_a_segment, &block)
45
- end
46
-
47
- # Left Rectangle Method and Right Rectangle Method
48
- def self.left_rect_integration(left_p, right_p, eps = 0.0001, &block)
49
- splits = 1
50
- res1 = left_rect_integration_n(left_p, right_p, 1, &block)
51
- res2 = left_rect_integration_n(left_p, right_p, 5, &block)
52
- while (res1 - res2).abs > eps
53
- res1 = left_rect_integration_n(left_p, right_p, splits, &block)
54
- splits *= 5
55
- res2 = left_rect_integration_n(left_p, right_p, splits, &block)
56
- end
57
- (res1 + res2) / 2.0
58
- end
59
-
60
- # Left Rectangle Auxiliary Method and Right Rectangle Auxiliary Method
61
- def self.left_rect_integration_n(left_p, right_p, splits, &block)
62
- dx = (right_p - left_p) / splits.to_f
63
- result = 0
64
- i = 0
65
- while i < splits
66
- result += block.call(left_p + i * dx)
67
- i += 1
68
- end
69
- result * dx
70
- end
71
-
72
-
73
- # Middle Rectangles Method with a segment
74
- def self.middle_rectangles_with_a_segment(a, b, n, &block)
75
- dx = (b - a) / n.to_f
76
- result = 0
77
- i = 0
78
- n.times do
79
- result += block.call(a + dx * (i + 1 / 2)) * dx
80
- i += 1
81
- end
82
- result
83
- end
84
-
85
- # Middle Rectangles Method with specified accuracy
86
- def self.middle_rectangles(a, b, eps = 0.0001, &block)
87
- wrapper_method([a, b], eps, :middle_rectangles_with_a_segment, &block)
88
- end
89
-
90
-
91
- # Trapezoid Method with a segment
92
- def self.trapezoid_with_a_segment(a, b, n, &block)
93
- dx = (b - a) / n.to_f
94
- result = 0
95
- i = 1
96
- (n - 1).times do
97
- result += block.call(a + dx * i)
98
- i += 1
99
- end
100
- result += (block.call(a) + block.call(b)) / 2.0
101
- result * dx
102
- end
103
-
104
- # Trapezoid Method with specified accuracy
105
- def self.trapezoid(a, b, eps = 0.0001, &block)
106
- wrapper_method([a, b], eps, :trapezoid_with_a_segment ,&block)
107
- end
108
-
109
- private
110
-
111
- ##
112
- # Wrapper method for num_integratons methods
113
- # @param [Array] a_b integration range
114
- # @param [Numeric] eps
115
- # @param [Proc] proc - integration Proc
116
- # @param [Block] block - integrated function as Block
117
- def self.wrapper_method(a_b, eps, method_name, &block)
118
- n = 1
119
- a, b = a_b
120
- begin
121
- begin
122
- result = send(method_name, a, b, n, &block)
123
- check_value(result)
124
- n *= 5
125
- result1 = send(method_name, a, b, n, &block)
126
- check_value(result1)
127
- end until (result - result1).abs < eps
128
- rescue Math::DomainError
129
- raise IntegralDoesntExistError, 'Domain error in math function'
130
- rescue ZeroDivisionError
131
- raise IntegralDoesntExistError, 'Divide by zero'
132
- end
133
- (result + result1) / 2.0
134
- end
135
-
136
- def self.check_value(value)
137
- if value.nan?
138
- raise IntegralDoesntExistError, 'We have not-a-number result :('
139
- end
140
- if value == Float::INFINITY
141
- raise IntegralDoesntExistError, 'We have infinity :('
142
- end
143
- end
144
- end
145
- end
146
-
147
-
data/lib/optimization.rb DELETED
@@ -1,144 +0,0 @@
1
- require "silicium"
2
- require 'fast_matrix'
3
-
4
- module Silicium
5
- module Optimization
6
-
7
-
8
- # reflector function
9
- def re_lu(x)
10
- x.negative? ? 0 : x
11
- end
12
-
13
- #sigmoid function
14
- def sigmoid(x)
15
- 1.0 / (1 + Math.exp(-x))
16
- end
17
-
18
- #integrating using method Monte Carlo (f - function, a, b - integrating limits, n - amount of random numbers)
19
- def integrating_Monte_Carlo_base(a, b, n = 100000, &block)
20
- res = 0
21
- range = a..b.to_f
22
- for i in 1..(n + 1)
23
- x = rand(range)
24
- res += (b - a) * 1.0 / n * block.call(x)
25
- end
26
- res
27
- end
28
-
29
- #return true if array is sorted
30
- def sorted?(a)
31
- return false if a.nil?
32
- for i in 0..a.length - 2
33
- if (a[i + 1] < a[i])
34
- return false
35
- end
36
- end
37
- true
38
- end
39
-
40
- #fastest(but it is not exactly) sort, modify sequance
41
- def bogosort!(a)
42
- if (a.nil?)
43
- raise ArgumentError, "Nil array in bogosort"
44
- end
45
- while (!sorted?(a))
46
- a.shuffle!
47
- end
48
- a
49
- end
50
-
51
- #fastest(but it is not exactly) sort
52
- def bogosort(a)
53
- if (a.nil?)
54
- raise ArgumentError, "Nil array in bogosort"
55
- end
56
- crutch = a
57
- while (!sorted?(crutch))
58
- crutch = a.shuffle
59
- end
60
- crutch
61
- end
62
-
63
- #calculate current accuracy in Hook - Jeeves method
64
- def accuracy(step)
65
- acc = 0
66
- step.each { |a| acc += a * a }
67
- Math.sqrt(acc)
68
- end
69
-
70
- #do one Hook - Jeeves step
71
- def hook_jeeves_step(x, i, step, &block)
72
- x[i] += step[i]
73
- tmp1 = block.call(x)
74
- x[i] = x[i] - 2 * step[i]
75
- tmp2 = block.call(x)
76
- if (tmp1 > tmp2)
77
- cur_f = tmp2
78
- else
79
- x[i] = x[i] + step[i] * 2
80
- cur_f = tmp1
81
- end
82
- [cur_f, x[i]]
83
- end
84
-
85
- #switch step if current func value > previous func value
86
- def switch_step(cur_f, prev_f, step, i)
87
- return step[i] / 2.0 if cur_f >= prev_f #you can switch 2.0 on something else
88
- step[i]
89
- end
90
- #Hook - Jeeves method for find minimum point (x - array of start variables, step - step of one iteration, eps - allowable error, alfa - slowdown of step,
91
- #block - function which takes array x, WAENING function doesn't control correctness of input
92
- def hook_jeeves(x, step, eps = 0.1, &block)
93
- prev_f = block.call(x)
94
- acc = accuracy(step)
95
- while (acc > eps)
96
- for i in 0..x.length - 1
97
- tmp = hook_jeeves_step(x, i, step, &block)
98
- cur_f = tmp[0]
99
- x[i] = tmp[1]
100
- step[i] = switch_step(cur_f, prev_f, step, i)
101
- prev_f = cur_f
102
- end
103
- acc = accuracy(step)
104
- end
105
- x
106
- end
107
-
108
- #find centr of interval
109
- def middle(a, b)
110
- (a + b) / 2.0
111
- end
112
-
113
- #do one half division step
114
- def half_division_step(a, b, c, &block)
115
- if (block.call(a) * block.call(c) < 0)
116
- b = c
117
- c = middle(a, c)
118
- else
119
- a = c
120
- c = middle(b, c)
121
- end
122
- [a, b, c]
123
- end
124
-
125
- #find root in [a, b], if he exist, if number of iterations > iters -> error
126
- def half_division(a, b, eps = 0.001, &block)
127
- iters = 1000000
128
- c = middle(a, b)
129
- while ((block.call(c).abs) > eps)
130
- tmp = half_division_step(a, b, c, &block)
131
- a = tmp[0]
132
- b = tmp[1]
133
- c = tmp[2]
134
- iters -= 1
135
- if iters == 0
136
- raise RuntimeError, "Root not found! Check does he exist, or change eps or iters"
137
- end
138
- end
139
- c
140
- end
141
-
142
-
143
- end
144
- end