source: git/factory/facNTLzzpEXGCD.cc @ 473102

spielwiese
Last change on this file since 473102 was 473102, checked in by Martin Lee <martinlee84@…>, 11 years ago
various changes/fixes to documentation
  • Property mode set to 100644
File size: 7.7 KB
Line 
1// -*- c++ -*-
2//*****************************************************************************
3/** @file facNTLzzpEXGCD.cc
4 *
5 * @author Martin Lee
6 *
7 * @note the following code is slightly modified code out of
8 * lzz_pEX.c from Victor Shoup's NTL. Below is NTL's copyright notice.
9 *
10 * Univariate GCD and extended GCD over Z/p[t]/(f)[x] for reducible f
11 *
12 * @par Copyright:
13 *   (c) by The SINGULAR Team, see LICENSE file
14 *
15
16                  COPYRIGHT NOTICE
17                    for NTL 5.5
18          (modified for Singular 2-0-6 - 3-1)
19
20NTL -- A Library for Doing Number Theory
21Copyright (C) 1996-2009  Victor Shoup
22
23The most recent version of NTL is available at http://www.shoup.net
24
25This program is free software; you can redistribute it and/or
26modify it under the terms of the GNU General Public License
27as published by the Free Software Foundation; either version 2
28of the License, or (at your option) any later version.
29
30This program is distributed in the hope that it will be useful,
31but WITHOUT ANY WARRANTY; without even the implied warranty of
32MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33GNU General Public License for more details.
34
35You should have received a copy of the GNU General Public License
36along with this program; if not, write to the Free Software
37Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
38
39This entire copyright notice should be placed in an appropriately
40conspicuous place accompanying all distributions of software that
41make use of NTL.
42
43The above terms apply to all of the software modules distributed with NTL,
44i.e., all source files in either the ntl-xxx.tar.gz or WinNTL-xxx.zip
45distributions.  In general, the individual files do not contain
46copyright notices.
47
48Note that the quad_float package is derived from the doubledouble package,
49originally developed by Keith Briggs, and also licensed unger the GNU GPL.
50The files quad_float.c and quad_float.h contain more detailed copyright
51notices.
52
53Note that the traditional long integer package used by NTL, lip.c, is derived
54from---and represents an extensive modification of---
55a package originally developed and copyrighted by Arjen Lenstra,
56who has agreed to renounce any copyright claims on the particular
57version of the long integer package appearing in NTL, so that the
58this package now is covered by the GNU GPL as well.
59
60Note that the alternative long integer package used by NTL is GMP,
61which is written by Torbjorn Granlund <tege@swox.com>.
62GMP is licensed under the terms of the GNU Lesser General Public License.
63
64Note that NTL makes use of the RSA Data Security, Inc. MD5 Message
65Digest Algorithm.
66
67Note that prior to version 4.0, NTL was distributed under the following terms:
68   NTL is freely available for research and educational purposes.
69   I don't want to attach any legalistic licensing restrictions on
70   users of NTL.
71   However, NTL should not be linked in a commercial program
72   (although using data in a commercial
73   product produced by a program that used NTL is fine).
74
75The hope is that the GNU GPL is actually less restrictive than these
76older terms;  however, in any circumstances such that GNU GPL is more
77restrictive, then the following rule is in force:
78versions prior to 4.0 may continue to be used under the old terms,
79but users of versions 4.0 or later should adhere to the terms of the GNU GPL.
80**/
81
82
83#ifdef HAVE_CONFIG_H
84#include "config.h"
85#endif /* HAVE_CONFIG_H */
86
87#include "facNTLzzpEXGCD.h"
88
89#ifdef HAVE_NTL
90#include "NTLconvert.h"
91#endif
92
93#ifdef HAVE_NTL
94
95long InvModStatus (zz_pE& x, const zz_pE& a)
96{
97   return InvModStatus(x._zz_pE__rep, a._zz_pE__rep, zz_pE::modulus());
98}
99
100static
101void SetSize(vec_zz_pX& x, long n, long m)
102{
103   x.SetLength(n);
104   long i;
105   for (i = 0; i < n; i++)
106      x[i].rep.SetMaxLength(m);
107}
108
109void tryPlainRem(zz_pEX& r, const zz_pEX& a, const zz_pEX& b, vec_zz_pX& x,
110                 bool& fail)
111{
112   long da, db, dq, i, j, LCIsOne;
113   const zz_pE *bp;
114   zz_pX *xp;
115
116
117   zz_pE LCInv, t;
118   zz_pX s;
119
120   da = deg(a);
121   db = deg(b);
122
123   if (db < 0) Error("zz_pEX: division by zero");
124
125   if (da < db) {
126      r = a;
127      return;
128   }
129
130   bp = b.rep.elts();
131
132   if (IsOne(bp[db]))
133      LCIsOne = 1;
134   else {
135      LCIsOne = 0;
136      fail= InvModStatus (LCInv, bp[db]);
137      //inv(LCInv, bp[db]);
138      if (fail)
139        return;
140   }
141
142   for (i = 0; i <= da; i++)
143      x[i] = rep(a.rep[i]);
144
145   xp = x.elts();
146
147   dq = da - db;
148
149   for (i = dq; i >= 0; i--) {
150      conv(t, xp[i+db]);
151      if (!LCIsOne)
152         mul(t, t, LCInv);
153      NTL::negate(t, t);
154
155      for (j = db-1; j >= 0; j--) {
156         mul(s, rep(t), rep(bp[j]));
157         add(xp[i+j], xp[i+j], s);
158      }
159   }
160
161   r.rep.SetLength(db);
162   for (i = 0; i < db; i++)
163      conv(r.rep[i], xp[i]);
164   r.normalize();
165}
166
167void tryPlainDivRem(zz_pEX& q, zz_pEX& r, const zz_pEX& a, const zz_pEX& b,
168                    bool& fail)
169{
170   long da, db, dq, i, j, LCIsOne;
171   const zz_pE *bp;
172   zz_pE *qp;
173   zz_pX *xp;
174
175
176   zz_pE LCInv, t;
177   zz_pX s;
178
179   da = deg(a);
180   db = deg(b);
181
182   if (db < 0) Error("zz_pEX: division by zero");
183
184   if (da < db) {
185      r = a;
186      clear(q);
187      return;
188   }
189
190   zz_pEX lb;
191
192   if (&q == &b) {
193      lb = b;
194      bp = lb.rep.elts();
195   }
196   else
197      bp = b.rep.elts();
198
199   if (IsOne(bp[db]))
200      LCIsOne = 1;
201   else {
202      LCIsOne = 0;
203      fail= InvModStatus (LCInv, bp[db]);
204      //inv(LCInv, bp[db]);
205      if (fail)
206        return;
207   }
208
209   vec_zz_pX x;
210
211   SetSize(x, da+1, 2*zz_pE::degree());
212
213   for (i = 0; i <= da; i++)
214      x[i] = rep(a.rep[i]);
215
216   xp = x.elts();
217
218   dq = da - db;
219   q.rep.SetLength(dq+1);
220   qp = q.rep.elts();
221
222   for (i = dq; i >= 0; i--) {
223      conv(t, xp[i+db]);
224      if (!LCIsOne)
225         mul(t, t, LCInv);
226      qp[i] = t;
227      NTL::negate(t, t);
228
229      for (j = db-1; j >= 0; j--) {
230         mul(s, rep(t), rep(bp[j]));
231         add(xp[i+j], xp[i+j], s);
232      }
233   }
234
235   r.rep.SetLength(db);
236   for (i = 0; i < db; i++)
237      conv(r.rep[i], xp[i]);
238   r.normalize();
239}
240
241
242void tryNTLGCD(zz_pEX& x, const zz_pEX& a, const zz_pEX& b, bool& fail)
243{
244   zz_pE t;
245
246   if (IsZero(b))
247      x = a;
248   else if (IsZero(a))
249      x = b;
250   else {
251      long n = max(deg(a),deg(b)) + 1;
252      zz_pEX u(INIT_SIZE, n), v(INIT_SIZE, n);
253
254      vec_zz_pX tmp;
255      SetSize(tmp, n, 2*zz_pE::degree());
256
257      u = a;
258      v = b;
259      do {
260         tryPlainRem(u, u, v, tmp, fail);
261         if (fail)
262           return;
263         swap(u, v);
264      } while (!IsZero(v));
265
266      x = u;
267   }
268
269   if (IsZero(x)) return;
270   if (IsOne(LeadCoeff(x))) return;
271
272   /* make gcd monic */
273
274
275   fail= InvModStatus (t, LeadCoeff(x));
276   if (fail)
277     return;
278   mul(x, x, t);
279}
280
281void tryNTLXGCD(zz_pEX& d, zz_pEX& s, zz_pEX& t, const zz_pEX& a,
282                const zz_pEX& b, bool& fail)
283{
284   zz_pE z;
285
286
287   if (IsZero(b)) {
288      set(s);
289      clear(t);
290      d = a;
291   }
292   else if (IsZero(a)) {
293      clear(s);
294      set(t);
295      d = b;
296   }
297   else {
298      long e = max(deg(a), deg(b)) + 1;
299
300      zz_pEX temp(INIT_SIZE, e), u(INIT_SIZE, e), v(INIT_SIZE, e),
301            u0(INIT_SIZE, e), v0(INIT_SIZE, e),
302            u1(INIT_SIZE, e), v1(INIT_SIZE, e),
303            u2(INIT_SIZE, e), v2(INIT_SIZE, e), q(INIT_SIZE, e);
304
305
306      set(u1); clear(v1);
307      clear(u2); set(v2);
308      u = a; v = b;
309
310      do {
311         fail= InvModStatus (z, LeadCoeff(v));
312         if (fail)
313           return;
314         DivRem(q, u, u, v);
315         swap(u, v);
316         u0 = u2;
317         v0 = v2;
318         mul(temp, q, u2);
319         sub(u2, u1, temp);
320         mul(temp, q, v2);
321         sub(v2, v1, temp);
322         u1 = u0;
323         v1 = v0;
324      } while (!IsZero(v));
325
326      d = u;
327      s = u1;
328      t = v1;
329   }
330
331   if (IsZero(d)) return;
332   if (IsOne(LeadCoeff(d))) return;
333
334   /* make gcd monic */
335
336   fail= InvModStatus (z, LeadCoeff(d));
337   if (fail)
338     return;
339   mul(d, d, z);
340   mul(s, s, z);
341   mul(t, t, z);
342}
343#endif
344
Note: See TracBrowser for help on using the repository browser.