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
|
# File 'lib/algebra/splitting-field.rb', line 13
def decompose(pre_facts = nil, var_obj = 'a', no_sq = false)
poly = self
ext_field = poly.ground
polys = pre_facts ? pre_facts.dup : poly.factorize
roots = []
addelems = []
cmpelems = []
fac = Factors.new
while fn = polys.shift
f, n = fn
if f.deg <= 1
fac.push [f, n]
roots.concat([-f[0] / f[1]] * n) unless f[1].zero?
cmpelems.concat([-f[0] / f[1]] * n) unless f[1].zero?
else
if !no_sq && f.deg == 2
newF, r, r0 = Algebra.QuadraticExtensionField(ext_field, &f)
roots.concat([r, r0] * n)
addelems.push r
cmpelems.concat([r] * (n - 1))
cmpelems.concat([r0] * n)
px, x = Algebra.Polynomial(newF, 'x')
fac.push [x - r, n]
fac.push [x - r0, n]
q = f.convert_to(px) / (x - r) / (x - r0)
else
newF = Algebra.AlgebraicExtensionField(ext_field, var_obj) do |v|
f.evaluate(v)
end
r = newF.var
roots.concat([r] * n)
addelems.push r
cmpelems.concat([r] * (n - 1))
px, x = Algebra.Polynomial(newF, 'x')
fac.push [x - r, n]
q = f.convert_to(px) / (x - r)
end
polys_new = q.factorize**n
polys.each do |g, m|
g0 = g.convert_to(px)
fc = g0.factorize
polys_new.concat fc**m
end
ext_field = newF
polys = polys_new
var_obj = /^[a-qs-z]\d*$/ =~ var_obj ? var_obj.succ : var_obj + '_'
end
end
mods = if ext_field <= Algebra::AlgebraicExtensionField
ext_field.def_polys
else
[]
end
proots = addelems + cmpelems
[ext_field, mods, fac, roots, proots]
end
|