source: git/polys/longtrans.cc @ 3fe3da0

fieker-DuValspielwiese
Last change on this file since 3fe3da0 was aff5ae, checked in by Hans Schoenemann <hannes@…>, 14 years ago
nInitChar and related stuff
  • Property mode set to 100644
File size: 51.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longtrans.cc 12469 2011-02-25 13:38:49Z seelisch $ */
5/*
6* ABSTRACT:   numbers in transcendental field extensions, i.e.,
7              in rational function fields
8*/
9
10#if 0
11#include <stdio.h>
12#include <string.h>
13#include <kernel/mod2.h>
14#include <kernel/structs.h>
15#include <omalloc/omalloc.h>
16#include <kernel/febase.h>
17#include <kernel/longrat.h>
18#include <kernel/modulop.h>
19#include <kernel/numbers.h>
20#include <kernel/polys.h>
21#include <kernel/ideals.h>
22#include <kernel/ring.h>
23#ifdef HAVE_FACTORY
24#define SI_DONT_HAVE_GLOBAL_VARS
25#include <factory/factory.h>
26#include <kernel/clapsing.h>
27#include <kernel/clapconv.h>
28#endif
29#include <kernel/longtrans.h>
30#include <kernel/longalg.h>
31
32ring nacRing;
33int  ntIsChar0;
34ring ntMapRing;
35int  ntParsToCopy;
36int  ntNumbOfPar;
37
38numberfunc  nacMult, nacSub, nacAdd, nacDiv, nacIntDiv;
39number      (*ntMap)(number from);
40number      (*nacGcd)(number a, number b, const ring r);
41number      (*nacLcm)(number a, number b, const ring r);
42number      (*nacInit)(int i, const ring r);
43int         (*nacInt)(number &n, const ring r);
44void        (*nacNormalize)(number &a);
45number      (*nacNeg)(number a);
46number      (*nacCopy)(number a);
47number      (*nacInvers)(number a);
48BOOLEAN     (*nacIsZero)(number a);
49BOOLEAN     (*nacIsOne)(number a);
50BOOLEAN     (*nacGreaterZero)(number a);
51BOOLEAN     (*nacGreater)(number a, number b);
52number      (*nacMap)(number);
53
54#ifdef LDEBUG
55#define ntTest(a) ntDBTest(a,__FILE__,__LINE__)
56BOOLEAN ntDBTest(number a, const char *f,const int l);
57#else
58#define ntTest(a)
59#endif
60
61//static number ntdGcd( number a, number b, const ring r) { return nacInit(1,r); }
62/*2
63*  sets the appropriate operators
64*/
65void ntSetChar(int i, ring r)
66{
67  assume((r->minpoly  == NULL) &&
68         (r->minideal == NULL)    );
69 
70  if (naI!=NULL)
71  {
72    int j;
73    for (j=naI->anz-1; j>=0; j--)
74       p_Delete (&naI->liste[j],nacRing);
75    omFreeSize((ADDRESS)naI->liste,naI->anz*sizeof(napoly));
76    omFreeBin((ADDRESS)naI, snaIdeal_bin);
77    naI=NULL;
78  }
79  ntMap = ntCopy;
80  naMinimalPoly = NULL;
81
82  ntNumbOfPar=rPar(r);
83  if (i == 1)
84    ntIsChar0 = 1;
85  else if (i < 0)
86  {
87    ntIsChar0 = 0;
88    npSetChar(-i, r->algring); // to be changed HS
89  }
90#ifdef TEST
91  else
92  {
93    Print("ntSetChar:c=%d param=%d\n",i,rPar(r));
94  }
95#endif
96  nacRing        = r->algring;
97  nacInit        = nacRing->cf->cfInit;
98  nacInt         = nacRing->cf->n_Int;
99  nacCopy        = nacRing->cf->nCopy;
100  nacAdd         = nacRing->cf->nAdd;
101  nacSub         = nacRing->cf->nSub;
102  nacNormalize   = nacRing->cf->nNormalize;
103  nacNeg         = nacRing->cf->nNeg;
104  nacIsZero      = nacRing->cf->nIsZero;
105  nacGreaterZero = nacRing->cf->nGreaterZero;
106  nacGreater     = nacRing->cf->nGreater;
107  nacIsOne       = nacRing->cf->nIsOne;
108  nacGcd         = nacRing->cf->nGcd;
109  nacLcm         = nacRing->cf->nLcm;
110  nacMult        = nacRing->cf->nMult;
111  nacDiv         = nacRing->cf->nDiv;
112  nacIntDiv      = nacRing->cf->nIntDiv;
113  nacInvers      = nacRing->cf->nInvers;
114}
115
116/*============= procedure for polynomials: napXXXX =======================*/
117
118#ifdef LDEBUG
119void napTest(napoly p)
120{
121  if (ntIsChar0)
122  {
123    while (p != NULL)
124    {
125      nlDBTest(pGetCoeff(p), "", 0);
126      pIter(p);
127    }
128  }
129}
130#else
131#define napTest(p) ((void) 0)
132#endif
133
134/* creates a new napoly that consists of a
135   single coefficient (provided as a number);
136   the provided number is NOT const */
137napoly napInitz(number z)
138{
139  napoly a = (napoly)p_Init(nacRing);
140  pGetCoeff(a) = z;
141  return a;
142}
143
144/* creates a new napoly which is the
145   negative inverse of the argument;
146   keeps p */
147napoly napCopyNeg(const napoly p)
148{
149  napoly r = napCopy(p);
150  r = (napoly)p_Neg((poly)r, nacRing);
151  return r;
152}
153
154/* modifies the napoly p to p*z, i.e.
155   in-place multiplication of p with the number z;
156   keeps z */
157void napMultN(napoly p, const number z)
158{
159  number t;
160  while (p != NULL)
161  {
162    t = nacMult(pGetCoeff(p), z);
163    nacNormalize(t);
164    n_Delete(&pGetCoeff(p),nacRing);
165    pGetCoeff(p) = t;
166    pIter(p);
167  }
168}
169
170/* division of f by g with remainder
171   (with respect to the first variable),
172   f = g * q + r,
173   assumes that the exponent of the first variable
174   in f is greater than or equal to that in g
175   sets q, r; destroys f; keeps g */
176void napDivMod(napoly f, const napoly  g, napoly *q, napoly *r)
177{
178  napoly a, h, b, qq;
179
180  qq = (napoly)p_Init(nacRing);
181  pNext(qq) = b = NULL;
182  p_Normalize(g, nacRing);
183  p_Normalize(f, nacRing);
184  a = f;
185  assume(p_GetExp(a, 1, nacRing) >= p_GetExp(g, 1, nacRing));
186  do
187  {
188    napSetExp(qq, 1, p_GetExp(a, 1, nacRing) - p_GetExp(g, 1, nacRing));
189    p_Setm(qq, nacRing);
190    pGetCoeff(qq) = nacDiv(pGetCoeff(a), pGetCoeff(g));
191    nacNormalize(pGetCoeff(qq));
192    b = napAdd(b, napCopy(qq));
193    pGetCoeff(qq) = nacNeg(pGetCoeff(qq));
194    h = napCopy(g);
195    napMultT(h, qq);
196    p_Normalize(h, nacRing);
197    n_Delete(&pGetCoeff(qq), nacRing);
198    a = napAdd(a, h);
199  }
200  while ((a != NULL) &&
201         (p_GetExp(a, 1, nacRing) >= p_GetExp(g, 1, nacRing)));
202  omFreeBinAddr(qq);
203  *q = b;
204  *r = a;
205}
206
207/* remainder of division of f by g
208   (with respect to the first variable),
209   f = g * q + r,
210   assumes that the exponent of the first variable
211   in f is greater than or equal to that in g
212   destroys f; keeps g; returns r */
213napoly napRemainder(napoly f, const napoly g)
214{
215  napoly a, h, qq;
216
217  qq = (napoly)p_Init(nacRing);
218  pNext(qq) = NULL;
219  p_Normalize(g, nacRing);
220  p_Normalize(f, nacRing);
221  a = f;
222  assume(p_GetExp(a, 1, nacRing) >= p_GetExp(g, 1, nacRing));
223  do
224  {
225    napSetExp(qq, 1, p_GetExp(a, 1, nacRing) - p_GetExp(g, 1, nacRing));
226    napSetm(qq);
227    pGetCoeff(qq) = nacDiv(pGetCoeff(a), pGetCoeff(g));
228    pGetCoeff(qq) = nacNeg(pGetCoeff(qq));
229    nacNormalize(pGetCoeff(qq));
230    h = napCopy(g);
231    napMultT(h, qq);
232    p_Normalize(h, nacRing);
233    n_Delete(&pGetCoeff(qq), nacRing);
234    a = napAdd(a, h);
235  }
236  while ((a != NULL) &&
237         (p_GetExp(a,1,nacRing) >= p_GetExp(g,1,nacRing)));
238  omFreeBinAddr(qq);
239  return a;
240}
241
242/* returns z such that z * x mod c = 1;
243   if there is no solution, an error is reported and
244   some intermediate version of x is returned;
245   modifies x; keeps c */
246napoly napInvers(napoly x, const napoly c)
247{
248  napoly y, r, qa, qn, q;
249  number t;
250
251  if (p_GetExp(x, 1, nacRing) >= p_GetExp(c, 1, nacRing))
252    x = napRemainder(x, c);
253  if (x == NULL)
254  {
255    WerrorS("zero divisor found - your minpoly is not irreducible");
256    return NULL;
257  }
258  if (p_GetExp(x, 1, nacRing) == 0)
259  {
260    if (!nacIsOne(pGetCoeff(x)))
261    {
262      nacNormalize(pGetCoeff(x));
263      t = nacInvers(pGetCoeff(x));
264      nacNormalize(t);
265      n_Delete(&pGetCoeff(x), nacRing);
266      pGetCoeff(x) = t;
267    }
268    return x;
269  }
270  y = napCopy(c);
271  napDivMod(y, x, &qa, &r);
272  if (r == NULL)
273  {
274    WerrorS("x is not invertible modulo c(1)");
275    return x;
276  }
277  if (p_GetExp(r, 1, nacRing) == 0)
278  {
279    nacNormalize(pGetCoeff(r));
280    t = nacInvers(pGetCoeff(r));
281    nacNormalize(t);
282    t = nacNeg(t);
283    napMultN(qa, t);
284    n_Delete(&t, nacRing);
285    p_Normalize(qa, nacRing);
286    p_Delete(&x, nacRing);
287    p_Delete(&r, nacRing);
288    return qa;
289  }
290  y = x;
291  x = r;
292  napDivMod(y, x, &q, &r);
293  if (r == NULL)
294  {
295    WerrorS("x is not invertible modulo c(2)");
296    return x;
297  }
298  if (p_GetExp(r, 1, nacRing) == 0)
299  {
300    q = p_Mult_q(q, qa,nacRing);
301    q = napAdd(q, p_ISet(1, nacRing));
302    nacNormalize(pGetCoeff(r));
303    t = nacInvers(pGetCoeff(r));
304    napMultN(q, t);
305    p_Normalize(q, nacRing);
306    n_Delete(&t, nacRing);
307    p_Delete(&x, nacRing);
308    p_Delete(&r, nacRing);
309    if (p_GetExp(q, 1, nacRing) >= p_GetExp(c, 1, nacRing))
310      q = napRemainder(q, c);
311    return q;
312  }
313  q = p_Mult_q(q, napCopy(qa), nacRing);
314  q = napAdd(q, p_ISet(1, nacRing));
315  qa = napNeg(qa);
316  loop
317  {
318    y = x;
319    x = r;
320    napDivMod(y, x, &qn, &r);
321    if (r == NULL)
322    {
323      WerrorS("zero divisor found - your minpoly is not irreducible");
324      return x;
325    }
326    if (p_GetExp(r, 1, nacRing) == 0)
327    {
328      q = p_Mult_q(q, qn, nacRing);
329      q = napNeg(q);
330      q = napAdd(q, qa);
331      nacNormalize(pGetCoeff(r));
332      t = nacInvers(pGetCoeff(r));
333      //nacNormalize(t);
334      napMultN(q, t);
335      p_Normalize(q, nacRing);
336      n_Delete(&t, nacRing);
337      p_Delete(&x, nacRing);
338      p_Delete(&r, nacRing);
339      if (p_GetExp(q, 1, nacRing) >= p_GetExp(c, 1, nacRing))
340        q = napRemainder(q, c);
341      return q;
342    }
343    y = q;
344    q = p_Mult_q(napCopy(q), qn, nacRing);
345    q = napNeg(q);
346    q = napAdd(q, qa);
347    qa = y;
348  }
349}
350
351/* the degree of a napoly, i.e. the
352   maximum of all terms' degrees;
353   keeps p */
354int napMaxDeg(napoly p)
355{
356  int  d = 0;
357  while (p != NULL)
358  {
359    d=si_max(d, napDeg(p));
360    pIter(p);
361  }
362  return d;
363}
364
365/* the degree of a napoly, i.e. the
366   maximum of all terms' degrees;
367   fills l with the number of terms;
368   keeps p */
369int napMaxDegLen(napoly p, int &l)
370{
371  int d = 0;
372  l = 0;
373  while (p != NULL)
374  {
375    d = si_max(d, napDeg(p));
376    pIter(p);
377    l++;
378  }
379  return d;
380}
381
382
383/* writes a napoly, i.e. a number in the ground field;
384   if has_denom is TRUE, the output is ready to be
385   followed by a non-trivial denominator;
386   r is assumed to be a polynomial ring over an algebraic
387   or transcendental field extension;
388   keeps all arguments */
389void napWrite(napoly p, const BOOLEAN has_denom, const ring r)
390{
391  ring nacring = r->algring;
392  if (p == NULL) StringAppendS("0");
393  else if (p_LmIsConstant(p, nacring))
394  {
395    BOOLEAN kl = FALSE;
396    if (has_denom)
397    {
398      number den = nacring->cf->cfGetDenom(pGetCoeff(p), nacring);
399      kl = !n_IsOne(den, nacring);
400      n_Delete(&den, nacring);
401    }
402    if (kl) StringAppendS("(");
403    n_Write(pGetCoeff(p), nacring);
404    if (kl) StringAppendS(")");
405  }
406  else
407  {
408    StringAppendS("(");
409    loop
410    {
411      BOOLEAN wroteCoeff = FALSE;
412      if ((p_LmIsConstant(p, nacring)) ||
413           ((!n_IsOne(pGetCoeff(p), nacring)) &&
414            (!n_IsMOne(pGetCoeff(p),nacring))))
415      {
416        n_Write(pGetCoeff(p), nacring);
417        wroteCoeff = (r->ShortOut == 0);
418      }
419      else if (n_IsMOne(pGetCoeff(p), nacring)) StringAppendS("-");
420      for (int i = 0; i < r->P; i++)
421      {
422        int e = p_GetExp(p, i+1, nacring);
423        if (e > 0)
424        {
425          if (wroteCoeff) StringAppendS("*");
426          else            wroteCoeff=(r->ShortOut==0);
427          StringAppendS(r->parameter[i]);
428          if (e > 1)
429          {
430            if (r->ShortOut == 0) StringAppendS("^");
431            StringAppend("%d", e);
432          }
433        }
434      }
435      pIter(p);
436      if (p == NULL) break;
437      if (n_GreaterZero(pGetCoeff(p),nacring)) StringAppendS("+");
438    }
439    StringAppendS(")");
440  }
441}
442
443/* helper for napRead */
444const char* napHandleMons(const char* s, int i, napoly ex)
445{
446  int j;
447  if (strncmp(s, ntParNames[i], strlen(ntParNames[i])) == 0)
448  {
449    s += strlen(ntParNames[i]);
450    if ((*s >= '0') && (*s <= '9'))
451    {
452      s = eati(s, &j);
453      napAddExp(ex, i+1, j);
454    }
455    else
456      napAddExp(ex, i+1, 1);
457  }
458  return s;
459}
460
461/* helper for napRead */
462const char* napHandlePars(const char *s, int i, napoly ex)
463{
464  if (strcmp(s, ntParNames[i]) == 0)
465  {
466    s += strlen(ntParNames[i]);
467    napSetExp(ex, i+1, 1);
468  }
469  return s;
470}
471
472/* reads a monomial into the napoly b;
473   returns the latter portion of s which
474   comes "after" the monomial that has
475   just been read;
476   modifies b */
477const char* napRead(const char *s, napoly *b)
478{
479  napoly a;
480  int i;
481  a = (napoly)p_Init(nacRing);
482  if ((*s >= '0') && (*s <= '9'))
483  {
484    s = nacRing->cf->nRead(s, &pGetCoeff(a));
485    if (nacIsZero(pGetCoeff(a)))
486    {
487      p_LmDelete(&a, nacRing);
488      *b = NULL;
489      return s;
490    }
491  }
492  else pGetCoeff(a) = nacInit(1,nacRing);
493  i = 0;
494  const char* olds = s;
495  loop
496  {
497    s = napHandlePars(s, i, a);
498    if (olds == s) i++;
499    else if (*s == '\0')
500    {
501      *b = a;
502      return s;
503    }
504    if (i >= ntNumbOfPar) break;
505  }
506  i = 0;
507  loop
508  {
509    olds = s;
510    s = napHandleMons(s, i, a);
511    if (olds == s) i++;
512    else i = 0;
513    if ((*s == '\0') || (i >= ntNumbOfPar)) break;
514  }
515  *b = a;
516  return s;
517}
518
519/* considers the lowest terms la of a and lb of b;
520   returns the minimum of the two exponents of the
521   first variable in la and lb;
522   assumes a != NULL, b != NULL;
523   keeps a and b */
524int napExp(napoly a, napoly b)
525{
526  assume(a != NULL);
527  assume(b != NULL);
528  while (pNext(a) != NULL) pIter(a);
529  int m = p_GetExp(a, 1, nacRing);
530  if (m == 0) return 0;
531  while (pNext(b) != NULL) pIter(b);
532  int mm = p_GetExp(b, 1, nacRing);
533  if (m > mm) m = mm;
534  return m;
535}
536
537/* returns the smallest i-th exponent in a and b;
538   used to find it in a fraction;
539   keeps a and b */
540int napExpi(int i, napoly a, napoly b)
541{
542  if (a == NULL || b == NULL) return 0;
543  int m = p_GetExp(a, i+1, nacRing);
544  if (m == 0) return 0;
545  while (pNext(a) != NULL)
546  {
547    pIter(a);
548    if (m > p_GetExp(a, i+1, nacRing))
549    {
550      m = p_GetExp(a, i+1, nacRing);
551      if (m == 0) return 0;
552    }
553  }
554  do
555  {
556    if (m > p_GetExp(b, i+1, nacRing))
557    {
558      m = p_GetExp(b, i+1, nacRing);
559      if (m == 0) return 0;
560    }
561    pIter(b);
562  }
563  while (b != NULL);
564  return m;
565}
566
567/* divides out the content of the given napoly;
568   assumes that ph != NULL;
569   modifies ph */
570void napContent(napoly ph)
571{
572  number h, d;
573  napoly p;
574
575  assume(ph != NULL);
576  p = ph;
577  if (nacIsOne(pGetCoeff(p))) return;
578  h = nacCopy(pGetCoeff(p));
579  pIter(p);
580  while (p != NULL)
581  {
582    d = nacGcd(pGetCoeff(p), h, nacRing);
583    if (nacIsOne(d))
584    {
585      n_Delete(&h,nacRing);
586      n_Delete(&d,nacRing);
587      return;
588    }
589    n_Delete(&h, nacRing);
590    h = d;
591    pIter(p);
592  }
593  h = nacInvers(d);
594  n_Delete(&d, nacRing);
595  p = ph;
596  while (p != NULL)
597  {
598    d = nacMult(pGetCoeff(p), h);
599    n_Delete(&pGetCoeff(p), nacRing);
600    pGetCoeff(p) = d;
601    pIter(p);
602  }
603  n_Delete(&h, nacRing);
604}
605
606/* removes denominators of coefficients in ph
607   by multiplication with lcm of those;
608   if char != 0, then nothing is done;
609   modifies ph */
610void napCleardenom(napoly ph)
611{
612  number d, h;
613  napoly p;
614
615  if (!ntIsChar0) return;
616  p = ph;
617  h = nacInit(1,nacRing);
618  while (p!=NULL)
619  {
620    d = nacLcm(h, pGetCoeff(p), nacRing); // uses denominator of pGetCoeff(p)
621    n_Delete(&h,nacRing);
622    h = d;
623    pIter(p);
624  }
625  if(!nacIsOne(h))
626  {
627    p = ph;
628    while (p!=NULL)
629    {
630      d=nacMult(h, pGetCoeff(p));
631      n_Delete(&pGetCoeff(p),nacRing);
632      nacNormalize(d);
633      pGetCoeff(p) = d;
634      pIter(p);
635    }
636  }
637  n_Delete(&h,nacRing);
638  napContent(ph);
639}
640
641/* returns the gcd of all coefficients in a and b;
642   assumes a != NULL, b != NULL;
643   keeps a, keeps b */
644napoly napGcd0(napoly a, napoly b)
645{
646  number x, y;
647  assume(a != NULL);
648  assume(b != NULL);
649  if (!ntIsChar0) return p_ISet(1, nacRing);
650  x = nacCopy(pGetCoeff(a));
651  if (nacIsOne(x)) return napInitz(x);
652  pIter(a);
653  while (a!=NULL)
654  {
655    y = nacGcd(x, pGetCoeff(a), nacRing);
656    n_Delete(&x,nacRing);
657    x = y;
658    if (nacIsOne(x)) return napInitz(x);
659    pIter(a);
660  }
661  do
662  {
663    y = nacGcd(x, pGetCoeff(b), nacRing);
664    n_Delete(&x,nacRing);
665    x = y;
666    if (nacIsOne(x)) return napInitz(x);
667    pIter(b);
668  }
669  while (b!=NULL);
670  return napInitz(x);
671}
672
673/* returns the gcd of a and b;
674   if char != 0, then the constant poly 1 is returned;
675   if a = b = 0, then the constant poly 1 is returned;
676   if a = 0 != b, then b is returned;
677   if a != 0 = b, then a is returned;
678   keeps a, keeps b */
679napoly napGcd(napoly a, napoly b)
680{
681  int i;
682  napoly g, x, y, h;
683  if (a == NULL)
684  {
685    if (b == NULL)    return p_ISet(1,nacRing);
686    else              return napCopy(b);
687  }
688  else if (b == NULL) return napCopy(a);
689 
690  if (naMinimalPoly != NULL)
691  { // we have an algebraic extension
692    if (p_GetExp(a,1,nacRing) >= p_GetExp(b,1,nacRing))
693    {
694      x = a;
695      y = b;
696    }
697    else
698    {
699      x = b;
700      y = a;
701    }
702    if (!ntIsChar0) g = p_ISet(1,nacRing);
703    else            g = napGcd0(x, y);
704    if (pNext(y)==NULL)
705    {
706      napSetExp(g,1, napExp(x, y));
707      p_Setm(g,nacRing);
708      return g;
709    }
710    x = napCopy(x);
711    y = napCopy(y);
712    loop
713    {
714      h = napRemainder(x, y);
715      if (h==NULL)
716      {
717        napCleardenom(y);
718        if (!nacIsOne(pGetCoeff(g)))
719          napMultN(y, pGetCoeff(g));
720        p_LmDelete(&g,nacRing);
721        return y;
722      }
723      else if (pNext(h)==NULL)
724        break;
725      x = y;
726      y = h;
727    }
728    p_Delete(&y,nacRing);
729    p_LmDelete(&h,nacRing);
730    napSetExp(g,1, napExp(a, b));
731    p_Setm(g,nacRing);
732    return g;
733  }
734  else
735  { // we have ntNumbOfPar transcendental variables
736    if (!ntIsChar0) x = p_ISet(1,nacRing);
737    else            x = napGcd0(a,b);
738    for (i=(ntNumbOfPar-1); i>=0; i--)
739    {
740      napSetExp(x,i+1, napExpi(i,a,b));
741      p_Setm(x,nacRing);
742    }
743    return x;
744  }
745}
746
747/* returns the lcm of all denominators in the coefficients of a;
748   if char != 0, then the constant poly 1 is returned;
749   if a = 0, then the constant poly 1 is returned;
750   keeps a */
751number napLcm(napoly a)
752{
753  number h = nacInit(1,nacRing);
754  if (ntIsChar0)
755  {
756    number d;
757    napoly b = a;
758    while (b!=NULL)
759    {
760      d = nacLcm(h, pGetCoeff(b), nacRing); // uses denominator of pGetCoeff(b)
761      n_Delete(&h,nacRing);
762      h = d;
763      pIter(b);
764    }
765  }
766  return h;
767}
768
769/*2
770* meins  (for reduction in algebraic extension)
771* checks if head of p divides head of q
772* doesn't delete p and q
773*/
774BOOLEAN napDivPoly (napoly p, napoly q)
775{
776  int j=1;   /* evtl. von naNumber.. -1 abwaerts zaehlen */
777
778  while (p_GetExp(p,j,nacRing) <= p_GetExp(q,j,nacRing))
779  {
780    j++;
781    if (j > ntNumbOfPar)
782      return 1;
783  }
784  return 0;
785}
786
787
788/*
789 * only used for reduction in algebraic extensions when naI != NULL;
790 * reduces the tail of poly q which is required to be != NULL;
791 * modifies q and returns it
792 */
793napoly napRedp (napoly q)
794{
795  napoly h = (napoly)p_Init(nacRing);
796  int i=0,j;
797
798  loop
799  {
800    if (napDivPoly (naI->liste[i], q))
801    {
802      /* h = lt(q)/lt(naI->liste[i])*/
803      pGetCoeff(h) = nacCopy(pGetCoeff(q));
804      for (j=ntNumbOfPar; j>0; j--)
805        napSetExp(h,j, p_GetExp(q,j,nacRing) - p_GetExp(naI->liste[i],
806                                                        j,nacRing));
807      p_Setm(h,nacRing);
808      h = p_Mult_q(h, napCopy(naI->liste[i]),nacRing);
809      h = napNeg (h);
810      q = napAdd (q, napCopy(h));
811      p_Delete (&pNext(h),nacRing);
812      if (q == NULL)
813      {
814        p_Delete(&h,nacRing);
815        return q;
816      }
817      /* try to reduce further */
818      i = 0;
819    }
820    else
821    {
822      i++;
823      if (i >= naI->anz)
824      {
825        p_Delete(&h,nacRing);
826        return q;
827      }
828    }
829  }
830}
831
832
833/*
834 * only used for reduction in algebraic extensions when naI != NULL;
835 * reduces the tail of poly q which is required to be != NULL;
836 * modifies q and returns it
837 */
838napoly napTailred (napoly q)
839{
840  napoly h;
841
842  h = pNext(q);
843  while (h != NULL)
844  {
845     h = napRedp (h);
846     if (h == NULL)
847        return q;
848     pIter(h);
849  }
850  return q;
851}
852
853napoly napMap(napoly p)
854{
855  napoly w, a;
856
857  if (p==NULL) return NULL;
858  a = w = (napoly)p_Init(nacRing);
859  int i;
860  for(i=1;i<=ntParsToCopy;i++)
861    napSetExp(a,i,napGetExpFrom(p,i,ntMapRing));
862  p_Setm(a,nacRing);
863  pGetCoeff(w) = nacMap(pGetCoeff(p));
864  loop
865  {
866    pIter(p);
867    if (p==NULL) break;
868    pNext(a) = (napoly)p_Init(nacRing);
869    pIter(a);
870    for(i=1;i<=ntParsToCopy;i++)
871      napSetExp(a,i,napGetExpFrom(p,i,ntMapRing));
872    p_Setm(a,nacRing);
873    pGetCoeff(a) = nacMap(pGetCoeff(p));
874  }
875  pNext(a) = NULL;
876  return w;
877}
878
879napoly napPerm(napoly p,const int *par_perm,const ring src_ring,const nMapFunc nMap)
880{
881  napoly w;
882
883  if (p==NULL) return NULL;
884  w = (napoly)p_Init(nacRing);
885  int i;
886  BOOLEAN not_null=TRUE;
887  loop
888  {
889    for(i=1;i<=rPar(src_ring);i++)
890    {
891      int e;
892      if (par_perm!=NULL) e=par_perm[i-1];
893      else                e=-i;
894      int ee=napGetExpFrom(p,i,src_ring);
895      if (e<0)
896        napSetExp(w,-e,ee);
897      else if (ee>0)
898        not_null=FALSE;
899    }
900    pGetCoeff(w) = nMap(pGetCoeff(p));
901    p_Setm(w,nacRing);
902    pIter(p);
903    if (!not_null)
904    {
905      if (p==NULL)
906      {
907        p_Delete(&w,nacRing);
908        return NULL;
909      }
910      /* else continue*/
911      n_Delete(&(pGetCoeff(w)),nacRing);
912    }
913    else
914    {
915      if (p==NULL) return w;
916      else
917      {
918        pNext(w)=napPerm(p,par_perm,src_ring,nMap);
919        return w;
920      }
921    }
922  }
923}
924
925/*2
926* convert a napoly number into a poly
927*/
928poly napPermNumber(number z, int * par_perm, int P, ring oldRing)
929{
930  if (z==NULL) return NULL;
931  poly res=NULL;
932  poly p;
933  napoly za=((lnumber)z)->z;
934  napoly zb=((lnumber)z)->n;
935  nMapFunc nMap=naSetMap(oldRing,currRing); /* todo: check naSetMap
936                                                     vs. ntSetMap */
937  if (currRing->parameter!=NULL)
938    nMap=currRing->algring->cf->cfSetMap(oldRing->algring, nacRing);
939  else
940    nMap=currRing->cf->cfSetMap(oldRing->algring, currRing);
941  if (nMap==NULL) return NULL; /* emergency exit only */
942  while(za!=NULL)
943  {
944    p = pInit();
945    pNext(p)=NULL;
946    //nNew(&pGetCoeff(p));
947    int i;
948    //for(i=pVariables;i;i--) pSetExp(p,i, 0); // done by pInit
949    //if (rRing_has_Comp(currRing)) pSetComp(p, 0); // done by pInit
950    napoly pa=NULL;
951    lnumber pan;
952    if (currRing->parameter!=NULL)
953    {
954      assume(oldRing->algring!=NULL);
955      pGetCoeff(p)=(number)ALLOC0_LNUMBER();
956      pan=(lnumber)pGetCoeff(p);
957      pan->s=2;
958      pan->z=napInitz(nMap(pGetCoeff(za)));
959      pa=pan->z;
960    }
961    else
962    {
963      pGetCoeff(p)=nMap(pGetCoeff(za));
964    }
965    for(i=0;i<P;i++)
966    {
967      if(napGetExpFrom(za,i+1,oldRing)!=0)
968      {
969        if(par_perm==NULL)
970        {
971          if ((rPar(currRing)>=i) && (pa!=NULL))
972          {
973            napSetExp(pa,i+1,napGetExpFrom(za,i+1,oldRing));
974            p_Setm(pa,nacRing);
975          }
976          else
977          {
978            pDelete(&p);
979            break;
980          }
981        }
982        else if(par_perm[i]>0)
983          pSetExp(p,par_perm[i],napGetExpFrom(za,i+1,oldRing));
984        else if((par_perm[i]<0)&&(pa!=NULL))
985        {
986          napSetExp(pa,-par_perm[i], napGetExpFrom(za,i+1,oldRing));
987          p_Setm(pa,nacRing);
988        }
989        else
990        {
991          pDelete(&p);
992          break;
993        }
994      }
995    }
996    if (p!=NULL)
997    {
998      pSetm(p);
999      if (zb!=NULL)
1000      {
1001        if  (currRing->P>0)
1002        {
1003          pan->n=napPerm(zb,par_perm,oldRing,nMap);
1004          if(pan->n==NULL) /* error in mapping or mapping to variable */
1005            pDelete(&p);
1006        }
1007        else
1008          pDelete(&p);
1009      }
1010      nNormalize(pGetCoeff(p));
1011      if (nIsZero(pGetCoeff(p)))
1012        pDelete(&p);
1013      else
1014      {
1015        pTest(p);
1016        res=pAdd(res,p);
1017      }
1018    }
1019    pIter(za);
1020  }
1021  pTest(res);
1022  return res;
1023}
1024
1025number   napGetDenom(number &n, const ring r)
1026{
1027  lnumber x=(lnumber)n;
1028  if (x->n!=NULL)
1029  {
1030    lnumber rr=ALLOC0_LNUMBER();
1031    rr->z=p_Copy(x->n,r->algring);
1032    rr->s = 2;
1033    return (number)rr;
1034  }
1035  return n_Init(1,r);
1036}
1037
1038number   napGetNumerator(number &n, const ring r)
1039{
1040  lnumber x=(lnumber)n;
1041  lnumber rr=ALLOC0_LNUMBER();
1042  rr->z=p_Copy(x->z,r->algring);
1043  rr->s = 2;
1044  return (number)rr;
1045}
1046
1047/*================ procedure for rational functions: ntXXXX =================*/
1048
1049/*2
1050*  z:= i
1051*/
1052number ntInit(int i, const ring r)
1053{
1054  if (i!=0)
1055  {
1056    number c=n_Init(i,r->algring);
1057    if (!n_IsZero(c,r->algring))
1058    {
1059      poly z=p_Init(r->algring);
1060      pSetCoeff0(z,c);
1061      lnumber l = (lnumber)ALLOC_LNUMBER();
1062      l->z = z;
1063      l->s = 2;
1064      l->n = NULL;
1065      return (number)l;
1066    }
1067  }
1068  /*else*/
1069  return NULL;
1070}
1071
1072/*3
1073*  division with remainder: f = g*q + r,
1074*  returns r and destroys f
1075*/
1076napoly ntRemainder(napoly f, const napoly g)
1077{
1078  napoly a, h, qq;
1079
1080  qq = (napoly)p_Init(nacRing);
1081  pNext(qq) = NULL;
1082  p_Normalize(g, nacRing);
1083  p_Normalize(f, nacRing);
1084  a = f;
1085  do
1086  {
1087    napSetExp(qq,1, p_GetExp(a,1,nacRing) - p_GetExp(g,1,nacRing));
1088    napSetm(qq);
1089    pGetCoeff(qq) = nacDiv(pGetCoeff(a), pGetCoeff(g));
1090    pGetCoeff(qq) = nacNeg(pGetCoeff(qq));
1091    nacNormalize(pGetCoeff(qq));
1092    h = napCopy(g);
1093    napMultT(h, qq);
1094    p_Normalize(h,nacRing);
1095    n_Delete(&pGetCoeff(qq),nacRing);
1096    a = napAdd(a, h);
1097  }
1098  while ((a!=NULL) && (p_GetExp(a,1,nacRing) >= p_GetExp(g,1,nacRing)));
1099  omFreeBinAddr(qq);
1100  return a;
1101}
1102
1103number  ntPar(int i)
1104{
1105  lnumber l = ALLOC_LNUMBER();
1106  l->s = 2;
1107  l->z = p_ISet(1,nacRing);
1108  napSetExp(l->z,i,1);
1109  p_Setm(l->z,nacRing);
1110  l->n = NULL;
1111  return (number)l;
1112}
1113
1114int     ntParDeg(number n)     /* i := deg(n) */
1115{
1116  lnumber l = (lnumber)n;
1117  if (l==NULL) return -1;
1118  return napDeg(l->z);
1119}
1120
1121//int     ntParDeg(number n)     /* i := deg(n) */
1122//{
1123//  lnumber l = (lnumber)n;
1124//  if (l==NULL) return -1;
1125//  return napMaxDeg(l->z)+napMaxDeg(l->n);
1126//}
1127
1128int     ntSize(number n)     /* size desc. */
1129{
1130  lnumber l = (lnumber)n;
1131  if (l==NULL) return -1;
1132  int len_z;
1133  int len_n;
1134  int o=napMaxDegLen(l->z,len_z)+napMaxDegLen(l->n,len_n);
1135  return (len_z+len_n)+o;
1136}
1137
1138/*2
1139* convert a number to int (if possible)
1140*/
1141int ntInt(number &n, const ring r)
1142{
1143  lnumber l=(lnumber)n;
1144  if ((l!=NULL)&&(l->n==NULL)&&(p_IsConstant(l->z,r->algring)))
1145  {
1146    return nacInt(pGetCoeff(l->z),r->algring);
1147  }
1148  return 0;
1149}
1150
1151/*2
1152*  deletes p
1153*/
1154void ntDelete(number *p, const ring r)
1155{
1156  if ((*p)!=NULL)
1157  {
1158    lnumber l = (lnumber) * p;
1159    if (l==NULL) return;
1160    p_Delete(&(l->z),r->algring);
1161    p_Delete(&(l->n),r->algring);
1162    FREE_LNUMBER(l);
1163  }
1164  *p = NULL;
1165}
1166
1167/*2
1168* copy p to erg
1169*/
1170number ntCopy(number p)
1171{
1172  if (p==NULL) return NULL;
1173  ntTest(p);
1174  lnumber erg;
1175  lnumber src = (lnumber)p;
1176  erg = ALLOC_LNUMBER();
1177  erg->z = p_Copy(src->z, nacRing);
1178  erg->n = p_Copy(src->n, nacRing);
1179  erg->s = src->s;
1180  return (number)erg;
1181}
1182number nt_Copy(number p, const ring r)
1183{
1184  if (p==NULL) return NULL;
1185  lnumber erg;
1186  lnumber src = (lnumber)p;
1187  erg = ALLOC_LNUMBER();
1188  erg->z = p_Copy(src->z,r->algring);
1189  erg->n = p_Copy(src->n,r->algring);
1190  erg->s = src->s;
1191  return (number)erg;
1192}
1193
1194/*2
1195*  addition; lu:= la + lb
1196*/
1197number ntAdd(number la, number lb)
1198{
1199  if (la==NULL) return ntCopy(lb);
1200  if (lb==NULL) return ntCopy(la);
1201
1202  napoly x, y;
1203  lnumber lu;
1204  lnumber a = (lnumber)la;
1205  lnumber b = (lnumber)lb;
1206  #ifdef LDEBUG
1207  omCheckAddrSize(a,sizeof(slnumber));
1208  omCheckAddrSize(b,sizeof(slnumber));
1209  #endif
1210  if (b->n!=NULL) x = pp_Mult_qq(a->z, b->n,nacRing);
1211  else            x = napCopy(a->z);
1212  if (a->n!=NULL) y = pp_Mult_qq(b->z, a->n,nacRing);
1213  else            y = napCopy(b->z);
1214  napoly res = napAdd(x, y);
1215  if (res==NULL)
1216  {
1217    return (number)NULL;
1218  }
1219  lu = ALLOC_LNUMBER();
1220  lu->z=res;
1221  if (a->n!=NULL)
1222  {
1223    if (b->n!=NULL) x = pp_Mult_qq(a->n, b->n,nacRing);
1224    else            x = napCopy(a->n);
1225  }
1226  else
1227  {
1228    if (b->n!=NULL) x = napCopy(b->n);
1229    else            x = NULL;
1230  }
1231  //if (x!=NULL)
1232  //{
1233  //  if (p_LmIsConstant(x,nacRing))
1234  //  {
1235  //    number inv=nacInvers(pGetCoeff(x));
1236  //    napMultN(lu->z,inv);
1237  //    n_Delete(&inv,nacRing);
1238  //    napDelete(&x);
1239  //  }
1240  //}
1241  lu->n = x;
1242  lu->s = FALSE;
1243  if (/*lu->n*/ x!=NULL)
1244  {
1245     number luu=(number)lu;
1246     //if (p_IsConstant(lu->n,nacRing)) ntCoefNormalize(luu);
1247     //else
1248                ntNormalize(luu);
1249     lu=(lnumber)luu;
1250  }
1251  //else lu->s=2;
1252  ntTest((number)lu);
1253  return (number)lu;
1254}
1255
1256/*2
1257*  subtraction; r:= la - lb
1258*/
1259number ntSub(number la, number lb)
1260{
1261  lnumber lu;
1262
1263  if (lb==NULL) return ntCopy(la);
1264  if (la==NULL)
1265  {
1266    lu = (lnumber)ntCopy(lb);
1267    lu->z = napNeg(lu->z);
1268    return (number)lu;
1269  }
1270
1271  lnumber a = (lnumber)la;
1272  lnumber b = (lnumber)lb;
1273
1274  #ifdef LDEBUG
1275  omCheckAddrSize(a,sizeof(slnumber));
1276  omCheckAddrSize(b,sizeof(slnumber));
1277  #endif
1278
1279  napoly x, y;
1280  if (b->n!=NULL) x = pp_Mult_qq(a->z, b->n,nacRing);
1281  else            x = napCopy(a->z);
1282  if (a->n!=NULL) y = p_Mult_q(napCopy(b->z), napCopyNeg(a->n),nacRing);
1283  else            y = napCopyNeg(b->z);
1284  napoly res = napAdd(x, y);
1285  if (res==NULL)
1286  {
1287    return (number)NULL;
1288  }
1289  lu = ALLOC_LNUMBER();
1290  lu->z=res;
1291  if (a->n!=NULL)
1292  {
1293    if (b->n!=NULL) x = pp_Mult_qq(a->n, b->n,nacRing);
1294    else            x = napCopy(a->n);
1295  }
1296  else
1297  {
1298    if (b->n!=NULL) x = napCopy(b->n);
1299    else            x = NULL;
1300  }
1301  lu->n = x;
1302  lu->s = FALSE;
1303  if (/*lu->n*/ x!=NULL)
1304  {
1305     number luu=(number)lu;
1306     //if (p_IsConstant(lu->n,nacRing)) ntCoefNormalize(luu);
1307     //else
1308                         ntNormalize(luu);
1309     lu=(lnumber)luu;
1310  }
1311  //else lu->s=2;
1312  ntTest((number)lu);
1313  return (number)lu;
1314}
1315
1316/*2
1317*  multiplication; r:= la * lb
1318*/
1319number ntMult(number la, number lb)
1320{
1321  if ((la==NULL) || (lb==NULL))
1322    return NULL;
1323
1324  lnumber a = (lnumber)la;
1325  lnumber b = (lnumber)lb;
1326  lnumber lo;
1327  napoly x;
1328
1329  #ifdef LDEBUG
1330  omCheckAddrSize(a,sizeof(slnumber));
1331  omCheckAddrSize(b,sizeof(slnumber));
1332  #endif
1333  ntTest(la);
1334  ntTest(lb);
1335
1336  lo = ALLOC_LNUMBER();
1337  lo->z = pp_Mult_qq(a->z, b->z,nacRing);
1338
1339  if (a->n==NULL)
1340  {
1341    if (b->n==NULL)
1342      x = NULL;
1343    else
1344      x = napCopy(b->n);
1345  }
1346  else
1347  {
1348    if (b->n==NULL)
1349    {
1350      x = napCopy(a->n);
1351    }
1352    else
1353    {
1354      x = pp_Mult_qq(b->n, a->n, nacRing);
1355    }
1356  }
1357  if ((x!=NULL) && (p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
1358    p_Delete(&x,nacRing);
1359  lo->n = x;
1360  lo->s = 0;
1361  number luu=(number)lo;
1362  if(lo->z==NULL)
1363  {
1364    FREE_LNUMBER(lo);
1365    lo=NULL;
1366  }
1367  else if (lo->n!=NULL)
1368  {
1369    // if (p_IsConstant(lo->n,nacRing)) ntCoefNormalize(luu);
1370    // else
1371                      ntNormalize(luu);
1372    lo=(lnumber)luu;
1373  }
1374  luu=(number)lo;
1375  if ((lo!=NULL) 
1376  && (naMinimalPoly!=NULL)
1377  &&(p_GetExp(lo->z,1,nacRing)>=p_GetExp(naMinimalPoly,1,nacRing)))
1378    lo->z=napRemainder(lo->z,naMinimalPoly);
1379  //if (naMinimalPoly==NULL) lo->s=2;
1380  ntTest((number)lo);
1381  return (number)lo;
1382}
1383
1384number ntIntDiv(number la, number lb)
1385{
1386  ntTest(la);
1387  ntTest(lb);
1388  lnumber res;
1389  lnumber a = (lnumber)la;
1390  lnumber b = (lnumber)lb;
1391  if (a==NULL)
1392  {
1393    return NULL;
1394  }
1395  if (b==NULL)
1396  {
1397    WerrorS(nDivBy0);
1398    return NULL;
1399  }
1400#ifdef LDEBUG
1401  omCheckAddrSize(a,sizeof(slnumber));
1402  omCheckAddrSize(b,sizeof(slnumber));
1403#endif
1404  assume(a->z!=NULL && b->z!=NULL);
1405  assume(a->n==NULL && b->n==NULL);
1406  res = ALLOC_LNUMBER();
1407  res->z = napCopy(a->z);
1408  res->n = napCopy(b->z);
1409  res->s = 0;
1410  number nres=(number)res;
1411  ntNormalize(nres);
1412
1413  //napDelete(&res->n);
1414  ntTest(nres);
1415  return nres;
1416}
1417
1418/*2
1419*  division; lo:= la / lb
1420*/
1421number ntDiv(number la, number lb)
1422{
1423  lnumber lo;
1424  lnumber a = (lnumber)la;
1425  lnumber b = (lnumber)lb;
1426  napoly x;
1427
1428  if (a==NULL)
1429    return NULL;
1430
1431  if (b==NULL)
1432  {
1433    WerrorS(nDivBy0);
1434    return NULL;
1435  }
1436  #ifdef LDEBUG
1437  omCheckAddrSize(a,sizeof(slnumber));
1438  omCheckAddrSize(b,sizeof(slnumber));
1439  #endif
1440  lo = ALLOC_LNUMBER();
1441  if (b->n!=NULL)
1442    lo->z = pp_Mult_qq(a->z, b->n,nacRing);
1443  else
1444    lo->z = napCopy(a->z);
1445  if (a->n!=NULL)
1446    x = pp_Mult_qq(b->z, a->n, nacRing);
1447  else
1448    x = napCopy(b->z);
1449  if ((p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
1450    p_Delete(&x,nacRing);
1451  lo->n = x;
1452  lo->s = 0;
1453  if (lo->n!=NULL)
1454  {
1455    number luu=(number)lo;
1456     //if (p_IsConstant(lo->n,nacRing)) ntCoefNormalize(luu);
1457     //else
1458                         ntNormalize(luu);
1459    lo=(lnumber)luu;
1460  }
1461  //else lo->s=2;
1462  ntTest((number)lo);
1463  return (number)lo;
1464}
1465
1466/*2
1467*  za:= - za, inplace
1468*/
1469number ntNeg(number za)
1470{
1471  if (za!=NULL)
1472  {
1473    lnumber e = (lnumber)za;
1474    ntTest(za);
1475    e->z = napNeg(e->z);
1476  }
1477  return za;
1478}
1479
1480/*2
1481* 1/a
1482*/
1483number ntInvers(number a)
1484{
1485  lnumber lo;
1486  lnumber b = (lnumber)a;
1487  napoly x;
1488
1489  if (b==NULL)
1490  {
1491    WerrorS(nDivBy0);
1492    return NULL;
1493  }
1494  #ifdef LDEBUG
1495  omCheckAddrSize(b,sizeof(slnumber));
1496  #endif
1497  lo = ALLOC0_LNUMBER();
1498  lo->s = b->s;
1499  if (b->n!=NULL)
1500    lo->z = napCopy(b->n);
1501  else
1502    lo->z = p_ISet(1,nacRing);
1503  x = b->z;
1504  if ((!p_LmIsConstant(x,nacRing)) || !nacIsOne(pGetCoeff(x)))
1505    x = napCopy(x);
1506  else
1507  {
1508    lo->n = NULL;
1509    ntTest((number)lo);
1510    return (number)lo;
1511  }
1512  lo->n = x;
1513  if (lo->n!=NULL)
1514  {
1515     number luu=(number)lo;
1516     //if (p_IsConstant(lo->n,nacRing)) ntCoefNormalize(luu);
1517     //else
1518                           ntNormalize(luu);
1519     lo=(lnumber)luu;
1520  }
1521  ntTest((number)lo);
1522  return (number)lo;
1523}
1524
1525
1526BOOLEAN ntIsZero(number za)
1527{
1528  lnumber zb = (lnumber)za;
1529  ntTest(za);
1530#ifdef LDEBUG
1531  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(2)");
1532#endif
1533  return (zb==NULL);
1534}
1535
1536
1537BOOLEAN ntGreaterZero(number za)
1538{
1539  lnumber zb = (lnumber)za;
1540#ifdef LDEBUG
1541  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(3)");
1542#endif
1543  ntTest(za);
1544  if (zb!=NULL)
1545  {
1546    return (nacGreaterZero(pGetCoeff(zb->z))||(!p_LmIsConstant(zb->z,nacRing)));
1547  }
1548  /* else */ return FALSE;
1549}
1550
1551
1552/*2
1553* a = b ?
1554*/
1555BOOLEAN ntEqual (number a, number b)
1556{
1557  if(a==b) return TRUE;
1558  if((a==NULL)&&(b!=NULL)) return FALSE;
1559  if((b==NULL)&&(a!=NULL)) return FALSE;
1560
1561  lnumber aa=(lnumber)a;
1562  lnumber bb=(lnumber)b;
1563
1564  int an_deg=0;
1565  if(aa->n!=NULL)
1566    an_deg=napDeg(aa->n);
1567  int bn_deg=0;
1568  if(bb->n!=NULL)
1569    bn_deg=napDeg(bb->n);
1570  if(an_deg+napDeg(bb->z)!=bn_deg+napDeg(aa->z))
1571    return FALSE;
1572#if 0
1573  ntNormalize(a);
1574  aa=(lnumber)a;
1575  ntNormalize(b);
1576  bb=(lnumber)b;
1577  if((aa->n==NULL)&&(bb->n!=NULL)) return FALSE;
1578  if((bb->n==NULL)&&(aa->n!=NULL)) return FALSE;
1579  if(napComp(aa->z,bb->z)!=0) return FALSE;
1580  if((aa->n!=NULL) && (napComp(aa->n,bb->n))) return FALSE;
1581#endif
1582  number h = ntSub(a, b);
1583  BOOLEAN bo = ntIsZero(h);
1584  ntDelete(&h,currRing);
1585  return bo;
1586}
1587
1588/* This method will only consider the numerators of a and b.
1589   Moreover it may return TRUE only if one or both numerators
1590   are zero or if their degrees are equal. Then TRUE is returned iff
1591   coeff(numerator(a)) > coeff(numerator(b));
1592   In all other cases, FALSE will be returned. */
1593BOOLEAN ntGreater (number a, number b)
1594{
1595  int az = 0; int ad = 0;
1596  if (ntIsZero(a)) az = 1;
1597  else ad = napDeg(((lnumber)a)->z);
1598  int bz = 0; int bd = 0;
1599  if (ntIsZero(b)) bz = 1;
1600  else bd = napDeg(((lnumber)b)->z);
1601 
1602  if ((az == 1) && (bz == 1)) /* a = b = 0 */ return FALSE;
1603  if (az == 1) /* a = 0, b != 0 */
1604  {
1605    return (!nacGreaterZero(pGetCoeff(((lnumber)b)->z)));
1606  }
1607  if (bz == 1) /* a != 0, b = 0 */
1608  {
1609    return (nacGreaterZero(pGetCoeff(((lnumber)a)->z)));
1610  }
1611  if (ad == bd) 
1612    return nacGreater(pGetCoeff(((lnumber)a)->z),
1613                      pGetCoeff(((lnumber)b)->z));
1614  return FALSE;
1615}
1616
1617/*2
1618* reads a number
1619*/
1620const char  *ntRead(const char *s, number *p)
1621{
1622  napoly x;
1623  lnumber a;
1624  s = napRead(s, &x);
1625  if (x==NULL)
1626  {
1627    *p = NULL;
1628    return s;
1629  }
1630  *p = (number)ALLOC0_LNUMBER();
1631  a = (lnumber)*p;
1632  a->z = x;
1633  if(a->z==NULL)
1634  {
1635    FREE_LNUMBER(a);
1636    *p=NULL;
1637  }
1638  else
1639  {
1640    a->n = NULL;
1641    a->s = 0;
1642    ntTest(*p);
1643  }
1644  return s;
1645}
1646
1647/*2
1648* tries to convert a number to a name
1649*/
1650char * ntName(number n)
1651{
1652  lnumber ph = (lnumber)n;
1653  if (ph==NULL)
1654    return NULL;
1655  int i;
1656  char *s=(char *)omAlloc(4* ntNumbOfPar);
1657  char *t=(char *)omAlloc(8);
1658  s[0]='\0';
1659  for (i = 0; i <= ntNumbOfPar - 1; i++)
1660  {
1661    int e=p_GetExp(ph->z,i+1,nacRing);
1662    if (e > 0)
1663    {
1664      if (e >1)
1665      {
1666        sprintf(t,"%s%d",ntParNames[i],e);
1667        strcat(s,t);
1668      }
1669      else
1670      {
1671        strcat(s,ntParNames[i]);
1672      }
1673    }
1674  }
1675  omFreeSize((ADDRESS)t,8);
1676  if (s[0]=='\0')
1677  {
1678    omFree((ADDRESS)s);
1679    return NULL;
1680  }
1681  return s;
1682}
1683
1684/*2
1685*  writes a number
1686*/
1687void ntWrite(number &phn, const ring r)
1688{
1689  lnumber ph = (lnumber)phn;
1690  if (ph==NULL)
1691    StringAppendS("0");
1692  else
1693  {
1694    phn->s = 0;
1695    BOOLEAN has_denom=(ph->n!=NULL);
1696    napWrite(ph->z,has_denom/*(ph->n!=NULL)*/,r);
1697    if (has_denom/*(ph->n!=NULL)*/)
1698    {
1699      StringAppendS("/");
1700      napWrite(ph->n,TRUE,r);
1701    }
1702  }
1703}
1704
1705/*2
1706* za == 1 ?
1707*/
1708BOOLEAN ntIsOne(number za)
1709{
1710  lnumber a = (lnumber)za;
1711  if (a==NULL) return FALSE;
1712#ifdef LDEBUG
1713  omCheckAddrSize(a,sizeof(slnumber));
1714  if (a->z==NULL)
1715  {
1716    WerrorS("internal zero error(4)");
1717    return FALSE;
1718  }
1719#endif
1720  if (a->n==NULL)
1721  {
1722    if (p_LmIsConstant(a->z,nacRing))
1723    {
1724      return nacIsOne(pGetCoeff(a->z));
1725    }
1726    else                 return FALSE;
1727  }
1728#if 0
1729  number t;
1730  x = a->z;
1731  y = a->n;
1732  do
1733  {
1734    if (napComp(x, y))
1735      return FALSE;
1736    else
1737    {
1738      t = nacSub(pGetCoeff(x), pGetCoeff(y));
1739      if (!nacIsZero(t))
1740      {
1741        n_Delete(&t,nacRing);
1742        return FALSE;
1743      }
1744      else
1745        n_Delete(&t,nacRing);
1746    }
1747    pIter(x);
1748    pIter(y);
1749  }
1750  while ((x!=NULL) && (y!=NULL));
1751  if ((x!=NULL) || (y!=NULL)) return FALSE;
1752  p_Delete(&a->z,nacRing);
1753  p_Delete(&a->n,nacRing);
1754  a->z = p_ISet(1,nacRing);
1755  a->n = NULL;
1756  return TRUE;
1757#else
1758  return FALSE;
1759#endif
1760}
1761
1762/*2
1763* za == -1 ?
1764*/
1765BOOLEAN ntIsMOne(number za)
1766{
1767  lnumber a = (lnumber)za;
1768  if (a==NULL) return FALSE;
1769#ifdef LDEBUG
1770  omCheckAddrSize(a,sizeof(slnumber));
1771  if (a->z==NULL)
1772  {
1773    WerrorS("internal zero error(5)");
1774    return FALSE;
1775  }
1776#endif
1777  if (a->n==NULL)
1778  {
1779    if (p_LmIsConstant(a->z,nacRing)) return n_IsMOne(pGetCoeff(a->z),nacRing);
1780    /*else                   return FALSE;*/
1781  }
1782  return FALSE;
1783}
1784
1785/*2
1786* returns the i-th power of p (i>=0)
1787*/
1788void ntPower(number p, int i, number *rc)
1789{
1790  number x;
1791  *rc = ntInit(1,currRing);
1792  for (; i > 0; i--)
1793  {
1794    x = ntMult(*rc, p);
1795    ntDelete(rc,currRing);
1796    *rc = x;
1797  }
1798}
1799
1800/*2
1801* result =gcd(a,b)
1802*/
1803number ntGcd(number a, number b, const ring r)
1804{
1805  if (a==NULL)  return ntCopy(b);
1806  if (b==NULL)  return ntCopy(a);
1807
1808  lnumber x, y;
1809  lnumber result = ALLOC0_LNUMBER();
1810
1811  x = (lnumber)a;
1812  y = (lnumber)b;
1813#ifndef HAVE_FACTORY
1814  result->z = napGcd(x->z, y->z); // change from napGcd0
1815#else
1816  int c=ABS(nGetChar());
1817  if (c==1) c=0;
1818  setCharacteristic( c );
1819
1820  napoly rz=napGcd(x->z, y->z);
1821  CanonicalForm F, G, R;
1822  R=convSingPFactoryP(rz,r->algring);
1823  p_Normalize(x->z,nacRing);
1824  F=convSingPFactoryP(x->z,r->algring)/R;
1825  p_Normalize(y->z,nacRing);
1826  G=convSingPFactoryP(y->z,r->algring)/R;
1827  F = gcd( F, G );
1828  if (F.isOne())
1829    result->z= rz;
1830  else
1831  {
1832    p_Delete(&rz,r->algring);
1833    result->z=convFactoryPSingP( F*R,r->algring );
1834    p_Normalize(result->z,nacRing);
1835  }
1836#endif
1837  ntTest((number)result);
1838  return (number)result;
1839}
1840
1841
1842/*2
1843* ntNumbOfPar = 1:
1844* clears denominator         algebraic case;
1845* tries to simplify ratio    transcendental case;
1846*
1847* cancels monomials
1848* occuring in denominator
1849* and enumerator  ?          ntNumbOfPar != 1;
1850*
1851* #defines for Factory:
1852* FACTORY_GCD_TEST: do not apply built in gcd for
1853*   univariate polynomials, always use Factory
1854*/
1855//#define FACTORY_GCD_TEST
1856void ntCoefNormalize(number pp)
1857{
1858  if (pp==NULL) return;
1859  lnumber p = (lnumber)pp;
1860  number nz; // all denom. of the numerator
1861  nz=p_GetAllDenom(p->z,nacRing);
1862  BOOLEAN norm=FALSE;
1863  if (!n_IsOne(nz,nacRing))
1864  {
1865    norm=TRUE;
1866    p->z=p_Mult_nn(p->z,nz,nacRing);
1867    if (p->n==NULL)
1868    {
1869      p->n=p_NSet(nz,nacRing);
1870    }
1871    else
1872    {
1873      p->n=p_Mult_nn(p->n,nz,nacRing);
1874      n_Delete(&nz, nacRing);
1875    }
1876  }
1877  else
1878  {
1879    n_Delete(&nz, nacRing);
1880  }
1881  if (norm)
1882  {
1883    norm=FALSE;
1884    p_Normalize(p->z,nacRing);
1885    p_Normalize(p->n,nacRing);
1886  }
1887  number nn;
1888  nn=p_GetAllDenom(p->n,nacRing);
1889  if (!n_IsOne(nn,nacRing))
1890  {
1891    norm=TRUE;
1892    p->n=p_Mult_nn(p->n,nn,nacRing);
1893    p->z=p_Mult_nn(p->z,nn,nacRing);
1894    n_Delete(&nn, nacRing);
1895  }
1896  else
1897  {
1898    n_Delete(&nn, nacRing);
1899  }
1900  if (norm)
1901  {
1902    p_Normalize(p->z,nacRing);
1903    p_Normalize(p->n,nacRing);
1904  }
1905  // remove common factors in n, z:
1906  if (p->n!=NULL)
1907  {
1908    poly pp=p->z;
1909    nz=n_Copy(pGetCoeff(pp),nacRing);
1910    pIter(pp);
1911    while(pp!=NULL)
1912    {
1913      if (n_IsOne(nz,nacRing)) break;
1914      number d=n_Gcd(nz,pGetCoeff(pp),nacRing);
1915      n_Delete(&nz,nacRing); nz=d;
1916      pIter(pp);
1917    }
1918    if (!n_IsOne(nz,nacRing))
1919    {
1920      pp=p->n;
1921      nn=n_Copy(pGetCoeff(pp),nacRing);
1922      pIter(pp);
1923      while(pp!=NULL)
1924      {
1925        if (n_IsOne(nn,nacRing)) break;
1926        number d=n_Gcd(nn,pGetCoeff(pp),nacRing);
1927        n_Delete(&nn,nacRing); nn=d;
1928        pIter(pp);
1929      }
1930      number ng=n_Gcd(nz,nn,nacRing);
1931      n_Delete(&nn,nacRing);
1932      if (!n_IsOne(ng,nacRing))
1933      {
1934        number ni=n_Invers(ng,nacRing);
1935        p->z=p_Mult_nn(p->z,ni,nacRing);
1936        p->n=p_Mult_nn(p->n,ni,nacRing);
1937        p_Normalize(p->z,nacRing);
1938        p_Normalize(p->n,nacRing);
1939        n_Delete(&ni,nacRing);
1940      }
1941      n_Delete(&ng,nacRing);
1942    }
1943    n_Delete(&nz,nacRing);
1944  }
1945  if (p->n!=NULL)
1946  {
1947    if(!nacGreaterZero(pGetCoeff(p->n)))
1948    {
1949      p->z=napNeg(p->z);
1950      p->n=napNeg(p->n);
1951    }
1952
1953    if (/*(p->n!=NULL) && */
1954    (p_IsConstant(p->n,nacRing))
1955    && (n_IsOne(pGetCoeff(p->n),nacRing)))
1956    {
1957      p_Delete(&(p->n), nacRing);
1958      p->n = NULL;
1959    }
1960  }
1961}
1962
1963void ntNormalize(number &pp)
1964{
1965
1966  //ntTest(pp); // input may not be "normal"
1967  lnumber p = (lnumber)pp;
1968
1969  if (p==NULL)
1970    return;
1971  ntCoefNormalize(pp);
1972  p->s = 2;
1973  napoly x = p->z;
1974  napoly y = p->n;
1975
1976  if (y==NULL) return;
1977
1978  if ((x!=NULL) && (y!=NULL))
1979  {
1980    int i;
1981    for (i=ntNumbOfPar-1; i>=0; i--)
1982    {
1983      napoly xx=x;
1984      napoly yy=y;
1985      int m = napExpi(i, yy, xx);
1986      if (m != 0)          // in this case xx!=NULL!=yy
1987      {
1988        while (xx != NULL)
1989        {
1990          napAddExp(xx,i+1, -m);
1991          pIter(xx);
1992        }
1993        while (yy != NULL)
1994        {
1995          napAddExp(yy,i+1, -m);
1996          pIter(yy);
1997        }
1998      }
1999    }
2000  }
2001  if (p_LmIsConstant(y,nacRing)) /* i.e. => simplify to (1/c)*z / monom */
2002  {
2003    if (nacIsOne(pGetCoeff(y)))
2004    {
2005      p_LmDelete(&y,nacRing);
2006      p->n = NULL;
2007      ntTest(pp);
2008      return;
2009    }
2010    number h1 = nacInvers(pGetCoeff(y));
2011    nacNormalize(h1);
2012    napMultN(x, h1);
2013    n_Delete(&h1,nacRing);
2014    p_LmDelete(&y,nacRing);
2015    p->n = NULL;
2016    ntTest(pp);
2017    return;
2018  }
2019#ifndef FACTORY_GCD_TEST
2020  if (ntNumbOfPar == 1) /* apply built-in gcd */
2021  {
2022    napoly x1,y1;
2023    if (p_GetExp(x,1,nacRing) >= p_GetExp(y,1,nacRing))
2024    {
2025      x1 = napCopy(x);
2026      y1 = napCopy(y);
2027    }
2028    else
2029    {
2030      x1 = napCopy(y);
2031      y1 = napCopy(x);
2032    }
2033    napoly r;
2034    loop
2035    {
2036      r = ntRemainder(x1, y1);
2037      if ((r==NULL) || (pNext(r)==NULL)) break;
2038      x1 = y1;
2039      y1 = r;
2040    }
2041    if (r!=NULL)
2042    {
2043      p_Delete(&r,nacRing);
2044      p_Delete(&y1,nacRing);
2045    }
2046    else
2047    {
2048      napDivMod(x, y1, &(p->z), &r);
2049      napDivMod(y, y1, &(p->n), &r);
2050      p_Delete(&y1,nacRing);
2051    }
2052    x = p->z;
2053    y = p->n;
2054    /* collect all denoms from y and multiply x and y by it */
2055    if (ntIsChar0)
2056    {
2057      number n=napLcm(y);
2058      napMultN(x,n);
2059      napMultN(y,n);
2060      n_Delete(&n,nacRing);
2061      while(x!=NULL)
2062      {
2063        nacNormalize(pGetCoeff(x));
2064        pIter(x);
2065      }
2066      x = p->z;
2067      while(y!=NULL)
2068      {
2069        nacNormalize(pGetCoeff(y));
2070        pIter(y);
2071      }
2072      y = p->n;
2073    }
2074    if (pNext(y)==NULL)
2075    {
2076      if (nacIsOne(pGetCoeff(y)))
2077      {
2078        if (p_GetExp(y,1,nacRing)==0)
2079        {
2080          p_LmDelete(&y,nacRing);
2081          p->n = NULL;
2082        }
2083        ntTest(pp);
2084        return;
2085      }
2086    }
2087  }
2088#endif /* FACTORY_GCD_TEST */
2089#ifdef HAVE_FACTORY
2090#ifndef FACTORY_GCD_TEST
2091  else
2092#endif
2093  {
2094    napoly xx,yy;
2095    singclap_algdividecontent(x,y,xx,yy);
2096    if (xx!=NULL)
2097    {
2098      p->z=xx;
2099      p->n=yy;
2100      p_Delete(&x,nacRing);
2101      p_Delete(&y,nacRing);
2102    }
2103  }
2104#endif
2105  /* remove common factors from z and n */
2106  x=p->z;
2107  y=p->n;
2108  if(!nacGreaterZero(pGetCoeff(y)))
2109  {
2110    x=napNeg(x);
2111    y=napNeg(y);
2112  }
2113  number g=nacCopy(pGetCoeff(x));
2114  pIter(x);
2115  while (x!=NULL)
2116  {
2117    number d=nacGcd(g,pGetCoeff(x), nacRing);
2118    if(nacIsOne(d))
2119    {
2120      n_Delete(&g,nacRing);
2121      n_Delete(&d,nacRing);
2122      ntTest(pp);
2123      return;
2124    }
2125    n_Delete(&g,nacRing);
2126    g = d;
2127    pIter(x);
2128  }
2129  while (y!=NULL)
2130  {
2131    number d=nacGcd(g,pGetCoeff(y), nacRing);
2132    if(nacIsOne(d))
2133    {
2134      n_Delete(&g,nacRing);
2135      n_Delete(&d,nacRing);
2136      ntTest(pp);
2137      return;
2138    }
2139    n_Delete(&g,nacRing);
2140    g = d;
2141    pIter(y);
2142  }
2143  x=p->z;
2144  y=p->n;
2145  while (x!=NULL)
2146  {
2147    number d = nacIntDiv(pGetCoeff(x),g);
2148    napSetCoeff(x,d);
2149    pIter(x);
2150  }
2151  while (y!=NULL)
2152  {
2153    number d = nacIntDiv(pGetCoeff(y),g);
2154    napSetCoeff(y,d);
2155    pIter(y);
2156  }
2157  n_Delete(&g,nacRing);
2158  ntTest(pp);
2159}
2160
2161/*2
2162* returns in result->n 1
2163* and in     result->z the lcm(a->z,b->n)
2164*/
2165number ntLcm(number la, number lb, const ring r)
2166{
2167  lnumber result;
2168  lnumber a = (lnumber)la;
2169  lnumber b = (lnumber)lb;
2170  result = ALLOC0_LNUMBER();
2171  ntTest(la);
2172  ntTest(lb);
2173  napoly x = p_Copy(a->z, r->algring);
2174  number t = napLcm(b->z); // get all denom of b->z
2175  if (!nacIsOne(t))
2176  {
2177    number bt, rr;
2178    napoly xx=x;
2179    while (xx!=NULL)
2180    {
2181      bt = nacGcd(t, pGetCoeff(xx), r->algring);
2182      rr = nacMult(t, pGetCoeff(xx));
2183      n_Delete(&pGetCoeff(xx),r->algring);
2184      pGetCoeff(xx) = nacDiv(rr, bt);
2185      nacNormalize(pGetCoeff(xx));
2186      n_Delete(&bt,r->algring);
2187      n_Delete(&rr,r->algring);
2188      pIter(xx);
2189    }
2190  }
2191  n_Delete(&t,r->algring);
2192  result->z = x;
2193#ifdef HAVE_FACTORY
2194  if (b->n!=NULL)
2195  {
2196    result->z=singclap_alglcm(result->z,b->n);
2197    p_Delete(&x,r->algring);
2198  }
2199#endif
2200  ntTest(la);
2201  ntTest(lb);
2202  ntTest((number)result);
2203  return ((number)result);
2204}
2205
2206/*2
2207* map Z/p -> Q(a)
2208*/
2209number ntMapP0(number c)
2210{
2211  if (npIsZero(c)) return NULL;
2212  lnumber l=ALLOC_LNUMBER();
2213  l->s=2;
2214  l->z=(napoly)p_Init(nacRing);
2215  int i=(int)((long)c);
2216  if (i>((long)ntMapRing->ch>>2)) i-=(long)ntMapRing->ch;
2217  pGetCoeff(l->z)=nlInit(i, nacRing);
2218  l->n=NULL;
2219  return (number)l;
2220}
2221
2222/*2
2223* map Q -> Q(a)
2224*/
2225number ntMap00(number c)
2226{
2227  if (nlIsZero(c)) return NULL;
2228  lnumber l=ALLOC_LNUMBER();
2229  l->s=0;
2230  l->z=(napoly)p_Init(nacRing);
2231  pGetCoeff(l->z)=nlCopy(c);
2232  l->n=NULL;
2233  return (number)l;
2234}
2235
2236/*2
2237* map Z/p -> Z/p(a)
2238*/
2239number ntMapPP(number c)
2240{
2241  if (npIsZero(c)) return NULL;
2242  lnumber l=ALLOC_LNUMBER();
2243  l->s=2;
2244  l->z=(napoly)p_Init(nacRing);
2245  pGetCoeff(l->z)=c; /* omit npCopy, because npCopy is a no-op */
2246  l->n=NULL;
2247  return (number)l;
2248}
2249
2250/*2
2251* map Z/p' -> Z/p(a)
2252*/
2253number ntMapPP1(number c)
2254{
2255  if (npIsZero(c)) return NULL;
2256  int i=(int)((long)c);
2257  if (i>(long)ntMapRing->ch) i-=(long)ntMapRing->ch;
2258  number n=npInit(i,ntMapRing);
2259  if (npIsZero(n)) return NULL;
2260  lnumber l=ALLOC_LNUMBER();
2261  l->s=2;
2262  l->z=(napoly)p_Init(nacRing);
2263  pGetCoeff(l->z)=n;
2264  l->n=NULL;
2265  return (number)l;
2266}
2267
2268/*2
2269* map Q -> Z/p(a)
2270*/
2271number ntMap0P(number c)
2272{
2273  if (nlIsZero(c)) return NULL;
2274  number n=npInit(nlModP(c,npPrimeM),nacRing);
2275  if (npIsZero(n)) return NULL;
2276  npTest(n);
2277  lnumber l=ALLOC_LNUMBER();
2278  l->s=2;
2279  l->z=(napoly)p_Init(nacRing);
2280  pGetCoeff(l->z)=n;
2281  l->n=NULL;
2282  return (number)l;
2283}
2284
2285/*2
2286* map _(a) -> _(b)
2287*/
2288number ntMapQaQb(number c)
2289{
2290  if (c==NULL) return NULL;
2291  lnumber erg= ALLOC0_LNUMBER();
2292  lnumber src =(lnumber)c;
2293  erg->s=src->s;
2294  erg->z=napMap(src->z);
2295  erg->n=napMap(src->n);
2296  return (number)erg;
2297}
2298
2299nMapFunc ntSetMap(const ring src, const ring dst)
2300{
2301  ntMapRing=src;
2302  if (rField_is_Q_a(dst)) /* -> Q(a) */
2303  {
2304    if (rField_is_Q(src))
2305    {
2306      return ntMap00;   /*Q -> Q(a)*/
2307    }
2308    if (rField_is_Zp(src))
2309    {
2310      return ntMapP0;  /* Z/p -> Q(a)*/
2311    }
2312    if (rField_is_Q_a(src))
2313    {
2314      int i;
2315      ntParsToCopy=0;
2316      for(i=0;i<rPar(src);i++)
2317      {
2318        if ((i>=rPar(dst))
2319        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
2320           return NULL;
2321        ntParsToCopy++;
2322      }
2323      nacMap=nacCopy;
2324      if ((ntParsToCopy==rPar(dst))&&(ntParsToCopy==rPar(src)))
2325        return ntCopy;    /* Q(a) -> Q(a) */
2326      return ntMapQaQb;   /* Q(a..) -> Q(a..) */
2327    }
2328  }
2329  /*-----------------------------------------------------*/
2330  if (rField_is_Zp_a(dst)) /* -> Z/p(a) */
2331  {
2332    if (rField_is_Q(src))
2333    {
2334      return ntMap0P;   /*Q -> Z/p(a)*/
2335    }
2336    if (rField_is_Zp(src))
2337    {
2338      if (src->ch==dst->ch)
2339      {
2340        return ntMapPP;  /* Z/p -> Z/p(a)*/
2341      }
2342      else
2343      {
2344        return ntMapPP1;  /* Z/p' -> Z/p(a)*/
2345      }
2346    }
2347    if (rField_is_Zp_a(src))
2348    {
2349      if (rChar(src)==rChar(dst))
2350      {
2351        nacMap=nacCopy;
2352      }
2353      else
2354      {
2355        nacMap = npMapP;
2356      }
2357      int i;
2358      ntParsToCopy=0;
2359      for(i=0;i<rPar(src);i++)
2360      {
2361        if ((i>=rPar(dst))
2362        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
2363           return NULL;
2364        ntParsToCopy++;
2365      }
2366      if ((ntParsToCopy==rPar(dst))&&(ntParsToCopy==rPar(src))
2367      && (nacMap==nacCopy))
2368        return ntCopy;    /* Z/p(a) -> Z/p(a) */
2369      return ntMapQaQb;   /* Z/p(a),Z/p'(a) -> Z/p(b)*/
2370    }
2371  }
2372  return NULL;      /* default */
2373}
2374
2375/*2
2376* convert a napoly number into a poly
2377*/
2378poly ntPermNumber(number z, int * par_perm, int P, ring oldRing)
2379{
2380  if (z==NULL) return NULL;
2381  poly res=NULL;
2382  poly p;
2383  napoly za=((lnumber)z)->z;
2384  napoly zb=((lnumber)z)->n;
2385  nMapFunc nMap=ntSetMap(oldRing,currRing);
2386  if (currRing->parameter!=NULL)
2387    nMap=currRing->algring->cf->cfSetMap(oldRing->algring, nacRing);
2388  else
2389    nMap=currRing->cf->cfSetMap(oldRing->algring, currRing);
2390  if (nMap==NULL) return NULL; /* emergency exit only */
2391  do
2392  {
2393    p = pInit();
2394    pNext(p)=NULL;
2395    nNew(&pGetCoeff(p));
2396    int i;
2397    for(i=pVariables;i;i--)
2398       pSetExp(p,i, 0);
2399    if (rRing_has_Comp(currRing)) pSetComp(p, 0);
2400    napoly pa=NULL;
2401    lnumber pan;
2402    if (currRing->parameter!=NULL)
2403    {
2404      assume(oldRing->algring!=NULL);
2405      pGetCoeff(p)=(number)ALLOC0_LNUMBER();
2406      pan=(lnumber)pGetCoeff(p);
2407      pan->s=2;
2408      pan->z=napInitz(nMap(pGetCoeff(za)));
2409      pa=pan->z;
2410    }
2411    else
2412    {
2413      pGetCoeff(p)=nMap(pGetCoeff(za));
2414    }
2415    for(i=0;i<P;i++)
2416    {
2417      if(napGetExpFrom(za,i+1,oldRing)!=0)
2418      {
2419        if(par_perm==NULL)
2420        {
2421          if ((rPar(currRing)>=i) && (pa!=NULL))
2422          {
2423            napSetExp(pa,i+1,napGetExpFrom(za,i+1,oldRing));
2424            p_Setm(pa,nacRing);
2425          }
2426          else
2427          {
2428            pDelete(&p);
2429            break;
2430          }
2431        }
2432        else if(par_perm[i]>0)
2433          pSetExp(p,par_perm[i],napGetExpFrom(za,i+1,oldRing));
2434        else if((par_perm[i]<0)&&(pa!=NULL))
2435        {
2436          napSetExp(pa,-par_perm[i], napGetExpFrom(za,i+1,oldRing));
2437          p_Setm(pa,nacRing);
2438        }
2439        else
2440        {
2441          pDelete(&p);
2442          break;
2443        }
2444      }
2445    }
2446    if (p!=NULL)
2447    {
2448      pSetm(p);
2449      if (zb!=NULL)
2450      {
2451        if  (currRing->P>0)
2452        {
2453          pan->n=napPerm(zb,par_perm,oldRing,nMap);
2454          if(pan->n==NULL) /* error in mapping or mapping to variable */
2455            pDelete(&p);
2456        }
2457        else
2458          pDelete(&p);
2459      }
2460      pTest(p);
2461      res=pAdd(res,p);
2462    }
2463    pIter(za);
2464  }
2465  while (za!=NULL);
2466  pTest(res);
2467  return res;
2468}
2469
2470number   ntGetDenom(number &n, const ring r)
2471{
2472  lnumber x=(lnumber)n;
2473  if (x->n!=NULL)
2474  {
2475    lnumber rr=ALLOC0_LNUMBER();
2476    rr->z=p_Copy(x->n,r->algring);
2477    rr->s = 2;
2478    return (number)rr;
2479  }
2480  return n_Init(1,r);
2481}
2482
2483number   ntGetNumerator(number &n, const ring r)
2484{
2485  lnumber x=(lnumber)n;
2486  lnumber rr=ALLOC0_LNUMBER();
2487  rr->z=p_Copy(x->z,r->algring);
2488  rr->s = 2;
2489  return (number)rr;
2490}
2491
2492#ifdef LDEBUG
2493BOOLEAN ntDBTest(number a, const char *f,const int l)
2494{
2495  lnumber x=(lnumber)a;
2496  if (x == NULL)
2497    return TRUE;
2498  #ifdef LDEBUG
2499  omCheckAddrSize(a, sizeof(slnumber));
2500  #endif
2501  napoly p = x->z;
2502  if (p==NULL)
2503  {
2504    Print("0/* in %s:%d\n",f,l);
2505    return FALSE;
2506  }
2507  while(p!=NULL)
2508  {
2509    if (( ntIsChar0  && nlIsZero(pGetCoeff(p)))
2510    || ((!ntIsChar0) && npIsZero(pGetCoeff(p))))
2511    {
2512      Print("coeff 0 in %s:%d\n",f,l);
2513      return FALSE;
2514    }
2515    if (ntIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
2516      return FALSE;
2517    pIter(p);
2518  }
2519  p = x->n;
2520  while(p!=NULL)
2521  {
2522    if (ntIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
2523      return FALSE;
2524    pIter(p);
2525  }
2526  return TRUE;
2527}
2528#endif
2529#endif
Note: See TracBrowser for help on using the repository browser.