# Factorization of Multivariate polynomial / Zp
#
# by Shin-ichiro Hara
#
# Version 1.0 (2001.09.14)
require "algebra/m-polynomial"
require "algebra/polynomial"
require "algebra/polynomial-factor"
require "algebra/residue-class-ring"
require "algebra/chinese-rem-th"
require "algebra/m-polynomial-gcd"
#require "algebra/annihilate"
module Algebra
module MPolynomialFactorization
# include PolynomialFactorization::Z
def factorize_modp(an = 0)
f = self
f = f.sqfree_zp if an == 0
an += 1 while f.deg_at(an) <= 0
f = f.pp(an)
lc_of_f = f.lc_at(an)
f = f.monic_int(an)
facts = f._factorize(an)
facts = facts.map!{|f2|
f3 = f2.project(self.class){|c, j| c*lc_of_f**j[an]}
f3.pp(an)
}
facts = facts.fact_all_u(self)
facts.mcorrect_lc!(self, an) { |fac|
fac.factorize_modp(an + 1)
}
facts
end
def verschiebung
ary = vars
ch = ground.char
e = zero
project0 { |c, ind|
c * index_eval(self.class, ary, ind.collect{|i| i/ch})
}
end
def sqfree_zp
f = self
s = unity
until f.constant?
g = f._sqfree
s *= g
f = (f/g).verschiebung
end
s / s.lc
end
# def hensel_lift_zp(g0, f0, char, height)
def hensel_lift_zp(g0, f0, char, height, where)
# self in MPolynomial/int
# g0 in Polyomial/Zp, candidate of factor of f0
# f0 in Polyomial/Zp, one variable reduction of self
# fk = _hensel_lift(g0, f0, char, height) {|ha, ary, cofacts|
fk = _hensel_lift(g0, f0, char, height, where) {|ha, ary, cofacts|
decompose_on_cofactors_modp(ha, ary, cofacts)
}
r = self - fk[0] * fk[1]
if r.zero?
return fk
end
return nil
end
end
end
if __FILE__ == $0
require "algebra/rational"
require "algebra/m-polynomial-factor"
include Algebra
def test(f)
print "#{f}\n => "
a = f.factorize_modp
sw = (f == a.pi)
puts "#{a.inspect}", "#{sw}"
puts
raise unless sw
end
# P = MPolynomial(Rational)
Z7 = ResidueClassRing(Integer, 7)
P = MPolynomial(Z7)
# PS = Polynomial(Z7, "t")
x, y, z = P.vars("xyz")
# x, y, z, t = P.vars("xyzt")
fs = [
x**3 + y**3 + z**3 - 3*x*y*z,
(x + y + 1)**2 * x,
(x + y + 1)**2 * (x + 1),
x**2 + (-z**2 - y*z + y + z + 2)*x + (y*z**3 - z**3 - y**2*z - y*z + 2*z),
(x + z + 1) * (x + y ) * (x + y**2 + z + 2),
(x + z + 1) * (x + y) * (x + y**2 + z),
(x + z + 1) * (x + y)**2 * (x + y**2 + z + 2),
(x + y)*(y + z)*(z + x),
(x + y)*(y + z)*(z + x)**3,
(x * y + 1) * (x * z + 1),
# (t + x)*(t + y)*(t + z),
]
fs.each do |f|
test(f)
end
end
syntax highlighted by Code2HTML, v. 0.9.1