silicium 0.0.2 → 0.0.14

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