source: git/kernel/longtrans.cc @ 528f5b7

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