# Algebraic Extension Field
#
# by Shin-ichiro Hara
#
# Version 1.00 (2002.02.27)
require "algebra/polynomial"
#require "algebra/m-polynomial"
require "algebra/residue-class-ring"
require "algebra/polynomial"
module Algebra
def AlgebraicExtensionField(field, var = "x", &b)
AlgebraicExtensionField.create(field, var, &b)
end
module_function :AlgebraicExtensionField
class AlgebraicExtensionField < ResidueClassRing
def self.create(field, var_obj)
poly_ring = Algebra.Polynomial(field, var_obj)
modulus = yield(poly_ring.var)
klass = super(poly_ring, modulus)
# def klass.var; self[ground.var]; end
klass.sysvar :var, klass[klass.ground.var]
klass.sysvar :base, field
if Algebra::AlgebraicExtensionField >= field
env_ring = Algebra.Polynomial(field.env_ring, var_obj)
klass.sysvar :def_polys, field.def_polys + [modulus]
else
env_ring = poly_ring
klass.sysvar :def_polys, [modulus]
end
poly_ring.class_eval <<-__DEF__
def abs_lift
if Algebra::AlgebraicExtensionField >= ground
project(self.class.env_ring) {|c, n| c.abs_lift }
else
project(self.class.env_ring) {|c, n| c }
end
end
__DEF__
poly_ring.sysvar :env_ring, env_ring
klass.sysvar :env_ring, env_ring
klass
end
def [](n)
lift[n]
end
def abs_lift
Algebra::AlgebraicExtensionField >= self.class.base ? lift.abs_lift : lift
end
def self.to_ary
[self, var]
end
end
################# experimental ###################
def QuadraticExtensionField(field, var_obj = nil)
poly_ring = Algebra.Polynomial(field, 'x')
modulus = yield(poly_ring.var)
unless modulus.deg == 2
raise "give deg 2 polynomial to QuadraticicExtensionField."
end
fact = modulus.factorize
if o = fact.find{|x| x[0].deg == 1}
b, a = o[0][0], o[0][1]
c = b / a
return [field, - c, c]
end
c, b, a = modulus[0], modulus[1], modulus[2]
a2 = a * 2
b0 = a2.zero? ? b : (b / a2)
c1 = c / a - b0**2
cs = (-c1).to_s
r = "r"
var_obj ||= r + (/^\d+$/ !~ cs ? "(" + cs + ")" : cs)
klass, v = AlgebraicExtensionField(field, var_obj) {|x| x**2 + c1}
r1 = v - b0
r2 = - v - b0
[klass, r1, r2]
end
module_function :QuadraticExtensionField
def Sqrt(field, a, name = nil)
QuadraticExtensionField(field, nil) {|x| x**2 - a}
end
module_function :Sqrt
def Root(field, a = nil, deg = 2, cs = nil, &b)
r, x = Polynomial(field)
if b
f = b.call(x)
as = a ? a.to_s : f.to_s
else
f = x ** deg - a
as = a.to_s
end
r = deg == 2 ? "r" : "r[#{deg}]"
cs ||= r + (/^\d+$/ !~ as ? "(" + as + ")" : as)
k = f.splitting_field(nil, cs)
[k.field, *k.roots]
end
module_function :Root
end
if $0 == __FILE__
R2, r2, r2_ = Root(Rational, 2)
R3, r3, r3_ = Root(R2, 3)
R6, r6, r6_ = Root(R3, 6)
p r6
p (r6 + r2 + r3)*(r6 + r2 - r3)
P, x = Polynomial(R6, x)
p (x**4 - 60*x**2 + 36).factorize
#=> (x - 2r3 - 3r2)(x + 2r3 - 3r2)(x - 2r3 + 3r2)(x + 2r3 + 3r2)
end
syntax highlighted by Code2HTML, v. 0.9.1