source: git/kernel/longalg.cc @ b3af93

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