aboutsummaryrefslogtreecommitdiff
path: root/src/algebra/geneez.spad.pamphlet
diff options
context:
space:
mode:
Diffstat (limited to 'src/algebra/geneez.spad.pamphlet')
-rw-r--r--src/algebra/geneez.spad.pamphlet248
1 files changed, 248 insertions, 0 deletions
diff --git a/src/algebra/geneez.spad.pamphlet b/src/algebra/geneez.spad.pamphlet
new file mode 100644
index 00000000..74076d65
--- /dev/null
+++ b/src/algebra/geneez.spad.pamphlet
@@ -0,0 +1,248 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra geneez.spad}
+\author{Patrizia Gianni}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{package GENEEZ GenExEuclid}
+<<package GENEEZ GenExEuclid>>=
+)abbrev package GENEEZ GenExEuclid
+++ Author : P.Gianni.
+++ January 1990
+++ The equation \spad{Af+Bg=h} and its generalization to n polynomials
+++ is solved for solutions over the R, euclidean domain.
+++ A table containing the solutions of \spad{Af+Bg=x**k} is used.
+++ The operations are performed modulus a prime which are in principle big enough,
+++ but the solutions are tested and, in case of failure, a hensel
+++ lifting process is used to get to the right solutions.
+++ It will be used in the factorization of multivariate polynomials
+++ over finite field, with \spad{R=F[x]}.
+
+GenExEuclid(R,BP) : C == T
+ where
+ R : EuclideanDomain
+ PI ==> PositiveInteger
+ NNI ==> NonNegativeInteger
+ BP : UnivariatePolynomialCategory R
+ L ==> List
+
+ C == with
+ reduction: (BP,R) -> BP
+ ++ reduction(p,prime) reduces the polynomial p modulo prime of R.
+ ++ Note: this function is exported only because it's conditional.
+ compBound: (BP,L BP) -> NNI
+ ++ compBound(p,lp)
+ ++ computes a bound for the coefficients of the solution
+ ++ polynomials.
+ ++ Given a polynomial right hand side p, and a list lp of left hand side polynomials.
+ ++ Exported because it depends on the valuation.
+ tablePow : (NNI,R,L BP) -> Union(Vector(L BP),"failed")
+ ++ tablePow(maxdeg,prime,lpol) constructs the table with the
+ ++ coefficients of the Extended Euclidean Algorithm for lpol.
+ ++ Here the right side is \spad{x**k}, for k less or equal to maxdeg.
+ ++ The operation returns "failed" when the elements are not coprime modulo prime.
+ solveid : (BP,R,Vector L BP) -> Union(L BP,"failed")
+ ++ solveid(h,table) computes the coefficients of the
+ ++ extended euclidean algorithm for a list of polynomials
+ ++ whose tablePow is table and with right side h.
+
+ testModulus : (R, L BP) -> Boolean
+ ++ testModulus(p,lp) returns true if the the prime p
+ ++ is valid for the list of polynomials lp, i.e. preserves
+ ++ the degree and they remain relatively prime.
+
+ T == add
+ if R has multiplicativeValuation then
+ compBound(m:BP,listpolys:L BP) : NNI ==
+ ldeg:=[degree f for f in listpolys]
+ n:NNI:= (+/[df for df in ldeg])
+ normlist:=[ +/[euclideanSize(u)**2 for u in coefficients f]
+ for f in listpolys]
+ nm:= +/[euclideanSize(u)**2 for u in coefficients m]
+ normprod := */[g**((n-df)::NNI) for g in normlist for df in ldeg]
+ 2*(approxSqrt(normprod * nm)$IntegerRoots(Integer))::NNI
+ else if R has additiveValuation then
+ -- a fairly crude Hadamard-style bound for the solution
+ -- based on regarding the problem as a system of linear equations.
+ compBound(m:BP,listpolys:L BP) : NNI ==
+ "max"/[euclideanSize u for u in coefficients m] +
+ +/["max"/[euclideanSize u for u in coefficients p]
+ for p in listpolys]
+ else
+ compBound(m:BP,listpolys:L BP) : NNI ==
+ error "attempt to use compBound without a well-understood valuation"
+ if R has IntegerNumberSystem then
+ reduction(u:BP,p:R):BP ==
+ p = 0 => u
+ map(symmetricRemainder(#1,p),u)
+ else reduction(u:BP,p:R):BP ==
+ p = 0 => u
+ map(#1 rem p,u)
+
+ merge(p:R,q:R):Union(R,"failed") ==
+ p = q => p
+ p = 0 => q
+ q = 0 => p
+ "failed"
+
+ modInverse(c:R,p:R):R ==
+ (extendedEuclidean(c,p,1)::Record(coef1:R,coef2:R)).coef1
+
+ exactquo(u:BP,v:BP,p:R):Union(BP,"failed") ==
+ invlcv:=modInverse(leadingCoefficient v,p)
+ r:=monicDivide(u,reduction(invlcv*v,p))
+ reduction(r.remainder,p) ^=0 => "failed"
+ reduction(invlcv*r.quotient,p)
+
+ FP:=EuclideanModularRing(R,BP,R,reduction,merge,exactquo)
+
+ --make table global variable!
+ table:Vector L BP
+ import GeneralHenselPackage(R,BP)
+
+ --local functions
+ makeProducts : L BP -> L BP
+ liftSol: (L BP,BP,R,R,Vector L BP,BP,NNI) -> Union(L BP,"failed")
+
+ reduceList(lp:L BP,lmod:R): L FP ==[reduce(ff,lmod) for ff in lp]
+
+ coerceLFP(lf:L FP):L BP == [fm::BP for fm in lf]
+
+ liftSol(oldsol:L BP,err:BP,lmod:R,lmodk:R,
+ table:Vector L BP,m:BP,bound:NNI):Union(L BP,"failed") ==
+ euclideanSize(lmodk) > bound => "failed"
+ d:=degree err
+ ftab:Vector L FP :=
+ map(reduceList(#1,lmod),table)$VectorFunctions2(List BP,List FP)
+ sln:L FP:=[0$FP for xx in ftab.1 ]
+ for i in 0 .. d |(cc:=coefficient(err,i)) ^=0 repeat
+ sln:=[slp+reduce(cc::BP,lmod)*pp
+ for pp in ftab.(i+1) for slp in sln]
+ nsol:=[f-lmodk*reduction(g::BP,lmod) for f in oldsol for g in sln]
+ lmodk1:=lmod*lmodk
+ nsol:=[reduction(slp,lmodk1) for slp in nsol]
+ lpolys:L BP:=table.(#table)
+ (fs:=+/[f*g for f in lpolys for g in nsol]) = m => nsol
+ a:BP:=((fs-m) exquo lmodk1)::BP
+ liftSol(nsol,a,lmod,lmodk1,table,m,bound)
+
+ makeProducts(listPol:L BP):L BP ==
+ #listPol < 2 => listPol
+ #listPol = 2 => reverse listPol
+ f:= first listPol
+ ll := rest listPol
+ [*/ll,:[f*g for g in makeProducts ll]]
+
+ testModulus(pmod, listPol) ==
+ redListPol := reduceList(listPol, pmod)
+ for pol in listPol for rpol in redListPol repeat
+ degree(pol) ^= degree(rpol::BP) => return false
+ while not empty? redListPol repeat
+ rpol := first redListPol
+ redListPol := rest redListPol
+ for rpol2 in redListPol repeat
+ gcd(rpol, rpol2) ^= 1 => return false
+ true
+
+ if R has Field then
+ tablePow(mdeg:NNI,pmod:R,listPol:L BP) ==
+ multiE:=multiEuclidean(listPol,1$BP)
+ multiE case "failed" => "failed"
+ ptable:Vector L BP :=new(mdeg+1,[])
+ ptable.1:=multiE
+ x:BP:=monomial(1,1)
+ for i in 2..mdeg repeat ptable.i:=
+ [tpol*x rem fpol for tpol in ptable.(i-1) for fpol in listPol]
+ ptable.(mdeg+1):=makeProducts listPol
+ ptable
+
+ solveid(m:BP,pmod:R,table:Vector L BP) : Union(L BP,"failed") ==
+ -- Actually, there's no possibility of failure
+ d:=degree m
+ sln:L BP:=[0$BP for xx in table.1]
+ for i in 0 .. d | coefficient(m,i)^=0 repeat
+ sln:=[slp+coefficient(m,i)*pp
+ for pp in table.(i+1) for slp in sln]
+ sln
+
+ else
+
+ tablePow(mdeg:NNI,pmod:R,listPol:L BP) ==
+ listP:L FP:= [reduce(pol,pmod) for pol in listPol]
+ multiE:=multiEuclidean(listP,1$FP)
+ multiE case "failed" => "failed"
+ ftable:Vector L FP :=new(mdeg+1,[])
+ fl:L FP:= [ff::FP for ff in multiE]
+ ftable.1:=[fpol for fpol in fl]
+ x:FP:=reduce(monomial(1,1),pmod)
+ for i in 2..mdeg repeat ftable.i:=
+ [tpol*x rem fpol for tpol in ftable.(i-1) for fpol in listP]
+ ptable:= map(coerceLFP,ftable)$VectorFunctions2(List FP,List BP)
+ ptable.(mdeg+1):=makeProducts listPol
+ ptable
+
+ solveid(m:BP,pmod:R,table:Vector L BP) : Union(L BP,"failed") ==
+ d:=degree m
+ ftab:Vector L FP:=
+ map(reduceList(#1,pmod),table)$VectorFunctions2(List BP,List FP)
+ lpolys:L BP:=table.(#table)
+ sln:L FP:=[0$FP for xx in ftab.1]
+ for i in 0 .. d | coefficient(m,i)^=0 repeat
+ sln:=[slp+reduce(coefficient(m,i)::BP,pmod)*pp
+ for pp in ftab.(i+1) for slp in sln]
+ soln:=[slp::BP for slp in sln]
+ (fs:=+/[f*g for f in lpolys for g in soln]) = m=> soln
+ -- Compute bound
+ bound:=compBound(m,lpolys)
+ a:BP:=((fs-m) exquo pmod)::BP
+ liftSol(soln,a,pmod,pmod,table,m,bound)
+
+@
+\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 GENEEZ GenExEuclid>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}