source: git/kernel/longalg.cc @ 893148

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