1
2
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
\documentclass{article}
\usepackage{open-axiom}
\begin{document}
\title{\$SPAD/src/algebra multsqfr.spad}
\author{Patrizia Gianni}
\maketitle
\begin{abstract}
\end{abstract}
\eject
\tableofcontents
\eject
\section{package MULTSQFR MultivariateSquareFree}
<<package MULTSQFR MultivariateSquareFree>>=
)abbrev package MULTSQFR MultivariateSquareFree
++Author : P.Gianni
++ This package provides the functions for the computation of the square
++ free decomposition of a multivariate polynomial.
++ It uses the package GenExEuclid for the resolution of
++ the equation \spad{Af + Bg = h} and its generalization to n polynomials
++ over an integral domain and the package \spad{MultivariateLifting}
++ for the "multivariate" lifting.
MultivariateSquareFree (E,OV,R,P) : C == T where
Z ==> Integer
NNI ==> NonNegativeInteger
R : EuclideanDomain
OV : OrderedSet
E : OrderedAbelianMonoidSup
P : PolynomialCategory(R,E,OV)
SUP ==> SparseUnivariatePolynomial P
BP ==> SparseUnivariatePolynomial(R)
fUnion ==> Union("nil","sqfr","irred","prime")
ffSUP ==> Record(flg:fUnion,fctr:SUP,xpnt:Integer)
ffP ==> Record(flg:fUnion,fctr:P,xpnt:Integer)
FFE ==> Record(factor:BP,exponent:Z)
FFEP ==> Record(factor:P,exponent:Z)
FFES ==> Record(factor:SUP,exponent:Z)
Choice ==> Record(upol:BP,Lval:List(R),Lfact:List FFE,ctpol:R)
squareForm ==> Record(unitPart:P,suPart:List FFES)
Twopol ==> Record(pol:SUP,polval:BP)
UPCF2 ==> UnivariatePolynomialCategoryFunctions2
C == with
squareFree : P -> Factored P
++ squareFree(p) computes the square free
++ decomposition of a multivariate polynomial p.
squareFree : SUP -> Factored SUP
++ squareFree(p) computes the square free
++ decomposition of a multivariate polynomial p presented as
++ a univariate polynomial with multivariate coefficients.
squareFreePrim : P -> Factored P
++ squareFreePrim(p) compute the square free decomposition
++ of a primitive multivariate polynomial p.
---- local functions ----
compdegd : List FFE -> Z
++ compdegd should be local
univcase : (P,OV) -> Factored(P)
++ univcase should be local
consnewpol : (SUP,BP,Z) -> Twopol
++ consnewpol should be local
nsqfree : (SUP,List(OV), List List R) -> squareForm
++ nsqfree should be local
intChoose : (SUP,List(OV),List List R) -> Choice
++ intChoose should be local
coefChoose : (Z,Factored P) -> P
++ coefChoose should be local
check : (List(FFE),List(FFE)) -> Boolean
++ check should be local
lift : (SUP,BP,BP,P,List(OV),List(NNI),List(R)) -> Union(List(SUP),"failed")
++ lift should be local
myDegree : (SUP,List OV,NNI) -> List NNI
++ myDegree should be local
normDeriv2 : (BP,Z) -> BP
++ normDeriv2 should be local
T == add
pmod:R := (prevPrime(2**26)$IntegerPrimesPackage(Integer))::R
import GenExEuclid()
import MultivariateLifting(E,OV,R,P)
import PolynomialGcdPackage(E,OV,R,P)
import FactoringUtilities(E,OV,R,P)
import IntegerCombinatoricFunctions(Z)
---- Are the univariate square-free decompositions consistent? ----
---- new square-free algorithm for primitive polynomial ----
nsqfree(oldf:SUP,lvar:List(OV),ltry:List List R) : squareForm ==
f:=oldf
univPol := intChoose(f,lvar,ltry)
-- debug msg
-- if not empty? ltry then output("ltry =", (ltry::OutputForm))$OutputPackage
f0:=univPol.upol
--the polynomial is square-free
f0=1$BP => [1$P,[[f,1]$FFES]]$squareForm
lfact:List(FFE):=univPol.Lfact
lval:=univPol.Lval
ctf:=univPol.ctpol
leadpol:Boolean:=false
sqdec:List FFES := empty()
exp0:Z:=0
unitsq:P:=1
lcf:P:=leadingCoefficient f
if not one? ctf then
f0:=ctf*f0
f:=(ctf::P)*f
lcf:=ctf*lcf
sqlead:List FFEP:= empty()
sqlc:Factored P:=1
if not one? lcf then
leadpol:=true
sqlc:=squareFree lcf
unitsq:=unitsq*(unit sqlc)
sqlead:= factors sqlc
lfact:=sort(#1.exponent > #2.exponent,lfact)
while lfact~=[] repeat
pfact:=lfact.first
(g0,exp0):=(pfact.factor,pfact.exponent)
lfact:=lfact.rest
lfact=[] and exp0 =1 =>
f := (f exquo (ctf::P))::SUP
gg := unitNormal leadingCoefficient f
sqdec:=cons([gg.associate*f,exp0],sqdec)
return [gg.unit, sqdec]$squareForm
if not one? ctf then g0:=ctf*g0
npol:=consnewpol(f,f0,exp0)
(d,d0):=(npol.pol,npol.polval)
if leadpol then lcoef:=coefChoose(exp0,sqlc)
else lcoef:=1$P
ldeg:=myDegree(f,lvar,exp0::NNI)
result:=lift(d,g0,(d0 exquo g0)::BP,lcoef,lvar,ldeg,lval)
result case "failed" => return nsqfree(oldf,lvar,ltry)
result0:SUP:= (result::List SUP).1
r1:SUP:=result0**(exp0:NNI)
if (h:=f exquo r1) case "failed" then return nsqfree(oldf,lvar,empty())
sqdec:=cons([result0,exp0],sqdec)
f:=h::SUP
f0:=completeEval(h,lvar,lval)
lcr:P:=leadingCoefficient result0
if leadpol and not one? lcr then
for lpfact in sqlead while not one? lcr repeat
ground? lcr =>
unitsq:=(unitsq exquo lcr)::P
lcr:=1$P
(h1:=lcr exquo lpfact.factor) case "failed" => "next"
lcr:=h1::P
lpfact.exponent:=(lpfact.exponent)-exp0
[((retract f) exquo ctf)::P,sqdec]$squareForm
squareFree(f:SUP) : Factored SUP ==
degree f =0 =>
fu:=squareFree retract f
makeFR((unit fu)::SUP,[["sqfr",ff.fctr::SUP,ff.xpnt]
for ff in factorList fu])
lvar:= "setUnion"/[variables cf for cf in coefficients f]
empty? lvar => -- the polynomial is univariate
upol:=map(ground,f)$UPCF2(P,SUP,R,BP)
usqfr:=squareFree upol
makeFR(map(coerce,unit usqfr)$UPCF2(R,BP,P,SUP),
[["sqfr",map(coerce,ff.fctr)$UPCF2(R,BP,P,SUP),ff.xpnt]
for ff in factorList usqfr])
lcf:=content f
f:=(f exquo lcf) ::SUP
lcSq:=squareFree lcf
lfs:List ffSUP:=[["sqfr",ff.fctr ::SUP,ff.xpnt]
for ff in factorList lcSq]
partSq:=nsqfree(f,lvar,empty())
lfs:=append([["sqfr",fu.factor,fu.exponent]$ffSUP
for fu in partSq.suPart],lfs)
makeFR((unit lcSq * partSq.unitPart) ::SUP,lfs)
squareFree(f:P) : Factored P ==
ground? f => makeFR(f,[]) --- the polynomial is constant ---
lvar:List(OV):=variables(f)
result1:List ffP:= empty()
lmdeg :=minimumDegree(f,lvar) --- is the mindeg > 0 ? ---
p:P:=1$P
for im in 1..#lvar repeat
(n:=lmdeg.im)=0 => "next im"
y:=lvar.im
p:=p*monomial(1$P,y,n)
result1:=cons(["sqfr",y::P,n],result1)
if not one? p then
f := (f exquo p)::P
if ground? f then return makeFR(f, result1)
lvar:=variables(f)
#lvar=1 => --- the polynomial is univariate ---
result:=univcase(f,lvar.first)
makeFR(unit result,append(result1,factorList result))
ldeg:=degree(f,lvar) --- general case ---
m:="min"/[j for j in ldeg|j~=0]
i:Z:=1
for j in ldeg while j>m repeat i:=i+1
x:=lvar.i
lvar:=delete(lvar,i)
f0:=univariate (f,x)
lcont:P:= content f0
nsqfftot:=nsqfree((f0 exquo lcont)::SUP,lvar,empty())
nsqff:List ffP:=[["sqfr",multivariate(fu.factor,x),fu.exponent]$ffP
for fu in nsqfftot.suPart]
result1:=append(result1,nsqff)
ground? lcont => makeFR(lcont*nsqfftot.unitPart,result1)
sqlead:=squareFree(lcont)
makeFR(unit sqlead*nsqfftot.unitPart,append(result1,factorList sqlead))
-- Choose the integer for the evaluation. --
-- If the polynomial is square-free the function returns upol=1. --
intChoose(f:SUP,lvar:List(OV),ltry:List List R):Choice ==
degf:= degree f
tryCount:NNI:=0
nvr:=#lvar
range:Z:=10
lfact1:List(FFE):=[]
lval1:List R := []
lfact:List(FFE)
ctf1:R:=1
f1:BP:=1$BP
d1:Z
while range < 10000000000 repeat
range:=2*range
lval:= [ran(range) for i in 1..nvr]
member?(lval,ltry) => "new integer"
ltry:=cons(lval,ltry)
f0:=completeEval(f,lvar,lval)
degree f0 ~=degf => "new integer"
ctf:=content f0
lfact:List(FFE):=factors(squareFree((f0 exquo (ctf:R)::BP)::BP))
---- the univariate polynomial is square-free ----
if #lfact=1 and (lfact.1).exponent=1 then
return [1$BP,lval,lfact,1$R]$Choice
d0:=compdegd lfact
---- inizialize lfact1 ----
tryCount=0 =>
f1:=f0
lfact1:=lfact
ctf1:=ctf
lval1:=lval
d1:=d0
tryCount:=1
d0=d1 =>
return [f1,lval1,lfact1,ctf1]$Choice
d0 < d1 =>
tryCount:=1
f1:=f0
lfact1:=lfact
ctf1:=ctf
lval1:=lval
d1:=d0
error "intChoose$MULTQFR: fell off loop without value"
---- Choose the leading coefficient for the lifting ----
coefChoose(exp:Z,sqlead:Factored(P)) : P ==
lcoef:P:=unit(sqlead)
for term in factors(sqlead) repeat
texp:=term.exponent
texp<exp => "next term"
texp=exp => lcoef:=lcoef*term.factor
lcoef:=lcoef*(term.factor)**((texp quo exp)::NNI)
lcoef
---- Construction of the polynomials for the lifting ----
consnewpol(g:SUP,g0:BP,deg:Z):Twopol ==
deg=1 => [g,g0]$Twopol
deg:=deg-1
[normalDeriv(g,deg),normDeriv2(g0,deg)]$Twopol
---- lift the univariate square-free factor ----
lift(ud:SUP,g0:BP,g1:BP,lcoef:P,lvar:List(OV),
ldeg:List(NNI),lval:List(R)) : Union(List SUP,"failed") ==
leadpol:Boolean:=false
lcd:P:=leadingCoefficient ud
leadlist:List(P):=empty()
if not ground?(leadingCoefficient ud) then
leadpol:=true
ud:=lcoef*ud
lcg0:R:=leadingCoefficient g0
if ground? lcoef then g0:=retract(lcoef) quo lcg0 *g0
else g0:=(retract(eval(lcoef,lvar,lval)) quo lcg0) * g0
g1:=lcg0*g1
leadlist:=[lcoef,lcd]
plist:=lifting(ud,lvar,[g0,g1],lval,leadlist,ldeg,pmod)
plist case "failed" => "failed"
(p0:SUP,p1:SUP):=((plist::List SUP).1,(plist::List SUP).2)
if completeEval(p0,lvar,lval) ~= g0 then (p0,p1):=(p1,p0)
[primitivePart p0,primitivePart p1]
---- the polynomial is univariate ----
univcase(f:P,x:OV) : Factored(P) ==
uf := univariate f
cf:=content uf
uf :=(uf exquo cf)::BP
result:Factored BP:=squareFree uf
makeFR(multivariate(cf*unit result,x),
[["sqfr",multivariate(term.factor,x),term.exponent]
for term in factors result])
-- squareFreePrim(p:P) : Factored P ==
-- -- p is content free
-- ground? p => makeFR(p,[]) --- the polynomial is constant ---
--
-- lvar:List(OV):=variables p
-- #lvar=1 => --- the polynomial is univariate ---
-- univcase(p,lvar.first)
-- nsqfree(p,lvar,1)
compdegd(lfact:List(FFE)) : Z ==
ris:Z:=0
for pfact in lfact repeat
ris:=ris+(pfact.exponent -1)*degree pfact.factor
ris
normDeriv2(f:BP,m:Z) : BP ==
(n1:Z:=degree f) < m => 0$BP
n1=m => (leadingCoefficient f)::BP
k:=binomial(n1,m)
ris:BP:=0$BP
n:Z:=n1
while n>= m repeat
while n1>n repeat
k:=(k*(n1-m)) quo n1
n1:=n1-1
ris:=ris+monomial(k*leadingCoefficient f,(n-m)::NNI)
f:=reductum f
n:=degree f
ris
myDegree(f:SUP,lvar:List OV,exp:NNI) : List NNI==
[n quo exp for n in degree(f,lvar)]
@
\section{License}
<<license>>=
--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
-- names of its contributors may be used to endorse or promote products
-- derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@
<<*>>=
<<license>>
<<package MULTSQFR MultivariateSquareFree>>
@
\eject
\begin{thebibliography}{99}
\bibitem{1} nothing
\end{thebibliography}
\end{document}
|