source: git/kernel/longalg.cc @ aaeb98

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