source: git/kernel/longalg.cc @ 52cc7a4

fieker-DuValspielwiese
Last change on this file since 52cc7a4 was 3de9a9, checked in by Hans Schönemann <hannes@…>, 16 years ago
hannes: exceptional 0-cases in anGcd git-svn-id: file:///usr/local/Singular/svn/trunk@10893 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 48.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longalg.cc,v 1.37 2008-07-20 10:19:02 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    napoly rz=napGcd(x->z, y->z);
1695    CanonicalForm F, G, R;
1696    R=convSingTrFactoryP(rz); 
1697    napNormalize(x->z);
1698    F=convSingTrFactoryP(x->z)/R; 
1699    napNormalize(y->z);
1700    G=convSingTrFactoryP(y->z)/R; 
1701    F = gcd( F, G );
1702    if (F.isOne()) 
1703      result->z= rz;
1704    else
1705    {
1706      napDelete(&rz);
1707      result->z=convFactoryPSingTr( F*R );
1708      napNormalize(result->z);
1709    }
1710  }
1711#endif
1712  result->cnt=0;
1713  naTest((number)result);
1714  return (number)result;
1715}
1716
1717
1718/*2
1719* naNumbOfPar = 1:
1720* clears denominator         algebraic case;
1721* tries to simplify ratio    transcendental case;
1722*
1723* cancels monomials
1724* occuring in denominator
1725* and enumerator  ?          naNumbOfPar != 1;
1726*
1727* #defines for Factory:
1728* FACTORY_GCD_TEST: do not apply built in gcd for
1729*   univariate polynomials, always use Factory
1730*/
1731//#define FACTORY_GCD_TEST
1732void naNormalize(number &pp)
1733{
1734
1735  //naTest(pp); // input may not be "normal"
1736  lnumber p = (lnumber)pp;
1737
1738  if ((p==NULL) /*|| (p->s==2)*/)
1739    return;
1740  p->s = 2; p->cnt=0;
1741  napoly x = p->z;
1742  napoly y = p->n;
1743  if ((y!=NULL) && (naMinimalPoly!=NULL))
1744  {
1745    y = napInvers(y, naMinimalPoly);
1746    x = napMult(x, y);
1747    if (napGetExp(x,1) >= napGetExp(naMinimalPoly,1))
1748      x = napRemainder(x, naMinimalPoly);
1749    p->z = x;
1750    p->n = y = NULL;
1751  }
1752  /* check for degree of x too high: */
1753  if ((x!=NULL) && (naMinimalPoly!=NULL) && (x!=naMinimalPoly)
1754  && (napGetExp(x,1)>napGetExp(naMinimalPoly,1)))
1755  // DO NOT REDUCE naMinimalPoly with itself
1756  {
1757    x = napRemainder(x, naMinimalPoly);
1758    p->z = x;
1759  }
1760  /* normalize all coefficients in n and z (if in Q) */
1761  if (naIsChar0)
1762  {
1763    while(x!=NULL)
1764    {
1765      nacNormalize(napGetCoeff(x));
1766      napIter(x);
1767    }
1768    x = p->z;
1769  }
1770  if (y==NULL) return;
1771  if (naIsChar0)
1772  {
1773    while(y!=NULL)
1774    {
1775      nacNormalize(napGetCoeff(y));
1776      napIter(y);
1777    }
1778    y = p->n;
1779  // p->n !=NULL:
1780  /* collect all denoms from y and multiply x and y by it */
1781    number n=napLcm(y);
1782    napMultN(x,n);
1783    napMultN(y,n);
1784    nacDelete(&n,nacRing);
1785    while(x!=NULL)
1786    {
1787      nacNormalize(napGetCoeff(x));
1788      napIter(x);
1789    }
1790    x = p->z;
1791    while(y!=NULL)
1792    {
1793      nacNormalize(napGetCoeff(y));
1794      napIter(y);
1795    }
1796    y = p->n;
1797  }
1798  if ((naMinimalPoly == NULL) && (x!=NULL) && (y!=NULL))
1799  {
1800    int i;
1801    for (i=naNumbOfPar-1; i>=0; i--)
1802    {
1803      napoly xx=x;
1804      napoly yy=y;
1805      int m = napExpi(i, yy, xx);
1806      if (m != 0)          // in this case xx!=NULL!=yy
1807      {
1808        while (xx != NULL)
1809        {
1810          napAddExp(xx,i+1, -m);
1811          napIter(xx);
1812        }
1813        while (yy != NULL)
1814        {
1815          napAddExp(yy,i+1, -m);
1816          napIter(yy);
1817        }
1818      }
1819    }
1820  }
1821  if (napIsConstant(y)) /* i.e. => simplify to (1/c)*z / monom */
1822  {
1823    if (nacIsOne(napGetCoeff(y)))
1824    {
1825      napDelete1(&y);
1826      p->n = NULL;
1827      naTest(pp);
1828      return;
1829    }
1830    number h1 = nacInvers(napGetCoeff(y));
1831    nacNormalize(h1);
1832    napMultN(x, h1);
1833    nacDelete(&h1,nacRing);
1834    napDelete1(&y);
1835    p->n = NULL;
1836    naTest(pp);
1837    return;
1838  }
1839#ifndef FACTORY_GCD_TEST
1840  if (naNumbOfPar == 1) /* apply built-in gcd */
1841  {
1842    napoly x1,y1;
1843    if (napGetExp(x,1) >= napGetExp(y,1))
1844    {
1845      x1 = napCopy(x);
1846      y1 = napCopy(y);
1847    }
1848    else
1849    {
1850      x1 = napCopy(y);
1851      y1 = napCopy(x);
1852    }
1853    napoly r;
1854    loop
1855    {
1856      r = napRemainder(x1, y1);
1857      if ((r==NULL) || (napNext(r)==NULL)) break;
1858      x1 = y1;
1859      y1 = r;
1860    }
1861    if (r!=NULL)
1862    {
1863      napDelete(&r);
1864      napDelete(&y1);
1865    }
1866    else
1867    {
1868      napDivMod(x, y1, &(p->z), &r);
1869      napDivMod(y, y1, &(p->n), &r);
1870      napDelete(&y1);
1871    }
1872    x = p->z;
1873    y = p->n;
1874    /* collect all denoms from y and multiply x and y by it */
1875    if (naIsChar0)
1876    {
1877      number n=napLcm(y);
1878      napMultN(x,n);
1879      napMultN(y,n);
1880      nacDelete(&n,nacRing);
1881      while(x!=NULL)
1882      {
1883        nacNormalize(napGetCoeff(x));
1884        napIter(x);
1885      }
1886      x = p->z;
1887      while(y!=NULL)
1888      {
1889        nacNormalize(napGetCoeff(y));
1890        napIter(y);
1891      }
1892      y = p->n;
1893    }
1894    if (napNext(y)==NULL)
1895    {
1896      if (nacIsOne(napGetCoeff(y)))
1897      {
1898        if (napGetExp(y,1)==0)
1899        {
1900          napDelete1(&y);
1901          p->n = NULL;
1902        }
1903        naTest(pp);
1904        return;
1905      }
1906    }
1907  }
1908#endif /* FACTORY_GCD_TEST */
1909#ifdef HAVE_FACTORY
1910#ifndef FACTORY_GCD_TEST
1911  else
1912#endif
1913  {
1914    napoly xx,yy;
1915    singclap_algdividecontent(x,y,xx,yy);
1916    if (xx!=NULL)
1917    {
1918      p->z=xx;
1919      p->n=yy;
1920      napDelete(&x);
1921      napDelete(&y);
1922    }
1923  }
1924#endif
1925  /* remove common factors from z and n */
1926  x=p->z;
1927  y=p->n;
1928  if(!nacGreaterZero(napGetCoeff(y)))
1929  {
1930    x=napNeg(x);
1931    y=napNeg(y);
1932  }
1933  number g=nacCopy(napGetCoeff(x));
1934  napIter(x);
1935  while (x!=NULL)
1936  {
1937    number d=nacGcd(g,napGetCoeff(x), nacRing);
1938    if(nacIsOne(d))
1939    {
1940      nacDelete(&g,nacRing);
1941      nacDelete(&d,nacRing);
1942      naTest(pp);
1943      return;
1944    }
1945    nacDelete(&g,nacRing);
1946    g = d;
1947    napIter(x);
1948  }
1949  while (y!=NULL)
1950  {
1951    number d=nacGcd(g,napGetCoeff(y), nacRing);
1952    if(nacIsOne(d))
1953    {
1954      nacDelete(&g,nacRing);
1955      nacDelete(&d,nacRing);
1956      naTest(pp);
1957      return;
1958    }
1959    nacDelete(&g,nacRing);
1960    g = d;
1961    napIter(y);
1962  }
1963  x=p->z;
1964  y=p->n;
1965  while (x!=NULL)
1966  {
1967    number d = nacIntDiv(napGetCoeff(x),g);
1968    napSetCoeff(x,d);
1969    napIter(x);
1970  }
1971  while (y!=NULL)
1972  {
1973    number d = nacIntDiv(napGetCoeff(y),g);
1974    napSetCoeff(y,d);
1975    napIter(y);
1976  }
1977  nacDelete(&g,nacRing);
1978  naTest(pp);
1979}
1980
1981/*2
1982* returns in result->n 1
1983* and in     result->z the lcm(a->z,b->n)
1984*/
1985number naLcm(number la, number lb, const ring r)
1986{
1987  lnumber result;
1988  lnumber a = (lnumber)la;
1989  lnumber b = (lnumber)lb;
1990  result = (lnumber)omAlloc0Bin(rnumber_bin);
1991  //if (((naMinimalPoly==NULL) && (naI==NULL)) || !naIsChar0)
1992  //{
1993  //  result->z = napInit(1);
1994  //  return (number)result;
1995  //}
1996  naNormalize(lb);
1997  naTest(la);
1998  naTest(lb);
1999  napoly x = napCopy(a->z);
2000  number t = napLcm(b->z); // get all denom of b->z
2001  if (!nacIsOne(t))
2002  {
2003    number bt, r;
2004    napoly xx=x;
2005    while (xx!=NULL)
2006    {
2007      bt = nacGcd(t, napGetCoeff(xx), nacRing);
2008      r = nacMult(t, napGetCoeff(xx));
2009      nacDelete(&napGetCoeff(xx),nacRing);
2010      napGetCoeff(xx) = nacDiv(r, bt);
2011      nacNormalize(napGetCoeff(xx));
2012      nacDelete(&bt,nacRing);
2013      nacDelete(&r,nacRing);
2014      napIter(xx);
2015    }
2016  }
2017  nacDelete(&t,nacRing);
2018  result->z = x;
2019  result->cnt=0;
2020#ifdef HAVE_FACTORY
2021  if (b->n!=NULL)
2022  {
2023    result->z=singclap_alglcm(result->z,b->n);
2024    napDelete(&x);
2025  }
2026#endif
2027  naTest(la);
2028  naTest(lb);
2029  naTest((number)result);
2030  return ((number)result);
2031}
2032
2033/*2
2034* input: a set of constant polynomials
2035* sets the global variable naI
2036*/
2037void naSetIdeal(ideal I)
2038{
2039  int i;
2040
2041  if (idIs0(I))
2042  {
2043    for (i=naI->anz-1; i>=0; i--)
2044      napDelete(&naI->liste[i]);
2045    omFreeBin((ADDRESS)naI, snaIdeal_bin);
2046    naI=NULL;
2047  }
2048  else
2049  {
2050    lnumber h;
2051    number a;
2052    napoly x;
2053
2054    naI=(naIdeal)omAllocBin(snaIdeal_bin);
2055    naI->anz=IDELEMS(I);
2056    naI->liste=(napoly*)omAlloc(naI->anz*sizeof(napoly));
2057    for (i=IDELEMS(I)-1; i>=0; i--)
2058    {
2059      h=(lnumber)pGetCoeff(I->m[i]);
2060      /* We only need the enumerator of h, as we expect it to be a polynomial */
2061      naI->liste[i]=napCopy(h->z);
2062      /* If it isn't normalized (lc = 1) do this */
2063      if (!nacIsOne(napGetCoeff(naI->liste[i])))
2064      {
2065        x=naI->liste[i];
2066        nacNormalize(napGetCoeff(x));
2067        a=nacCopy(napGetCoeff(x));
2068        number aa=nacInvers(a);
2069        nacDelete(&a,nacRing);
2070        napMultN(x,aa);
2071        nacDelete(&aa,nacRing);
2072      }
2073    }
2074  }
2075}
2076
2077/*2
2078* map Z/p -> Q(a)
2079*/
2080number naMapP0(number c)
2081{
2082  if (npIsZero(c)) return NULL;
2083  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2084  l->s=2;
2085  l->cnt=0;
2086  l->z=(napoly)p_Init(nacRing);
2087  int i=(int)((long)c);
2088  if (i>(naPrimeM>>2)) i-=naPrimeM;
2089  napGetCoeff(l->z)=nlInit(i);
2090  l->n=NULL;
2091  return (number)l;
2092}
2093
2094/*2
2095* map Q -> Q(a)
2096*/
2097number naMap00(number c)
2098{
2099  if (nlIsZero(c)) return NULL;
2100  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2101  l->s=0;
2102  l->cnt=0;
2103  l->z=(napoly)p_Init(nacRing);
2104  napGetCoeff(l->z)=nlCopy(c);
2105  l->n=NULL;
2106  return (number)l;
2107}
2108
2109/*2
2110* map Z/p -> Z/p(a)
2111*/
2112number naMapPP(number c)
2113{
2114  if (npIsZero(c)) return NULL;
2115  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2116  l->s=2;
2117  l->cnt=0;
2118  l->z=(napoly)p_Init(nacRing);
2119  napGetCoeff(l->z)=c; /* omit npCopy, because npCopy is a no-op */
2120  l->n=NULL;
2121  return (number)l;
2122}
2123
2124/*2
2125* map Z/p' -> Z/p(a)
2126*/
2127number naMapPP1(number c)
2128{
2129  if (npIsZero(c)) return NULL;
2130  int i=(int)((long)c);
2131  if (i>naPrimeM) i-=naPrimeM;
2132  number n=npInit(i);
2133  if (npIsZero(n)) return NULL;
2134  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2135  l->s=2;
2136  l->cnt=0;
2137  l->z=(napoly)p_Init(nacRing);
2138  napGetCoeff(l->z)=n;
2139  l->n=NULL;
2140  return (number)l;
2141}
2142
2143/*2
2144* map Q -> Z/p(a)
2145*/
2146number naMap0P(number c)
2147{
2148  if (nlIsZero(c)) return NULL;
2149  number n=npInit(nlModP(c,npPrimeM));
2150  if (npIsZero(n)) return NULL;
2151  npTest(n);
2152  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2153  l->s=2;
2154  l->cnt=0;
2155  l->z=(napoly)p_Init(nacRing);
2156  napGetCoeff(l->z)=n;
2157  l->n=NULL;
2158  return (number)l;
2159}
2160
2161static number (*nacMap)(number);
2162static int naParsToCopy;
2163static ring napMapRing;
2164static napoly napMap(napoly p)
2165{
2166  napoly w, a;
2167
2168  if (p==NULL) return NULL;
2169  a = w = (napoly)p_Init(nacRing);
2170  int i;
2171  for(i=1;i<=naParsToCopy;i++)
2172    napSetExp(a,i,napGetExpFrom(p,i,napMapRing));
2173  p_Setm(a,nacRing);
2174  napGetCoeff(w) = nacMap(napGetCoeff(p));
2175  loop
2176  {
2177    napIter(p);
2178    if (p==NULL) break;
2179    napNext(a) = (napoly)p_Init(nacRing);
2180    napIter(a);
2181    for(i=1;i<=naParsToCopy;i++)
2182      napSetExp(a,i,napGetExpFrom(p,i,napMapRing));
2183    p_Setm(a,nacRing);
2184    napGetCoeff(a) = nacMap(napGetCoeff(p));
2185  }
2186  napNext(a) = NULL;
2187  return w;
2188}
2189
2190static napoly napPerm(napoly p,const int *par_perm,const ring src_ring,const nMapFunc nMap)
2191{
2192  napoly w, a;
2193
2194  if (p==NULL) return NULL;
2195  w = (napoly)p_Init(nacRing);
2196  int i;
2197  BOOLEAN not_null=TRUE;
2198  loop
2199  {
2200    for(i=1;i<=rPar(src_ring);i++)
2201    {
2202      int e;
2203      if (par_perm!=NULL) e=par_perm[i-1];
2204      else                e=-i;
2205      int ee=napGetExpFrom(p,i,src_ring);
2206      if (e<0)
2207        napSetExp(w,-e,ee);
2208      else if (ee>0)
2209        not_null=FALSE;
2210    }
2211    napGetCoeff(w) = nMap(napGetCoeff(p));
2212    p_Setm(w,nacRing);
2213    napIter(p);
2214    if (!not_null)
2215    {
2216      if (p==NULL)
2217      {
2218        p_Delete(&w,nacRing);
2219        return NULL;
2220      }
2221      /* else continue*/
2222      nacDelete(&(napGetCoeff(w)),nacRing);
2223    }
2224    else
2225    {
2226      if (p==NULL) return w;
2227      else
2228      {
2229        napNext(w)=napPerm(p,par_perm,src_ring,nMap);
2230        return w;
2231      }
2232    }
2233  }
2234}
2235
2236/*2
2237* map _(a) -> _(b)
2238*/
2239number naMapQaQb(number c)
2240{
2241  if (c==NULL) return NULL;
2242  lnumber erg= (lnumber)omAlloc0Bin(rnumber_bin);
2243  lnumber src =(lnumber)c;
2244  erg->s=src->s;
2245  erg->cnt=src->cnt;
2246  erg->z=napMap(src->z);
2247  erg->n=napMap(src->n);
2248  if (naMinimalPoly!=NULL)
2249  {
2250    if (napGetExp(erg->z,1) >= napGetExp(naMinimalPoly,1))
2251    {
2252      erg->z = napRemainder(erg->z, naMinimalPoly);
2253      if (erg->z==NULL)
2254      {
2255        number t_erg=(number)erg;
2256        naDelete(&t_erg,currRing);
2257        return (number)NULL;
2258      }
2259    }
2260    if (erg->n!=NULL)
2261    {
2262      if (napGetExp(erg->n,1) >= napGetExp(naMinimalPoly,1))
2263        erg->n = napRemainder(erg->n, naMinimalPoly);
2264      if ((napIsConstant(erg->n)) && nacIsOne(napGetCoeff(erg->n)))
2265        napDelete(&(erg->n));
2266    }
2267  }
2268  return (number)erg;
2269}
2270
2271nMapFunc naSetMap(ring src, ring dst)
2272{
2273  if (rField_is_Q_a(dst)) /* -> Q(a) */
2274  {
2275    if (rField_is_Q(src))
2276    {
2277      return naMap00;   /*Q -> Q(a)*/
2278    }
2279    if (rField_is_Zp(src))
2280    {
2281      naPrimeM = rChar(src);
2282      return naMapP0;  /* Z/p -> Q(a)*/
2283    }
2284    if (rField_is_Q_a(src))
2285    {
2286      int i;
2287      naParsToCopy=0;
2288      for(i=0;i<rPar(src);i++)
2289      {
2290        if ((i>=rPar(dst))
2291        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
2292           return NULL;
2293        naParsToCopy++;
2294      }
2295      napMapRing=src;
2296      nacMap=nacCopy;
2297      if ((naParsToCopy==rPar(dst))&&(naParsToCopy==rPar(src)))
2298        return naCopy;    /* Q(a) -> Q(a) */
2299      return naMapQaQb;   /* Q(a..) -> Q(a..) */
2300    }
2301  }
2302  /*-----------------------------------------------------*/
2303  if (rField_is_Zp_a(dst)) /* -> Z/p(a) */
2304  {
2305    if (rField_is_Q(src))
2306    {
2307      return naMap0P;   /*Q -> Z/p(a)*/
2308    }
2309    if (rField_is_Zp(src))
2310    {
2311      int c=rChar(src);
2312      if (c==npPrimeM)
2313      {
2314        return naMapPP;  /* Z/p -> Z/p(a)*/
2315      }
2316      else
2317      {
2318        naPrimeM = c;
2319        return naMapPP1;  /* Z/p' -> Z/p(a)*/
2320      }
2321    }
2322    if (rField_is_Zp_a(src))
2323    {
2324      if (rChar(src)==rChar(dst))
2325      {
2326        nacMap=nacCopy;
2327      }
2328      else
2329      {
2330        npMapPrime=rChar(src);
2331        nacMap = npMapP;
2332      }
2333      int i;
2334      naParsToCopy=0;
2335      for(i=0;i<rPar(src);i++)
2336      {
2337        if ((i>=rPar(dst))
2338        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
2339           return NULL;
2340        naParsToCopy++;
2341      }
2342      napMapRing=src;
2343      if ((naParsToCopy==rPar(dst))&&(naParsToCopy==rPar(src))
2344      && (nacMap==nacCopy))
2345        return naCopy;    /* Z/p(a) -> Z/p(a) */
2346      return naMapQaQb;   /* Z/p(a),Z/p'(a) -> Z/p(b)*/
2347    }
2348  }
2349  return NULL;      /* default */
2350}
2351
2352/*2
2353* convert a napoly number into a poly
2354*/
2355poly naPermNumber(number z, int * par_perm, int P, ring oldRing)
2356{
2357  if (z==NULL) return NULL;
2358  poly res=NULL;
2359  poly p;
2360  napoly za=((lnumber)z)->z;
2361  napoly zb=((lnumber)z)->n;
2362  nMapFunc nMap=naSetMap(oldRing,currRing);
2363  if (currRing->parameter!=NULL)
2364    nMap=currRing->algring->cf->cfSetMap(oldRing->algring, nacRing);
2365  else
2366    nMap=currRing->cf->cfSetMap(oldRing->algring, currRing);
2367  if (nMap==NULL) return NULL; /* emergency exit only */
2368  do
2369  {
2370    p = pInit();
2371    pNext(p)=NULL;
2372    nNew(&pGetCoeff(p));
2373    int i;
2374    for(i=pVariables;i;i--)
2375       pSetExp(p,i, 0);
2376    pSetComp(p, 0);
2377    napoly pa=NULL;
2378    lnumber pan;
2379    if (currRing->parameter!=NULL)
2380    {
2381      assume(oldRing->algring!=NULL);
2382      pGetCoeff(p)=(number)omAlloc0Bin(rnumber_bin);
2383      pan=(lnumber)pGetCoeff(p);
2384      pan->s=2;
2385      pan->z=napInitz(nMap(napGetCoeff(za)));
2386      pa=pan->z;
2387    }
2388    else
2389    {
2390      pGetCoeff(p)=nMap(napGetCoeff(za));
2391    }
2392    for(i=0;i<P;i++)
2393    {
2394      if(napGetExpFrom(za,i+1,oldRing)!=0)
2395      {
2396        if(par_perm==NULL)
2397        {
2398          if ((rPar(currRing)>=i) && (pa!=NULL))
2399          {
2400            napSetExp(pa,i+1,napGetExpFrom(za,i+1,oldRing));
2401            p_Setm(pa,nacRing);
2402          }
2403          else
2404          {
2405            pDelete(&p);
2406            break;
2407          }
2408        }
2409        else if(par_perm[i]>0)
2410          pSetExp(p,par_perm[i],napGetExpFrom(za,i+1,oldRing));
2411        else if((par_perm[i]<0)&&(pa!=NULL))
2412        {
2413          napSetExp(pa,-par_perm[i], napGetExpFrom(za,i+1,oldRing));
2414          p_Setm(pa,nacRing);
2415        }
2416        else
2417        {
2418          pDelete(&p);
2419          break;
2420        }
2421      }
2422    }
2423    if (p!=NULL)
2424    {
2425      pSetm(p);
2426      if (zb!=NULL)
2427      {
2428        if  (currRing->P>0)
2429        {
2430          pan->n=napPerm(zb,par_perm,oldRing,nMap);
2431          if(pan->n==NULL) /* error in mapping or mapping to variable */
2432            pDelete(&p);
2433        }
2434        else
2435          pDelete(&p);
2436      }
2437      pTest(p);
2438      res=pAdd(res,p);
2439    }
2440    napIter(za);
2441  }
2442  while (za!=NULL);
2443  pTest(res);
2444  return res;
2445}
2446
2447number   naGetDenom(number &n, const ring r)
2448{
2449  if (r==currRing) naNormalize(n);
2450  lnumber x=(lnumber)n;
2451  if (x->n!=NULL)
2452  {
2453    lnumber rr=(lnumber)omAlloc0Bin(rnumber_bin);
2454    rr->z=nap_Copy(naGetDenom0(x),r);
2455    rr->s = 2;
2456    rr->cnt=0;
2457    return (number)rr;
2458  }
2459  return r->cf->nInit(1);
2460}
2461
2462#ifdef LDEBUG
2463BOOLEAN naDBTest(number a, const char *f,const int l)
2464{
2465  lnumber x=(lnumber)a;
2466  if (x == NULL)
2467    return TRUE;
2468  omCheckAddrSize(a, sizeof(snumber));
2469  napoly p = x->z;
2470  if (p==NULL)
2471  {
2472    Print("0/* in %s:%d\n",f,l);
2473    return FALSE;
2474  }
2475  while(p!=NULL)
2476  {
2477    if ((naIsChar0 && nlIsZero(napGetCoeff(p)))
2478    || ((!naIsChar0) && npIsZero(napGetCoeff(p))))
2479    {
2480      Print("coeff 0 in %s:%d\n",f,l);
2481      return FALSE;
2482    }
2483    if((naMinimalPoly!=NULL)&&(napGetExp(p,1)>napGetExp(naMinimalPoly,1))
2484    &&(p!=naMinimalPoly))
2485    {
2486      Print("deg>minpoly in %s:%d\n",f,l);
2487      return FALSE;
2488    }
2489    //if (naIsChar0 && (((int)p->ko &3) == 0) && (p->ko->s==0) && (x->s==2))
2490    //{
2491    //  Print("normalized with non-normal coeffs in %s:%d\n",f,l);
2492    //  return FALSE;
2493    //}
2494    if (naIsChar0 && !(nlDBTest(napGetCoeff(p),f,l)))
2495      return FALSE;
2496    napIter(p);
2497  }
2498  p = naGetDenom0(x);
2499  while(p!=NULL)
2500  {
2501    if (naIsChar0 && !(nlDBTest(napGetCoeff(p),f,l)))
2502      return FALSE;
2503    napIter(p);
2504  }
2505  return TRUE;
2506}
2507#endif
2508
Note: See TracBrowser for help on using the repository browser.