source: git/kernel/longalg.cc @ 6094f4

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