source: git/kernel/longalg.cc @ 61d32c

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