# Galois Group
#
# by Shin-ichiro Hara
#
# Version 1.13 (2002.07.22)
#
# This algorithm is founded on the paper:
# "Computaion of the splitting fields and the Galois groups of polynomials"
# by H. Anai, M. Noro and K. Yokoyama
# (Progress in Mathematics, 29-50, Vol. 143, 1996, Birkhuaser Verlag
# Basel/Swizerland)
require "algebra/ruby-version"
require "algebra/permutation-group"
module Algebra
module Galois
def galois_group(pre_facts = nil, sw = nil)
# sw : Ordinary, sw is asumed to be nil.
poly = sqfree
sf = poly.splitting_field(pre_facts, nil, true)
gens = []
reps0 = []
n = poly.deg
dpn = sf.def_polys.size
for i in 0...dpn do
reps = []
for j in (sw ? i : i+1)...n do
if g = prolong((0...i).to_a + [j], sf)
reps << g
end
end
gens.unshift reps
# gens.push reps
end
for i in dpn...n; gens << [(0...n).to_a]; end if sw
gs = gens.map{|a| a.map{|g| complete(g, sf)}}
ary_of_gens = gs.collect{|a| a.collect{|x| Permutation.new(x)}}
PermutationGroup.generate_strong(Permutation.unity(n), *ary_of_gens)
end
def prolong(ary, sf)
#INPUT
# ary: a set of defining polynomial
# sf: splitting field
#OUTPUT:
# ary0: the first l-part of g if g exists; nil other wize
t = ary.size
roots = sf.proots
pn = sf.def_polys.size
defs = sf.def_polys
for i in 0...t do
r = (roots.values_at(*ary))[0..i]
unless defs[i].abs_lift.evaluate(*r).zero? # this eval. needs no_sq
return nil
end
end
ary0 = ary.dup
for k in t...defs.size do
sw = false
for c in (0...roots.size).to_a - ary0 do
r = (roots.values_at(* ary0+[c]))[0..k]
if defs[k].abs_lift.evaluate(*r).zero? # this eval. needs no_sq
ary0.push c
sw = true
break
end
end
return nil unless sw
end
ary0
end
def complete(ary, sf)
# INPUT:
# ary: the first l-part of g
# sf: splitting field
# OUTPUT:
# ary0: the complete expression of g
ary0 = ary.dup
roots = sf.proots
n = roots.size
m = sf.def_polys.size
for i in m...n
ri = roots[i].abs_lift
h = if ri.is_a? Algebra::Polynomial
r = roots.values_at(*ary0[0...m])
ri.evaluate(*r)
else
ri
end
for k in 0...n
if !ary0.include?(k) && roots[k] == h
ary0.push k
end
end
end
if ary0.size != n
raise "complete: #{ary.inspect} is not extendable."
end
ary0
end
end
end
if __FILE__ == $0
require "algebra/rational"
require "algebra/polynomial"
require "algebra/splitting-field"
P = Algebra.Polynomial(Rational, "x")
x = P.var
f = [
x**3 - 2, #0
(x**2 - 2)*(x**2 - 3),#1
x**3 - 3*x + 1, #2
x**3 - x + 1, #3
(x**3 - 2)**2, #4
x**4 + 1,
x**4 - x + 1,
][ARGV.shift.to_i]
puts "Galois Group of #{f} is:"
f.galois_group.each do |reps|
p reps
end
end
syntax highlighted by Code2HTML, v. 0.9.1