silicium 0.0.20 → 0.0.21
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 +4 -4
- data/.codeclimate.yml +3 -3
- data/.gitignore +13 -13
- data/.rakeTasks +8 -0
- data/.travis.yml +28 -25
- data/CODE_OF_CONDUCT.md +74 -74
- data/Gemfile +8 -8
- data/LICENSE.txt +21 -21
- data/Makefile +269 -269
- data/README.md +588 -46
- data/Rakefile +16 -16
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/docs/Object.html +117 -117
- data/docs/README_md.html +142 -142
- data/docs/Silicium/Combinatorics.html +270 -270
- data/docs/Silicium/Dice/Polyhedron.html +315 -315
- data/docs/Silicium/Dice/PolyhedronSet.html +321 -321
- data/docs/Silicium/Dice.html +99 -99
- data/docs/Silicium/Error.html +106 -106
- data/docs/Silicium/Geometry/Line2dCanon.html +243 -243
- data/docs/Silicium/Geometry/VariablesOrderException.html +106 -106
- data/docs/Silicium/Geometry.html +940 -940
- data/docs/Silicium/GraphVisualizer.html +226 -0
- data/docs/Silicium/Graphs/GraphError.html +106 -106
- data/docs/Silicium/Graphs/OrientedGraph.html +901 -775
- data/docs/Silicium/Graphs/UnorientedGraph.html +237 -284
- data/docs/Silicium/Graphs.html +374 -164
- data/docs/Silicium/IntegralDoesntExistError.html +106 -106
- data/docs/Silicium/NumericalIntegration.html +521 -521
- data/docs/Silicium/Optimization.html +629 -639
- data/docs/Silicium/Plotter/Image.html +297 -297
- data/docs/Silicium/Plotter.html +186 -186
- data/docs/Silicium.html +101 -101
- data/docs/created.rid +9 -9
- data/docs/css/fonts.css +167 -167
- data/docs/css/rdoc.css +619 -619
- data/docs/index.html +134 -132
- data/docs/js/darkfish.js +84 -84
- data/docs/js/navigation.js +105 -105
- data/docs/js/search.js +110 -110
- data/docs/js/search_index.js +1 -1
- data/docs/js/search_index.js.gz +0 -0
- data/docs/js/searcher.js +229 -229
- data/docs/table_of_contents.html +697 -608
- data/lib/algebra.rb +452 -0
- data/lib/algebra_diff.rb +258 -0
- data/lib/geometry/figure.rb +62 -0
- data/lib/geometry.rb +290 -236
- data/lib/geometry3d.rb +270 -0
- data/lib/graph/dfs.rb +42 -0
- data/lib/graph/kruskal.rb +36 -0
- data/lib/graph/scc.rb +97 -0
- data/lib/graph.rb +350 -164
- data/lib/graph_visualizer.rb +287 -0
- data/lib/ml_algorithms.rb +181 -0
- data/lib/numerical_integration.rb +184 -147
- data/lib/optimization.rb +209 -144
- data/lib/plotter.rb +256 -96
- data/lib/polynomial_division.rb +132 -0
- data/lib/polynomial_interpolation.rb +94 -0
- data/lib/regression.rb +120 -0
- data/lib/silicium/adding.rb +37 -0
- data/lib/silicium/conversions.rb +23 -0
- data/lib/silicium/multi.rb +82 -0
- data/lib/silicium/sparse.rb +76 -0
- data/lib/silicium/sugar.rb +37 -0
- data/lib/silicium/trans.rb +26 -0
- data/lib/silicium/version.rb +3 -3
- data/lib/silicium.rb +5 -5
- data/lib/theory_of_probability.rb +240 -226
- data/lib/topological_sort.rb +50 -0
- data/oriented_graph.png +0 -0
- data/plot.png +0 -0
- data/silicium.gemspec +38 -39
- metadata +38 -16
data/lib/plotter.rb
CHANGED
@@ -1,96 +1,256 @@
|
|
1
|
-
require 'silicium'
|
2
|
-
require 'chunky_png'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
#
|
33
|
-
# @
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
1
|
+
require 'silicium'
|
2
|
+
require 'chunky_png'
|
3
|
+
require 'ruby2d'
|
4
|
+
|
5
|
+
|
6
|
+
module Silicium
|
7
|
+
##
|
8
|
+
# Plotter module
|
9
|
+
# Module contains classes, that are different kinds of plain plotters
|
10
|
+
#
|
11
|
+
module Plotter
|
12
|
+
include Silicium::Geometry
|
13
|
+
# The Color module defines methods for handling colors. Within the Plotter
|
14
|
+
# library, the concepts of pixels and colors are both used, and they are
|
15
|
+
# both represented by a Integer.
|
16
|
+
#
|
17
|
+
# Pixels/colors are represented in RGBA components. Each of the four
|
18
|
+
# components is stored with a depth of 8 bits (maximum value = 255 =
|
19
|
+
# {Plotter::Color::MAX}). Together, these components are stored in a 4-byte
|
20
|
+
# Integer.
|
21
|
+
#
|
22
|
+
# A color will always be represented using these 4 components in memory.
|
23
|
+
# When the image is encoded, a more suitable representation can be used
|
24
|
+
# (e.g. rgb, grayscale, palette-based), for which several conversion methods
|
25
|
+
# are provided in this module.
|
26
|
+
module Color
|
27
|
+
extend ChunkyPNG::Color
|
28
|
+
include ChunkyPNG::Color
|
29
|
+
end
|
30
|
+
##
|
31
|
+
# Factory method to return a color value, based on the arguments given.
|
32
|
+
#
|
33
|
+
# @overload Color(r, g, b, a)
|
34
|
+
# @param (see ChunkyPNG::Color.rgba)
|
35
|
+
# @return [Integer] The rgba color value.
|
36
|
+
#
|
37
|
+
# @overload Color(r, g, b)
|
38
|
+
# @param (see ChunkyPNG::Color.rgb)
|
39
|
+
# @return [Integer] The rgb color value.
|
40
|
+
#
|
41
|
+
# @overload Color(hex_value, opacity = nil)
|
42
|
+
# @param (see ChunkyPNG::Color.from_hex)
|
43
|
+
# @return [Integer] The hex color value, with the opacity applied if one
|
44
|
+
# was given.
|
45
|
+
#
|
46
|
+
# @overload Color(color_name, opacity = nil)
|
47
|
+
# @param (see ChunkyPNG::Color.html_color)
|
48
|
+
# @return [Integer] The hex color value, with the opacity applied if one
|
49
|
+
# was given.
|
50
|
+
#
|
51
|
+
# @overload Color(color_value, opacity = nil)
|
52
|
+
# @param [Integer, :to_i] The color value.
|
53
|
+
# @return [Integer] The color value, with the opacity applied if one was
|
54
|
+
# given.
|
55
|
+
#
|
56
|
+
# @return [Integer] The determined color value as RGBA integer.
|
57
|
+
# @raise [ArgumentError] if the arguments weren't understood as a color.
|
58
|
+
def color(*args)
|
59
|
+
case args.length
|
60
|
+
when 1 then Color.parse(args.first)
|
61
|
+
when 2 then (Color.parse(args.first) & 0xffffff00) | args[1].to_i
|
62
|
+
when 3 then Color.rgb(*args)
|
63
|
+
when 4 then Color.rgba(*args)
|
64
|
+
else raise ArgumentError,
|
65
|
+
"Don't know how to create a color from #{args.inspect}!"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
##
|
69
|
+
# A class representing canvas for plotting bar charts and function graphs
|
70
|
+
class Image
|
71
|
+
include Silicium::Geometry
|
72
|
+
##
|
73
|
+
# Creates a new plot with chosen +width+ and +height+ parameters
|
74
|
+
# with background colored +bg_color+
|
75
|
+
def initialize(width, height, bg_color = Color::TRANSPARENT, padding = 5)
|
76
|
+
@image = ChunkyPNG::Image.new(width, height, bg_color)
|
77
|
+
@padding = padding
|
78
|
+
end
|
79
|
+
|
80
|
+
def rectangle(left_upper, width, height, color)
|
81
|
+
x_end = left_upper.x + width - 1
|
82
|
+
y_end = left_upper.y + height - 1
|
83
|
+
(left_upper.x..x_end).each do |i|
|
84
|
+
(left_upper.y..y_end).each { |j| @image[i, j] = color }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def draw_axis(min, dpu, axis_color)
|
91
|
+
# Axis OX
|
92
|
+
rectangle(Point.new(
|
93
|
+
@padding,
|
94
|
+
@image.height - @padding - (min.y.abs * dpu.y).ceil
|
95
|
+
),
|
96
|
+
@image.width - 2 * @padding,
|
97
|
+
1,
|
98
|
+
axis_color)
|
99
|
+
# Axis OY
|
100
|
+
rectangle(Point.new(@padding + (min.x.abs * dpu.x).ceil, @padding),
|
101
|
+
1, @image.height - 2 * @padding, axis_color)
|
102
|
+
end
|
103
|
+
|
104
|
+
public
|
105
|
+
|
106
|
+
##
|
107
|
+
# Draws a bar chart in the plot using provided +bars+,
|
108
|
+
# each of them has width of +bar_width+ and colored +bars_color+
|
109
|
+
def bar_chart(bars, bar_width,
|
110
|
+
bars_color = Color('red @ 1.0'),
|
111
|
+
axis_color = Color::BLACK)
|
112
|
+
if bars.count * bar_width > @image.width
|
113
|
+
raise ArgumentError,
|
114
|
+
'Not enough big size of image to plot these number of bars'
|
115
|
+
end
|
116
|
+
|
117
|
+
# Values of x and y on borders of plot
|
118
|
+
min = Point.new([bars.collect { |k, _| k }.min, 0].min,
|
119
|
+
[bars.collect { |_, v| v }.min, 0].min)
|
120
|
+
max = Point.new([bars.collect { |k, _| k }.max, 0].max,
|
121
|
+
[bars.collect { |_, v| v }.max, 0].max)
|
122
|
+
|
123
|
+
# Dots per unit
|
124
|
+
dpu = Point.new(
|
125
|
+
(@image.width - 2 * @padding).to_f / (max.x - min.x + bar_width),
|
126
|
+
(@image.height - 2 * @padding).to_f / (max.y - min.y)
|
127
|
+
)
|
128
|
+
|
129
|
+
draw_axis(min, dpu, axis_color)
|
130
|
+
|
131
|
+
bars.each do |x, y| # Cycle drawing bars
|
132
|
+
l_up_x = @padding + ((x + min.x.abs) * dpu.x).floor
|
133
|
+
l_up_y = if y.negative?
|
134
|
+
@image.height - @padding - (min.y.abs * dpu.y).ceil + 1
|
135
|
+
else
|
136
|
+
@image.height - @padding - ((y + min.y.abs) * dpu.y).ceil
|
137
|
+
end
|
138
|
+
rectangle(Point.new(l_up_x, l_up_y),
|
139
|
+
bar_width, (y.abs * dpu.y).ceil,
|
140
|
+
bars_color)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
##
|
145
|
+
# Exports plotted image to file +filename+
|
146
|
+
def export(filename)
|
147
|
+
@image.save(filename, interlace: true)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
CENTER_X = Window.width / 2
|
152
|
+
CENTER_Y = Window.height / 2
|
153
|
+
|
154
|
+
mul = 100/1
|
155
|
+
|
156
|
+
##
|
157
|
+
# draws axes
|
158
|
+
def draw_axes
|
159
|
+
Line.new(x1: 0, y1: CENTER_Y, x2: (get :width), y2: CENTER_Y, width: 1, color: 'white', z: 20)
|
160
|
+
Line.new(x1: CENTER_X, y1: 0, x2: CENTER_X, y2: (get :height), width: 1, color: 'white', z: 20)
|
161
|
+
|
162
|
+
x1 = CENTER_X
|
163
|
+
x2 = CENTER_X
|
164
|
+
while (x1 < Window.width * 1.1) and (x2 > Window.width * -1.1) do
|
165
|
+
Line.new(x1: x1, y1: CENTER_Y - 4, x2: x1, y2: CENTER_Y + 3, width: 1, color: 'white', z: 20)
|
166
|
+
Line.new(x1: x2, y1: CENTER_Y - 4, x2: x2, y2: CENTER_Y + 3, width: 1, color: 'white', z: 20)
|
167
|
+
x1 += mul
|
168
|
+
x2 -= mul
|
169
|
+
end
|
170
|
+
|
171
|
+
y1 = CENTER_Y
|
172
|
+
y2 = CENTER_Y
|
173
|
+
while (y1 < Window.height * 1.1) and (y2 > Window.height * -1.1) do
|
174
|
+
Line.new(x1: CENTER_X - 3, y1: y1, x2: CENTER_X + 3, y2: y1, width: 1, color: 'white', z: 20)
|
175
|
+
Line.new(x1: CENTER_X - 3, y1: y2, x2: CENTER_X + 3, y2: y2, width: 1, color: 'white', z: 20)
|
176
|
+
y1 += mul
|
177
|
+
y2 -= mul
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Changes the coordinates to draw the next pixel for the +f+ function
|
183
|
+
# +x+ - current argument. +st+ - step to next point
|
184
|
+
def reset_step(x, st, &f)
|
185
|
+
y1 = f.call(x)
|
186
|
+
y2 = f.call(x + st)
|
187
|
+
|
188
|
+
if (y1 - y2).abs / mul > 1.0
|
189
|
+
[st / (y1 - y2).abs / mul, 0.001].max
|
190
|
+
else
|
191
|
+
st / mul * 2
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
##
|
196
|
+
# Draws a point on coordinates +x+ and +y+
|
197
|
+
# with the scale +mul+ and color +col+
|
198
|
+
def draw_point(x, y, mul, col)
|
199
|
+
Line.new(
|
200
|
+
x1: CENTER_X + x * mul, y1: CENTER_Y - y * mul,
|
201
|
+
x2: CENTER_X + 1 + x * mul, y2: CENTER_Y + 2 - y * mul,
|
202
|
+
width: 1,
|
203
|
+
color: col,
|
204
|
+
z: 20
|
205
|
+
)
|
206
|
+
end
|
207
|
+
|
208
|
+
##
|
209
|
+
# Reduces the interval to the window range. +a+ and +b+ that determine interval
|
210
|
+
def reduce_interval(a, b)
|
211
|
+
a *= mul
|
212
|
+
b *= mul
|
213
|
+
return [a, -(get :width) * 1.1].max / mul, [b, (get :width) * 1.1].min / mul
|
214
|
+
end
|
215
|
+
|
216
|
+
##
|
217
|
+
# Draws the function +func+ at the interval from +a+ to +b+
|
218
|
+
def draw_fn(a, b, &func)
|
219
|
+
draw_axes
|
220
|
+
|
221
|
+
a, b = reduce_interval(a, b)
|
222
|
+
|
223
|
+
step = 0.38
|
224
|
+
c_step = step
|
225
|
+
arg = a
|
226
|
+
|
227
|
+
while arg < b do
|
228
|
+
c_step = step
|
229
|
+
begin
|
230
|
+
c_step = reset_step(arg, step) {|xx| fn(xx)}
|
231
|
+
rescue Math::DomainError
|
232
|
+
arg += c_step * 0.1
|
233
|
+
else
|
234
|
+
draw_point(arg, func.call(arg), mul, 'lime')
|
235
|
+
ensure
|
236
|
+
arg += c_step
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
##
|
242
|
+
# show plot
|
243
|
+
def show_window
|
244
|
+
show
|
245
|
+
end
|
246
|
+
|
247
|
+
# @param [Integer] sc
|
248
|
+
def set_scale(sc)
|
249
|
+
mul = sc
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Silicium
|
2
|
+
|
3
|
+
|
4
|
+
module Algebra
|
5
|
+
##
|
6
|
+
# TODO: class docs
|
7
|
+
class PolynomialDivision
|
8
|
+
|
9
|
+
DELTA = 0.01
|
10
|
+
|
11
|
+
# This function returns an array of coefficients obtained by parsing input string in format: "<coeff>*x**<degree>+..."
|
12
|
+
# Even if in your expression don't exist x with some degree, you should to write it with 0 coefficient
|
13
|
+
# Also free term you should to write with 0 degree
|
14
|
+
# Example: "2*x**5-3*x**4+0*x**3+0*x**2-5*x**1-6*x**0"
|
15
|
+
def polynom_parser(str)
|
16
|
+
copy_str = str.clone
|
17
|
+
sgn_array = [] # Array of signs
|
18
|
+
if copy_str[0] != '-'
|
19
|
+
sgn_array.push('+')
|
20
|
+
else
|
21
|
+
sgn_array.push('-')
|
22
|
+
copy_str[0] = ''
|
23
|
+
end
|
24
|
+
token = copy_str.split(/[-+]/)
|
25
|
+
(0..copy_str.size-1).each do |i|
|
26
|
+
sgn_array.push(copy_str[i]) if copy_str[i] == '-' || copy_str[i] == '+'
|
27
|
+
end
|
28
|
+
size = token.size - 1
|
29
|
+
coeff = [] # Array of coefficients
|
30
|
+
(0..size).each do |i|
|
31
|
+
degree = token[i].split('*') # Split by '*' to get coefficient and degree
|
32
|
+
degree[0] == 'x' ? coeff[i] = 1.0 : coeff[i] = degree[0].to_f
|
33
|
+
coeff[i] *= -1 if sgn_array[i] == '-'
|
34
|
+
end
|
35
|
+
coeff
|
36
|
+
end
|
37
|
+
|
38
|
+
# String implementation of result
|
39
|
+
def str_res_impl(coeff_res, sgn_array)
|
40
|
+
res_size = coeff_res.size
|
41
|
+
res_exp = ""
|
42
|
+
(0..res_size-1).each do |i|
|
43
|
+
res_exp += ((coeff_res[i].ceil(3)).to_s+"*x**"+(res_size - i - 1).to_s)
|
44
|
+
res_exp += sgn_array[i+1] if sgn_array[i+1] != '-'
|
45
|
+
end
|
46
|
+
res_exp
|
47
|
+
end
|
48
|
+
|
49
|
+
# String implementation of remained part
|
50
|
+
def str_rem_impl(coeff_1)
|
51
|
+
c = coeff_1.size
|
52
|
+
rem_exp = ""
|
53
|
+
(0..c-1).each do |i|
|
54
|
+
rem_exp += '+' if coeff_1[i] >= 0.0
|
55
|
+
rem_exp += ((coeff_1[i].ceil(3)).to_s+"*x**"+(c - i - 1).to_s)
|
56
|
+
end
|
57
|
+
rem_exp[0] = '' if rem_exp[0] == '+'
|
58
|
+
rem_exp
|
59
|
+
end
|
60
|
+
|
61
|
+
# This function returns array of 2 strings: first is the result of division polynom poly_1 on polynom poly_2
|
62
|
+
# Second - remainder
|
63
|
+
def polynom_division(poly_1, poly_2)
|
64
|
+
coeff_1 = polynom_parser(poly_1)
|
65
|
+
coeff_2 = polynom_parser(poly_2)
|
66
|
+
res_size = coeff_1.size - coeff_2.size + 1
|
67
|
+
coeff_result = Array.new(res_size)
|
68
|
+
sgn_array = Array.new(res_size + 1,'')
|
69
|
+
(0..res_size-1).each do |i|
|
70
|
+
cur_coeff = coeff_1[i] / coeff_2[0]
|
71
|
+
coeff_result[i] = cur_coeff
|
72
|
+
coeff_result[i] < 0 ? sgn_array[i] = '-' : sgn_array[i] = '+'
|
73
|
+
(0..coeff_2.size-1).each do |j|
|
74
|
+
coeff_1[i+j] -= coeff_2[j]*cur_coeff
|
75
|
+
end
|
76
|
+
end
|
77
|
+
res_exp = str_res_impl(coeff_result, sgn_array)
|
78
|
+
rem_exp = str_rem_impl(coeff_1[coeff_result.size..coeff_1.size-1])
|
79
|
+
[res_exp, rem_exp]
|
80
|
+
end
|
81
|
+
|
82
|
+
def compare_polynoms(poly1, poly2)
|
83
|
+
polynom_parser(poly1).size - polynom_parser(poly2).size
|
84
|
+
end
|
85
|
+
|
86
|
+
def zero_coeffs?(polynom, delta = DELTA)
|
87
|
+
polynom_parser(polynom).all?{ |item| item.abs < delta }
|
88
|
+
end
|
89
|
+
|
90
|
+
def round_coeffs(coefficients, delta = DELTA)
|
91
|
+
coefficients.map do |element|
|
92
|
+
(element.round - element).abs < delta ? element.round.to_f : element
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def build_polynom_from_coeffs(coefficients)
|
97
|
+
"#{coefficients[0]}*x**#{coefficients.size - 1}" +
|
98
|
+
coefficients[1..-1].each_with_index.inject('') do |acc, (coefficient, index)|
|
99
|
+
leading_sign = coefficient >= 0 ? '+' : ''
|
100
|
+
acc + "#{leading_sign}#{coefficient}*x**#{ coefficients.size - index - 2 }"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# This function returns a string: greatest common integer divisor of two polynoms
|
105
|
+
def polynom_gcd(poly1, poly2, delta = DELTA)
|
106
|
+
divisor, remainder = order_gcd_operands(poly1, poly2)
|
107
|
+
until zero_coeffs?(remainder) do
|
108
|
+
division = polynom_division(divisor, remainder)
|
109
|
+
divisor = remainder
|
110
|
+
remainder = division[1]
|
111
|
+
end
|
112
|
+
normalizer = polynom_parser(divisor)[0]
|
113
|
+
temp_result = polynom_division(divisor, normalizer.to_s+'*x**0')[0]
|
114
|
+
coefficients = round_coeffs(polynom_parser(temp_result), delta)
|
115
|
+
build_polynom_from_coeffs(coefficients)
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def order_gcd_operands(poly1, poly2)
|
121
|
+
if compare_polynoms(poly1, poly2) >= 0
|
122
|
+
divisor = poly2
|
123
|
+
remainder = polynom_division(poly1, divisor)[1]
|
124
|
+
else
|
125
|
+
divisor = poly1
|
126
|
+
remainder = polynom_division(poly2, divisor)[1]
|
127
|
+
end
|
128
|
+
[divisor, remainder]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|