source: git/kernel/longalg.cc @ 70f63a

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