source: git/kernel/longalg.cc @ aa74213

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