source: git/kernel/longtrans.cc @ e9c3b2

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