source: git/kernel/longalg.cc @ 2072126

fieker-DuValspielwiese
Last change on this file since 2072126 was cdec33, checked in by Frank Seelisch <seelisch@…>, 13 years ago
fix for ticket #329 git-svn-id: file:///usr/local/Singular/svn/trunk@14114 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 34.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longalg.cc 12469 2010-01-28 10:39:49Z hannes $ */
5/*
6* ABSTRACT:   algebraic numbers
7*/
8
9#include <stdio.h>
10#include <string.h>
11#include <kernel/mod2.h>
12#include <kernel/structs.h>
13#include <omalloc/omalloc.h>
14#include <kernel/febase.h>
15#include <kernel/longrat.h>
16#include <kernel/modulop.h>
17#include <kernel/numbers.h>
18#include <kernel/polys.h>
19#include <kernel/ideals.h>
20#include <kernel/ring.h>
21#ifdef HAVE_FACTORY
22#define SI_DONT_HAVE_GLOBAL_VARS
23#include <factory/factory.h>
24#include <kernel/clapsing.h>
25#include <kernel/clapconv.h>
26#endif
27#include <kernel/longalg.h>
28#include <kernel/longtrans.h>
29
30#ifdef LDEBUG
31#define naTest(a) naDBTest(a,__FILE__,__LINE__)
32BOOLEAN naDBTest(number a, const char *f,const int l);
33#else
34#define naTest(a)
35#endif
36
37naIdeal naI = NULL;
38napoly  naMinimalPoly;
39omBin   snaIdeal_bin = omGetSpecBin(sizeof(snaIdeal));
40number  (*naMap)(number from);
41
42void redefineFunctionPointers()
43{
44  n_Procs_s* n = currRing->cf;
45  /* re-defining function pointers */
46  n->cfDelete       = naDelete;
47  n->nNormalize     = naNormalize;
48  n->cfInit         = naInit;
49  n->nPar           = naPar;
50  n->nParDeg        = naParDeg;
51  n->n_Int          = naInt;
52  n->nAdd           = naAdd;
53  n->nSub           = naSub;
54  n->nMult          = naMult;
55  n->nDiv           = naDiv;
56  n->nExactDiv      = naDiv;
57  n->nIntDiv        = naIntDiv;
58  n->nNeg           = naNeg;
59  n->nInvers        = naInvers;
60  n->nCopy          = naCopy;
61  n->cfCopy         = na_Copy;
62  n->nGreater       = naGreater;
63  n->nEqual         = naEqual;
64  n->nIsZero        = naIsZero;
65  n->nIsOne         = naIsOne;
66  n->nIsMOne        = naIsMOne;
67  n->nGreaterZero   = naGreaterZero;
68  n->nGreater       = naGreater;
69  n->cfWrite        = naWrite;
70  n->nRead          = naRead;
71  n->nPower         = naPower;
72  n->nGcd           = naGcd;
73  n->nLcm           = naLcm;
74  n->cfSetMap       = naSetMap;
75  n->nName          = naName;
76  n->nSize          = naSize;
77  n->cfGetDenom     = napGetDenom;
78  n->cfGetNumerator = napGetNumerator;
79#ifdef LDEBUG
80  n->nDBTest        = naDBTest;
81#endif
82  /* re-defining global function pointers */
83  nNormalize=naNormalize;
84  nPar   = naPar;
85  nParDeg= nParDeg;
86  n_Int  = naInt;
87  nAdd   = naAdd;
88  nSub   = naSub;
89  nMult  = naMult;
90  nDiv   = naDiv;
91  nExactDiv= naDiv;
92  nIntDiv= naIntDiv;
93  nNeg   = naNeg;
94  nInvers= naInvers;
95  nCopy  = naCopy;
96  nGreater = naGreater;
97  nEqual = naEqual;
98  nIsZero = naIsZero;
99  nIsOne = naIsOne;
100  nIsMOne = naIsMOne;
101  nGreaterZero = naGreaterZero;
102  nGreater = naGreater;
103  nRead = naRead;
104  nPower = naPower;
105  nGcd  = naGcd;
106  nLcm  = naLcm;
107  nName= naName;
108  nSize  = naSize;
109}
110
111static number nadGcd( number a, number b, const ring r) { return nacInit(1,r); }
112/*2
113*  sets the appropriate operators
114*/
115void naSetChar(int i, ring r)
116{
117  assume((r->minpoly  != NULL) ||
118         (r->minideal != NULL)    );
119 
120  if (naI!=NULL)
121  {
122    int j;
123    for (j=naI->anz-1; j>=0; j--)
124       p_Delete (&naI->liste[j],nacRing);
125    omFreeSize((ADDRESS)naI->liste,naI->anz*sizeof(napoly));
126    omFreeBin((ADDRESS)naI, snaIdeal_bin);
127    naI=NULL;
128  }
129  naMap = naCopy;
130
131  if (r->minpoly!=NULL)
132  {
133    naMinimalPoly=((lnumber)r->minpoly)->z;
134    #ifdef LDEBUG
135    omCheckAddr(naMinimalPoly);
136    #endif
137  }
138  else
139    naMinimalPoly = NULL;
140   
141  if (r->minideal!=NULL)
142  {
143    naI=(naIdeal)omAllocBin(snaIdeal_bin);
144    naI->anz=IDELEMS(r->minideal);
145    naI->liste=(napoly*)omAlloc(naI->anz*sizeof(napoly));
146    int j;
147    for (j=naI->anz-1; j>=0; j--)
148    {
149      lnumber a = (lnumber)pGetCoeff(r->minideal->m[j]);
150      naI->liste[j]=napCopy(a->z);
151    }
152  }
153
154  ntNumbOfPar=rPar(r);
155  if (i == 1)
156    ntIsChar0 = 1;
157  else if (i < 0)
158  {
159    ntIsChar0 = 0;
160    npSetChar(-i, r->algring); // to be changed HS
161  }
162#ifdef TEST
163  else
164  {
165    Print("naSetChar:c=%d param=%d\n",i,rPar(r));
166  }
167#endif
168  nacRing        = r->algring;
169  nacInit        = nacRing->cf->cfInit;
170  nacInt         = nacRing->cf->n_Int;
171  nacCopy        = nacRing->cf->nCopy;
172  nacAdd         = nacRing->cf->nAdd;
173  nacSub         = nacRing->cf->nSub;
174  nacNormalize   = nacRing->cf->nNormalize;
175  nacNeg         = nacRing->cf->nNeg;
176  nacIsZero      = nacRing->cf->nIsZero;
177  nacGreaterZero = nacRing->cf->nGreaterZero;
178  nacGreater     = nacRing->cf->nGreater;
179  nacIsOne       = nacRing->cf->nIsOne;
180  nacGcd         = nacRing->cf->nGcd;
181  nacLcm         = nacRing->cf->nLcm;
182  nacMult        = nacRing->cf->nMult;
183  nacDiv         = nacRing->cf->nDiv;
184  nacIntDiv      = nacRing->cf->nIntDiv;
185  nacInvers      = nacRing->cf->nInvers;
186}
187
188/*================ procedure for rational functions: naXXXX =================*/
189
190/*2
191*  z:= i
192*/
193number naInit(int i, const ring r)
194{
195  if (i!=0)
196  {
197    number c=n_Init(i,r->algring);
198    if (!n_IsZero(c,r->algring))
199    {
200      poly z=p_Init(r->algring);
201      pSetCoeff0(z,c);
202      lnumber l = (lnumber)omAllocBin(rnumber_bin);
203      l->z = z;
204      l->s = 2;
205      l->n = NULL;
206      return (number)l;
207    }
208  }
209  /*else*/
210  return NULL;
211}
212
213number  naPar(int i)
214{
215  lnumber l = (lnumber)omAllocBin(rnumber_bin);
216  l->s = 2;
217  l->z = p_ISet(1,nacRing);
218  napSetExp(l->z,i,1);
219  p_Setm(l->z,nacRing);
220  l->n = NULL;
221  return (number)l;
222}
223
224int     naParDeg(number n)     /* i := deg(n) */
225{
226  lnumber l = (lnumber)n;
227  if (l==NULL) return -1;
228  return napDeg(l->z);
229}
230
231//int     naParDeg(number n)     /* i := deg(n) */
232//{
233//  lnumber l = (lnumber)n;
234//  if (l==NULL) return -1;
235//  return napMaxDeg(l->z)+napMaxDeg(l->n);
236//}
237
238int     naSize(number n)     /* size desc. */
239{
240  lnumber l = (lnumber)n;
241  if (l==NULL) return -1;
242  int len_z;
243  int len_n;
244  int o=napMaxDegLen(l->z,len_z)+napMaxDegLen(l->n,len_n);
245  return (len_z+len_n)+o;
246}
247
248/*2
249* convert a number to int (if possible)
250*/
251int naInt(number &n, const ring r)
252{
253  lnumber l=(lnumber)n;
254  if ((l!=NULL)&&(l->n==NULL)&&(p_IsConstant(l->z,r->algring)))
255  {
256    return nacInt(pGetCoeff(l->z),r->algring);
257  }
258  return 0;
259}
260
261/*2
262*  deletes p
263*/
264void naDelete(number *p, const ring r)
265{
266  if ((*p)!=r->minpoly)
267  {
268    lnumber l = (lnumber) * p;
269    if (l==NULL) return;
270    p_Delete(&(l->z),r->algring);
271    p_Delete(&(l->n),r->algring);
272    omFreeBin((ADDRESS)l,  rnumber_bin);
273  }
274  *p = NULL;
275}
276
277/*2
278* copy p to erg
279*/
280number naCopy(number p)
281{
282  if (p==NULL) return NULL;
283  naTest(p);
284  lnumber erg;
285  lnumber src = (lnumber)p;
286  erg = (lnumber)omAlloc0Bin(rnumber_bin);
287  erg->z = p_Copy(src->z, nacRing);
288  erg->n = p_Copy(src->n, nacRing);
289  erg->s = src->s;
290  return (number)erg;
291}
292number na_Copy(number p, const ring r)
293{
294  if (p==NULL) return NULL;
295  lnumber erg;
296  lnumber src = (lnumber)p;
297  erg = (lnumber)omAlloc0Bin(rnumber_bin);
298  erg->z = p_Copy(src->z,r->algring);
299  erg->n = p_Copy(src->n,r->algring);
300  erg->s = src->s;
301  return (number)erg;
302}
303
304/*2
305*  addition; lu:= la + lb
306*/
307number naAdd(number la, number lb)
308{
309  if (la==NULL) return naCopy(lb);
310  if (lb==NULL) return naCopy(la);
311
312  napoly x, y;
313  lnumber lu;
314  lnumber a = (lnumber)la;
315  lnumber b = (lnumber)lb;
316  #ifdef LDEBUG
317  omCheckAddrSize(a,sizeof(snumber));
318  omCheckAddrSize(b,sizeof(snumber));
319  #endif
320  if (b->n!=NULL) x = pp_Mult_qq(a->z, b->n,nacRing);
321  else            x = napCopy(a->z);
322  if (a->n!=NULL) y = pp_Mult_qq(b->z, a->n,nacRing);
323  else            y = napCopy(b->z);
324  napoly res = napAdd(x, y);
325  if (res==NULL)
326  {
327    return (number)NULL;
328  }
329  lu = (lnumber)omAllocBin(rnumber_bin);
330  lu->z=res;
331  if (a->n!=NULL)
332  {
333    if (b->n!=NULL) x = pp_Mult_qq(a->n, b->n,nacRing);
334    else            x = napCopy(a->n);
335  }
336  else
337  {
338    if (b->n!=NULL) x = napCopy(b->n);
339    else            x = NULL;
340  }
341  //if (x!=NULL)
342  //{
343  //  if (p_LmIsConstant(x,nacRing))
344  //  {
345  //    number inv=nacInvers(pGetCoeff(x));
346  //    napMultN(lu->z,inv);
347  //    n_Delete(&inv,nacRing);
348  //    napDelete(&x);
349  //  }
350  //}
351  lu->n = x;
352  lu->s = FALSE;
353  if (/*lu->n*/ x!=NULL)
354  {
355     number luu=(number)lu;
356     //if (p_IsConstant(lu->n,nacRing)) naCoefNormalize(luu);
357     //else
358                naNormalize(luu);
359     lu=(lnumber)luu;
360  }
361  //else lu->s=2;
362  naTest((number)lu);
363  return (number)lu;
364}
365
366/*2
367*  subtraction; r:= la - lb
368*/
369number naSub(number la, number lb)
370{
371  lnumber lu;
372
373  if (lb==NULL) return naCopy(la);
374  if (la==NULL)
375  {
376    lu = (lnumber)naCopy(lb);
377    lu->z = napNeg(lu->z);
378    return (number)lu;
379  }
380
381  lnumber a = (lnumber)la;
382  lnumber b = (lnumber)lb;
383
384  #ifdef LDEBUG
385  omCheckAddrSize(a,sizeof(snumber));
386  omCheckAddrSize(b,sizeof(snumber));
387  #endif
388
389  napoly x, y;
390  if (b->n!=NULL) x = pp_Mult_qq(a->z, b->n,nacRing);
391  else            x = napCopy(a->z);
392  if (a->n!=NULL) y = p_Mult_q(napCopy(b->z), napCopyNeg(a->n),nacRing);
393  else            y = napCopyNeg(b->z);
394  napoly res = napAdd(x, y);
395  if (res==NULL)
396  {
397    return (number)NULL;
398  }
399  lu = (lnumber)omAllocBin(rnumber_bin);
400  lu->z=res;
401  if (a->n!=NULL)
402  {
403    if (b->n!=NULL) x = pp_Mult_qq(a->n, b->n,nacRing);
404    else            x = napCopy(a->n);
405  }
406  else
407  {
408    if (b->n!=NULL) x = napCopy(b->n);
409    else            x = NULL;
410  }
411  lu->n = x;
412  lu->s = FALSE;
413  if (/*lu->n*/ x!=NULL)
414  {
415     number luu=(number)lu;
416     //if (p_IsConstant(lu->n,nacRing)) naCoefNormalize(luu);
417     //else
418                         naNormalize(luu);
419     lu=(lnumber)luu;
420  }
421  //else lu->s=2;
422  naTest((number)lu);
423  return (number)lu;
424}
425
426/*2
427*  multiplication; r:= la * lb
428*/
429number naMult(number la, number lb)
430{
431  if ((la==NULL) || (lb==NULL))
432    return NULL;
433
434  lnumber a = (lnumber)la;
435  lnumber b = (lnumber)lb;
436  lnumber lo;
437  napoly x;
438
439  #ifdef LDEBUG
440  omCheckAddrSize(a,sizeof(snumber));
441  omCheckAddrSize(b,sizeof(snumber));
442  #endif
443  naTest(la);
444  naTest(lb);
445
446  lo = (lnumber)omAllocBin(rnumber_bin);
447  lo->z = pp_Mult_qq(a->z, b->z,nacRing);
448
449  if (a->n==NULL)
450  {
451    if (b->n==NULL)
452      x = NULL;
453    else
454      x = napCopy(b->n);
455  }
456  else
457  {
458    if (b->n==NULL)
459    {
460      x = napCopy(a->n);
461    }
462    else
463    {
464      x = pp_Mult_qq(b->n, a->n, nacRing);
465    }
466  }
467  if (naMinimalPoly!=NULL)
468  {
469    if (p_GetExp(lo->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
470      lo->z = napRemainder(lo->z, naMinimalPoly);
471    if ((x!=NULL) &&
472        (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing)))
473      x = napRemainder(x, naMinimalPoly);
474  }
475  if (naI!=NULL)
476  {
477    lo->z = napRedp (lo->z);
478    if (lo->z != NULL)
479       lo->z = napTailred (lo->z);
480    if (x!=NULL)
481    {
482      x = napRedp (x);
483      if (x!=NULL)
484        x = napTailred (x);
485    }
486  }
487  if ((x!=NULL) && (p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
488    p_Delete(&x,nacRing);
489  lo->n = x;
490  lo->s = 0;
491  if(lo->z==NULL)
492  {
493    omFreeBin((ADDRESS)lo, rnumber_bin);
494    lo=NULL;
495  }
496  else if (lo->n!=NULL)
497  {
498    number luu=(number)lo;
499    // if (p_IsConstant(lo->n,nacRing)) naCoefNormalize(luu);
500    // else
501                      naNormalize(luu);
502    lo=(lnumber)luu;
503  }
504  //if (naMinimalPoly==NULL) lo->s=2;
505  naTest((number)lo);
506  return (number)lo;
507}
508
509number naIntDiv(number la, number lb)
510{
511  lnumber res;
512  lnumber a = (lnumber)la;
513  lnumber b = (lnumber)lb;
514  if (a==NULL)
515  {
516    return NULL;
517  }
518  if (b==NULL)
519  {
520    WerrorS(nDivBy0);
521    return NULL;
522  }
523  assume(a->z!=NULL && b->z!=NULL);
524  assume(a->n==NULL && b->n==NULL);
525  res = (lnumber)omAllocBin(rnumber_bin);
526  res->z = napCopy(a->z);
527  res->n = napCopy(b->z);
528  res->s = 0;
529  number nres=(number)res;
530  naNormalize(nres);
531
532  //napDelete(&res->n);
533  naTest(nres);
534  return nres;
535}
536
537/*2
538*  division; lo:= la / lb
539*/
540number naDiv(number la, number lb)
541{
542  lnumber lo;
543  lnumber a = (lnumber)la;
544  lnumber b = (lnumber)lb;
545  napoly x;
546
547  if (a==NULL)
548    return NULL;
549
550  if (b==NULL)
551  {
552    WerrorS(nDivBy0);
553    return NULL;
554  }
555  #ifdef LDEBUG
556  omCheckAddrSize(a,sizeof(snumber));
557  omCheckAddrSize(b,sizeof(snumber));
558  #endif
559  lo = (lnumber)omAllocBin(rnumber_bin);
560  if (b->n!=NULL)
561    lo->z = pp_Mult_qq(a->z, b->n,nacRing);
562  else
563    lo->z = napCopy(a->z);
564  if (a->n!=NULL)
565    x = pp_Mult_qq(b->z, a->n, nacRing);
566  else
567    x = napCopy(b->z);
568  if (naMinimalPoly!=NULL)
569  {
570    if (p_GetExp(lo->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
571      lo->z = napRemainder(lo->z, naMinimalPoly);
572    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
573      x = napRemainder(x, naMinimalPoly);
574  }
575  if (naI!=NULL)
576  {
577    lo->z = napRedp (lo->z);
578    if (lo->z != NULL)
579       lo->z = napTailred (lo->z);
580    if (x!=NULL)
581    {
582      x = napRedp (x);
583      if (x!=NULL)
584        x = napTailred (x);
585    }
586  }
587  if ((p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
588    p_Delete(&x,nacRing);
589  lo->n = x;
590  lo->s = 0;
591  if (lo->n!=NULL)
592  {
593    number luu=(number)lo;
594     //if (p_IsConstant(lo->n,nacRing)) naCoefNormalize(luu);
595     //else
596                         naNormalize(luu);
597    lo=(lnumber)luu;
598  }
599  //else lo->s=2;
600  naTest((number)lo);
601  return (number)lo;
602}
603
604/*2
605*  za:= - za, inplace
606*/
607number naNeg(number za)
608{
609  if (za!=NULL)
610  {
611    lnumber e = (lnumber)za;
612    naTest(za);
613    e->z = napNeg(e->z);
614  }
615  return za;
616}
617
618/*2
619* 1/a
620*/
621number naInvers(number a)
622{
623  lnumber lo;
624  lnumber b = (lnumber)a;
625  napoly x;
626
627  if (b==NULL)
628  {
629    WerrorS(nDivBy0);
630    return NULL;
631  }
632  #ifdef LDEBUG
633  omCheckAddrSize(b,sizeof(snumber));
634  #endif
635  lo = (lnumber)omAlloc0Bin(rnumber_bin);
636  lo->s = b->s;
637  if (b->n!=NULL)
638    lo->z = napCopy(b->n);
639  else
640    lo->z = p_ISet(1,nacRing);
641  x = b->z;
642  if ((!p_LmIsConstant(x,nacRing)) || !nacIsOne(pGetCoeff(x)))
643    x = napCopy(x);
644  else
645  {
646    lo->n = NULL;
647    naTest((number)lo);
648    return (number)lo;
649  }
650  if (naMinimalPoly!=NULL)
651  {
652    x = napInvers(x, naMinimalPoly);
653    x = p_Mult_q(x, lo->z,nacRing);
654    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
655      x = napRemainder(x, naMinimalPoly);
656    lo->z = x;
657    lo->n = NULL;
658    while (x!=NULL)
659    {
660      nacNormalize(pGetCoeff(x));
661      pIter(x);
662    }
663  }
664  else
665    lo->n = x;
666  if (lo->n!=NULL)
667  {
668     number luu=(number)lo;
669     //if (p_IsConstant(lo->n,nacRing)) naCoefNormalize(luu);
670     //else
671                           naNormalize(luu);
672     lo=(lnumber)luu;
673  }
674  naTest((number)lo);
675  return (number)lo;
676}
677
678
679BOOLEAN naIsZero(number za)
680{
681  lnumber zb = (lnumber)za;
682  naTest(za);
683#ifdef LDEBUG
684  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(2)");
685#endif
686  return (zb==NULL);
687}
688
689
690BOOLEAN naGreaterZero(number za)
691{
692  lnumber zb = (lnumber)za;
693#ifdef LDEBUG
694  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(3)");
695#endif
696  naTest(za);
697  if (zb!=NULL)
698  {
699    return (nacGreaterZero(pGetCoeff(zb->z))||(!p_LmIsConstant(zb->z,nacRing)));
700  }
701  /* else */ return FALSE;
702}
703
704
705/*2
706* a = b ?
707*/
708BOOLEAN naEqual (number a, number b)
709{
710  if(a==b) return TRUE;
711  if((a==NULL)&&(b!=NULL)) return FALSE;
712  if((b==NULL)&&(a!=NULL)) return FALSE;
713
714  lnumber aa=(lnumber)a;
715  lnumber bb=(lnumber)b;
716
717  int an_deg=0;
718  if(aa->n!=NULL)
719    an_deg=napDeg(aa->n);
720  int bn_deg=0;
721  if(bb->n!=NULL)
722    bn_deg=napDeg(bb->n);
723  if(an_deg+napDeg(bb->z)!=bn_deg+napDeg(aa->z))
724    return FALSE;
725#if 0
726  naNormalize(a);
727  aa=(lnumber)a;
728  naNormalize(b);
729  bb=(lnumber)b;
730  if((aa->n==NULL)&&(bb->n!=NULL)) return FALSE;
731  if((bb->n==NULL)&&(aa->n!=NULL)) return FALSE;
732  if(napComp(aa->z,bb->z)!=0) return FALSE;
733  if((aa->n!=NULL) && (napComp(aa->n,bb->n))) return FALSE;
734#endif
735  number h = naSub(a, b);
736  BOOLEAN bo = naIsZero(h);
737  naDelete(&h,currRing);
738  return bo;
739}
740
741
742/* This method will only consider the numerators of a and b.
743   Moreover it may return TRUE only if one or both numerators
744   are zero or if their degrees are equal. Then TRUE is returned iff
745   coeff(numerator(a)) > coeff(numerator(b));
746   In all other cases, FALSE will be returned. */
747BOOLEAN naGreater (number a, number b)
748{
749  int az = 0; int ad = 0;
750  if (naIsZero(a)) az = 1;
751  else ad = napDeg(((lnumber)a)->z);
752  int bz = 0; int bd = 0;
753  if (naIsZero(b)) bz = 1;
754  else bd = napDeg(((lnumber)b)->z);
755 
756  if ((az == 1) && (bz == 1)) /* a = b = 0 */ return FALSE;
757  if (az == 1) /* a = 0, b != 0 */
758  {
759    return (!nacGreaterZero(pGetCoeff(((lnumber)b)->z)));
760  }
761  if (bz == 1) /* a != 0, b = 0 */
762  {
763    return (nacGreaterZero(pGetCoeff(((lnumber)a)->z)));
764  }
765  if (ad == bd) 
766    return nacGreater(pGetCoeff(((lnumber)a)->z),
767                      pGetCoeff(((lnumber)b)->z));
768  return FALSE;
769}
770
771/*2
772* reads a number
773*/
774const char  *naRead(const char *s, number *p)
775{
776  napoly x;
777  lnumber a;
778  s = napRead(s, &x);
779  if (x==NULL)
780  {
781    *p = NULL;
782    return s;
783  }
784  *p = (number)omAlloc0Bin(rnumber_bin);
785  a = (lnumber)*p;
786  if ((naMinimalPoly!=NULL)
787  && (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing)))
788    a->z = napRemainder(x, naMinimalPoly);
789  else if (naI!=NULL)
790  {
791    a->z = napRedp(x);
792    if (a->z != NULL)
793      a->z = napTailred (a->z);
794  }
795  else
796    a->z = x;
797  if(a->z==NULL)
798  {
799    omFreeBin((ADDRESS)*p, rnumber_bin);
800    *p=NULL;
801  }
802  else
803  {
804    a->n = NULL;
805    a->s = 0;
806    naTest(*p);
807  }
808  return s;
809}
810
811/*2
812* tries to convert a number to a name
813*/
814char * naName(number n)
815{
816  lnumber ph = (lnumber)n;
817  if (ph==NULL)
818    return NULL;
819  int i;
820  char *s=(char *)omAlloc(4* ntNumbOfPar);
821  char *t=(char *)omAlloc(8);
822  s[0]='\0';
823  for (i = 0; i <= ntNumbOfPar - 1; i++)
824  {
825    int e=p_GetExp(ph->z,i+1,nacRing);
826    if (e > 0)
827    {
828      if (e >1)
829      {
830        sprintf(t,"%s%d",ntParNames[i],e);
831        strcat(s,t);
832      }
833      else
834      {
835        strcat(s,ntParNames[i]);
836      }
837    }
838  }
839  omFreeSize((ADDRESS)t,8);
840  if (s[0]=='\0')
841  {
842    omFree((ADDRESS)s);
843    return NULL;
844  }
845  return s;
846}
847
848/*2
849*  writes a number
850*/
851void naWrite(number &phn, const ring r)
852{
853  lnumber ph = (lnumber)phn;
854  if (ph==NULL)
855    StringAppendS("0");
856  else
857  {
858    phn->s = 0;
859    BOOLEAN has_denom=(ph->n!=NULL);
860    napWrite(ph->z,has_denom/*(ph->n!=NULL)*/,r);
861    if (has_denom/*(ph->n!=NULL)*/)
862    {
863      StringAppendS("/");
864      napWrite(ph->n,TRUE,r);
865    }
866  }
867}
868
869/*2
870* za == 1 ?
871*/
872BOOLEAN naIsOne(number za)
873{
874  lnumber a = (lnumber)za;
875  napoly x, y;
876  number t;
877  if (a==NULL) return FALSE;
878#ifdef LDEBUG
879  omCheckAddrSize(a,sizeof(snumber));
880  if (a->z==NULL)
881  {
882    WerrorS("internal zero error(4)");
883    return FALSE;
884  }
885#endif
886  if (a->n==NULL)
887  {
888    if (p_LmIsConstant(a->z,nacRing))
889    {
890      return nacIsOne(pGetCoeff(a->z));
891    }
892    else                 return FALSE;
893  }
894#if 0
895  x = a->z;
896  y = a->n;
897  do
898  {
899    if (napComp(x, y))
900      return FALSE;
901    else
902    {
903      t = nacSub(pGetCoeff(x), pGetCoeff(y));
904      if (!nacIsZero(t))
905      {
906        n_Delete(&t,nacRing);
907        return FALSE;
908      }
909      else
910        n_Delete(&t,nacRing);
911    }
912    pIter(x);
913    pIter(y);
914  }
915  while ((x!=NULL) && (y!=NULL));
916  if ((x!=NULL) || (y!=NULL)) return FALSE;
917  p_Delete(&a->z,nacRing);
918  p_Delete(&a->n,nacRing);
919  a->z = p_ISet(1,nacRing);
920  a->n = NULL;
921  return TRUE;
922#else
923  return FALSE;
924#endif
925}
926
927/*2
928* za == -1 ?
929*/
930BOOLEAN naIsMOne(number za)
931{
932  lnumber a = (lnumber)za;
933  napoly x, y;
934  number t;
935  if (a==NULL) return FALSE;
936#ifdef LDEBUG
937  omCheckAddrSize(a,sizeof(snumber));
938  if (a->z==NULL)
939  {
940    WerrorS("internal zero error(5)");
941    return FALSE;
942  }
943#endif
944  if (a->n==NULL)
945  {
946    if (p_LmIsConstant(a->z,nacRing)) return n_IsMOne(pGetCoeff(a->z),nacRing);
947    /*else                   return FALSE;*/
948  }
949  return FALSE;
950}
951
952/*2
953* returns the i-th power of p (i>=0)
954*/
955void naPower(number p, int i, number *rc)
956{
957  number x;
958  *rc = naInit(1,currRing);
959  for (; i > 0; i--)
960  {
961    x = naMult(*rc, p);
962    naDelete(rc,currRing);
963    *rc = x;
964  }
965}
966
967/*2
968* result =gcd(a,b)
969*/
970number naGcd(number a, number b, const ring r)
971{
972  if (a==NULL)  return naCopy(b);
973  if (b==NULL)  return naCopy(a);
974
975  lnumber x, y;
976  lnumber result = (lnumber)omAlloc0Bin(rnumber_bin);
977
978  x = (lnumber)a;
979  y = (lnumber)b;
980  if ((ntNumbOfPar == 1) && (naMinimalPoly!=NULL))
981  {
982    if (pNext(x->z)!=NULL)
983      result->z = p_Copy(x->z, r->algring);
984    else
985      result->z = napGcd0(x->z, y->z);
986  }
987  else
988#ifndef HAVE_FACTORY
989    result->z = napGcd(x->z, y->z); // change from napGcd0
990#else
991  {
992    int c=ABS(nGetChar());
993    if (c==1) c=0;
994    setCharacteristic( c );
995
996    napoly rz=napGcd(x->z, y->z);
997    CanonicalForm F, G, R;
998    R=convSingPFactoryP(rz,r->algring);
999    p_Normalize(x->z,nacRing);
1000    F=convSingPFactoryP(x->z,r->algring)/R;
1001    p_Normalize(y->z,nacRing);
1002    G=convSingPFactoryP(y->z,r->algring)/R;
1003    F = gcd( F, G );
1004    if (F.isOne())
1005      result->z= rz;
1006    else
1007    {
1008      p_Delete(&rz,r->algring);
1009      result->z=convFactoryPSingP( F*R,r->algring );
1010      p_Normalize(result->z,nacRing);
1011    }
1012  }
1013#endif
1014  naTest((number)result);
1015  return (number)result;
1016}
1017
1018
1019/*2
1020* ntNumbOfPar = 1:
1021* clears denominator         algebraic case;
1022* tries to simplify ratio    transcendental case;
1023*
1024* cancels monomials
1025* occuring in denominator
1026* and enumerator  ?          ntNumbOfPar != 1;
1027*
1028* #defines for Factory:
1029* FACTORY_GCD_TEST: do not apply built in gcd for
1030*   univariate polynomials, always use Factory
1031*/
1032//#define FACTORY_GCD_TEST
1033void naCoefNormalize(number pp)
1034{
1035  if (pp==NULL) return;
1036  lnumber p = (lnumber)pp;
1037  number nz; // all denom. of the numerator
1038  nz=p_GetAllDenom(p->z,nacRing);
1039  BOOLEAN norm=FALSE;
1040  if (!n_IsOne(nz,nacRing))
1041  {
1042    norm=TRUE;
1043    p->z=p_Mult_nn(p->z,nz,nacRing);
1044    if (p->n==NULL)
1045    {
1046      p->n=p_NSet(nz,nacRing);
1047    }
1048    else
1049    {
1050      p->n=p_Mult_nn(p->n,nz,nacRing);
1051      n_Delete(&nz, nacRing);
1052    }
1053  }
1054  else
1055  {
1056    n_Delete(&nz, nacRing);
1057  }
1058  if (norm)
1059  {
1060    norm=FALSE;
1061    p_Normalize(p->z,nacRing);
1062    p_Normalize(p->n,nacRing);
1063  }
1064  number nn;
1065  nn=p_GetAllDenom(p->n,nacRing);
1066  if (!n_IsOne(nn,nacRing))
1067  {
1068    norm=TRUE;
1069    p->n=p_Mult_nn(p->n,nn,nacRing);
1070    p->z=p_Mult_nn(p->z,nn,nacRing);
1071    n_Delete(&nn, nacRing);
1072  }
1073  else
1074  {
1075    n_Delete(&nn, nacRing);
1076  }
1077  if (norm)
1078  {
1079    p_Normalize(p->z,nacRing);
1080    p_Normalize(p->n,nacRing);
1081  }
1082  // remove common factors in n, z:
1083  if (p->n!=NULL)
1084  {
1085    poly pp=p->z;
1086    nz=n_Copy(pGetCoeff(pp),nacRing);
1087    pIter(pp);
1088    while(pp!=NULL)
1089    {
1090      if (n_IsOne(nz,nacRing)) break;
1091      number d=n_Gcd(nz,pGetCoeff(pp),nacRing);
1092      n_Delete(&nz,nacRing); nz=d;
1093      pIter(pp);
1094    }
1095    if (!n_IsOne(nz,nacRing))
1096    {
1097      pp=p->n;
1098      nn=n_Copy(pGetCoeff(pp),nacRing);
1099      pIter(pp);
1100      while(pp!=NULL)
1101      {
1102        if (n_IsOne(nn,nacRing)) break;
1103        number d=n_Gcd(nn,pGetCoeff(pp),nacRing);
1104        n_Delete(&nn,nacRing); nn=d;
1105        pIter(pp);
1106      }
1107      number ng=n_Gcd(nz,nn,nacRing);
1108      n_Delete(&nn,nacRing);
1109      if (!n_IsOne(ng,nacRing))
1110      {
1111        number ni=n_Invers(ng,nacRing);
1112        p->z=p_Mult_nn(p->z,ni,nacRing);
1113        p->n=p_Mult_nn(p->n,ni,nacRing);
1114        p_Normalize(p->z,nacRing);
1115        p_Normalize(p->n,nacRing);
1116        n_Delete(&ni,nacRing);
1117      }
1118      n_Delete(&ng,nacRing);
1119    }
1120    n_Delete(&nz,nacRing);
1121  }
1122  if (p->n!=NULL)
1123  {
1124    if(!nacGreaterZero(pGetCoeff(p->n)))
1125    {
1126      p->z=napNeg(p->z);
1127      p->n=napNeg(p->n);
1128    }
1129
1130    if (/*(p->n!=NULL) && */
1131    (p_IsConstant(p->n,nacRing))
1132    && (n_IsOne(pGetCoeff(p->n),nacRing)))
1133    {
1134      p_Delete(&(p->n), nacRing);
1135      p->n = NULL;
1136    }
1137  }
1138}
1139
1140void naNormalize(number &pp)
1141{
1142
1143  //naTest(pp); // input may not be "normal"
1144  lnumber p = (lnumber)pp;
1145
1146  if (p==NULL)
1147    return;
1148  naCoefNormalize(pp);
1149  p->s = 2;
1150  napoly x = p->z;
1151  napoly y = p->n;
1152
1153  BOOLEAN norm=FALSE;
1154
1155  if ((y!=NULL) && (naMinimalPoly!=NULL))
1156  {
1157    y = napInvers(y, naMinimalPoly);
1158    x = p_Mult_q(x, y,nacRing);
1159    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1160      x = napRemainder(x, naMinimalPoly);
1161    p->z = x;
1162    p->n = y = NULL;
1163    norm=ntIsChar0;
1164  }
1165
1166  /* check for degree of x too high: */
1167  if ((x!=NULL) && (naMinimalPoly!=NULL) && (x!=naMinimalPoly)
1168  && (p_GetExp(x,1,nacRing)>p_GetExp(naMinimalPoly,1,nacRing)))
1169  // DO NOT REDUCE naMinimalPoly with itself
1170  {
1171    x = napRemainder(x, naMinimalPoly);
1172    p->z = x;
1173    norm=ntIsChar0;
1174  }
1175  /* normalize all coefficients in n and z (if in Q) */
1176  if (norm) 
1177  {
1178    naCoefNormalize(pp);
1179    x = p->z;
1180    y = p->n;
1181  }
1182  if (y==NULL) return;
1183
1184  if ((naMinimalPoly == NULL) && (x!=NULL) && (y!=NULL))
1185  {
1186    int i;
1187    for (i=ntNumbOfPar-1; i>=0; i--)
1188    {
1189      napoly xx=x;
1190      napoly yy=y;
1191      int m = napExpi(i, yy, xx);
1192      if (m != 0)          // in this case xx!=NULL!=yy
1193      {
1194        while (xx != NULL)
1195        {
1196          napAddExp(xx,i+1, -m);
1197          pIter(xx);
1198        }
1199        while (yy != NULL)
1200        {
1201          napAddExp(yy,i+1, -m);
1202          pIter(yy);
1203        }
1204      }
1205    }
1206  }
1207  if (p_LmIsConstant(y,nacRing)) /* i.e. => simplify to (1/c)*z / monom */
1208  {
1209    if (nacIsOne(pGetCoeff(y)))
1210    {
1211      p_LmDelete(&y,nacRing);
1212      p->n = NULL;
1213      naTest(pp);
1214      return;
1215    }
1216    number h1 = nacInvers(pGetCoeff(y));
1217    nacNormalize(h1);
1218    napMultN(x, h1);
1219    n_Delete(&h1,nacRing);
1220    p_LmDelete(&y,nacRing);
1221    p->n = NULL;
1222    naTest(pp);
1223    return;
1224  }
1225#ifndef FACTORY_GCD_TEST
1226  if (ntNumbOfPar == 1) /* apply built-in gcd */
1227  {
1228    napoly x1,y1;
1229    if (p_GetExp(x,1,nacRing) >= p_GetExp(y,1,nacRing))
1230    {
1231      x1 = napCopy(x);
1232      y1 = napCopy(y);
1233    }
1234    else
1235    {
1236      x1 = napCopy(y);
1237      y1 = napCopy(x);
1238    }
1239    napoly r;
1240    loop
1241    {
1242      r = napRemainder(x1, y1);
1243      if ((r==NULL) || (pNext(r)==NULL)) break;
1244      x1 = y1;
1245      y1 = r;
1246    }
1247    if (r!=NULL)
1248    {
1249      p_Delete(&r,nacRing);
1250      p_Delete(&y1,nacRing);
1251    }
1252    else
1253    {
1254      napDivMod(x, y1, &(p->z), &r);
1255      napDivMod(y, y1, &(p->n), &r);
1256      p_Delete(&y1,nacRing);
1257    }
1258    x = p->z;
1259    y = p->n;
1260    /* collect all denoms from y and multiply x and y by it */
1261    if (ntIsChar0)
1262    {
1263      number n=napLcm(y);
1264      napMultN(x,n);
1265      napMultN(y,n);
1266      n_Delete(&n,nacRing);
1267      while(x!=NULL)
1268      {
1269        nacNormalize(pGetCoeff(x));
1270        pIter(x);
1271      }
1272      x = p->z;
1273      while(y!=NULL)
1274      {
1275        nacNormalize(pGetCoeff(y));
1276        pIter(y);
1277      }
1278      y = p->n;
1279    }
1280    if (pNext(y)==NULL)
1281    {
1282      if (nacIsOne(pGetCoeff(y)))
1283      {
1284        if (p_GetExp(y,1,nacRing)==0)
1285        {
1286          p_LmDelete(&y,nacRing);
1287          p->n = NULL;
1288        }
1289        naTest(pp);
1290        return;
1291      }
1292    }
1293  }
1294#endif /* FACTORY_GCD_TEST */
1295#ifdef HAVE_FACTORY
1296#ifndef FACTORY_GCD_TEST
1297  else
1298#endif
1299  {
1300    napoly xx,yy;
1301    singclap_algdividecontent(x,y,xx,yy);
1302    if (xx!=NULL)
1303    {
1304      p->z=xx;
1305      p->n=yy;
1306      p_Delete(&x,nacRing);
1307      p_Delete(&y,nacRing);
1308    }
1309  }
1310#endif
1311  /* remove common factors from z and n */
1312  x=p->z;
1313  y=p->n;
1314  if(!nacGreaterZero(pGetCoeff(y)))
1315  {
1316    x=napNeg(x);
1317    y=napNeg(y);
1318  }
1319  number g=nacCopy(pGetCoeff(x));
1320  pIter(x);
1321  while (x!=NULL)
1322  {
1323    number d=nacGcd(g,pGetCoeff(x), nacRing);
1324    if(nacIsOne(d))
1325    {
1326      n_Delete(&g,nacRing);
1327      n_Delete(&d,nacRing);
1328      naTest(pp);
1329      return;
1330    }
1331    n_Delete(&g,nacRing);
1332    g = d;
1333    pIter(x);
1334  }
1335  while (y!=NULL)
1336  {
1337    number d=nacGcd(g,pGetCoeff(y), nacRing);
1338    if(nacIsOne(d))
1339    {
1340      n_Delete(&g,nacRing);
1341      n_Delete(&d,nacRing);
1342      naTest(pp);
1343      return;
1344    }
1345    n_Delete(&g,nacRing);
1346    g = d;
1347    pIter(y);
1348  }
1349  x=p->z;
1350  y=p->n;
1351  while (x!=NULL)
1352  {
1353    number d = nacIntDiv(pGetCoeff(x),g);
1354    napSetCoeff(x,d);
1355    pIter(x);
1356  }
1357  while (y!=NULL)
1358  {
1359    number d = nacIntDiv(pGetCoeff(y),g);
1360    napSetCoeff(y,d);
1361    pIter(y);
1362  }
1363  n_Delete(&g,nacRing);
1364  naTest(pp);
1365}
1366
1367/*2
1368* returns in result->n 1
1369* and in     result->z the lcm(a->z,b->n)
1370*/
1371number naLcm(number la, number lb, const ring r)
1372{
1373  lnumber result;
1374  lnumber a = (lnumber)la;
1375  lnumber b = (lnumber)lb;
1376  result = (lnumber)omAlloc0Bin(rnumber_bin);
1377  naTest(la);
1378  naTest(lb);
1379  napoly x = p_Copy(a->z, r->algring);
1380  number t = napLcm(b->z); // get all denom of b->z
1381  if (!nacIsOne(t))
1382  {
1383    number bt, rr;
1384    napoly xx=x;
1385    while (xx!=NULL)
1386    {
1387      bt = nacGcd(t, pGetCoeff(xx), r->algring);
1388      rr = nacMult(t, pGetCoeff(xx));
1389      n_Delete(&pGetCoeff(xx),r->algring);
1390      pGetCoeff(xx) = nacDiv(rr, bt);
1391      nacNormalize(pGetCoeff(xx));
1392      n_Delete(&bt,r->algring);
1393      n_Delete(&rr,r->algring);
1394      pIter(xx);
1395    }
1396  }
1397  n_Delete(&t,r->algring);
1398  result->z = x;
1399#ifdef HAVE_FACTORY
1400  if (b->n!=NULL)
1401  {
1402    result->z=singclap_alglcm(result->z,b->n);
1403    p_Delete(&x,r->algring);
1404  }
1405#endif
1406  naTest(la);
1407  naTest(lb);
1408  naTest((number)result);
1409  return ((number)result);
1410}
1411
1412/*2
1413* input: a set of constant polynomials
1414* sets the global variable naI
1415*/
1416void naSetIdeal(ideal I)
1417{
1418  int i;
1419
1420  if (idIs0(I))
1421  {
1422    for (i=naI->anz-1; i>=0; i--)
1423      p_Delete(&naI->liste[i],nacRing);
1424    omFreeBin((ADDRESS)naI, snaIdeal_bin);
1425    naI=NULL;
1426  }
1427  else
1428  {
1429    lnumber h;
1430    number a;
1431    napoly x;
1432
1433    naI=(naIdeal)omAllocBin(snaIdeal_bin);
1434    naI->anz=IDELEMS(I);
1435    naI->liste=(napoly*)omAlloc(naI->anz*sizeof(napoly));
1436    for (i=IDELEMS(I)-1; i>=0; i--)
1437    {
1438      h=(lnumber)pGetCoeff(I->m[i]);
1439      /* We only need the enumerator of h, as we expect it to be a polynomial */
1440      naI->liste[i]=napCopy(h->z);
1441      /* If it isn't normalized (lc = 1) do this */
1442      if (!nacIsOne(pGetCoeff(naI->liste[i])))
1443      {
1444        x=naI->liste[i];
1445        nacNormalize(pGetCoeff(x));
1446        a=nacCopy(pGetCoeff(x));
1447        number aa=nacInvers(a);
1448        n_Delete(&a,nacRing);
1449        napMultN(x,aa);
1450        n_Delete(&aa,nacRing);
1451      }
1452    }
1453  }
1454}
1455
1456/*2
1457* map Z/p -> Q(a)
1458*/
1459number naMapP0(number c)
1460{
1461  if (npIsZero(c)) return NULL;
1462  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1463  l->s=2;
1464  l->z=(napoly)p_Init(nacRing);
1465  int i=(int)((long)c);
1466  if (i>((long)ntMapRing->ch>>2)) i-=(long)ntMapRing->ch;
1467  pGetCoeff(l->z)=nlInit(i, nacRing);
1468  l->n=NULL;
1469  return (number)l;
1470}
1471
1472/*2
1473* map Q -> Q(a)
1474*/
1475number naMap00(number c)
1476{
1477  if (nlIsZero(c)) return NULL;
1478  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1479  l->s=0;
1480  l->z=(napoly)p_Init(nacRing);
1481  pGetCoeff(l->z)=nlCopy(c);
1482  l->n=NULL;
1483  return (number)l;
1484}
1485
1486/*2
1487* map Z/p -> Z/p(a)
1488*/
1489number naMapPP(number c)
1490{
1491  if (npIsZero(c)) return NULL;
1492  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1493  l->s=2;
1494  l->z=(napoly)p_Init(nacRing);
1495  pGetCoeff(l->z)=c; /* omit npCopy, because npCopy is a no-op */
1496  l->n=NULL;
1497  return (number)l;
1498}
1499
1500/*2
1501* map Z/p' -> Z/p(a)
1502*/
1503number naMapPP1(number c)
1504{
1505  if (npIsZero(c)) return NULL;
1506  int i=(int)((long)c);
1507  if (i>(long)ntMapRing->ch) i-=(long)ntMapRing->ch;
1508  number n=npInit(i,ntMapRing);
1509  if (npIsZero(n)) return NULL;
1510  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1511  l->s=2;
1512  l->z=(napoly)p_Init(nacRing);
1513  pGetCoeff(l->z)=n;
1514  l->n=NULL;
1515  return (number)l;
1516}
1517
1518/*2
1519* map Q -> Z/p(a)
1520*/
1521number naMap0P(number c)
1522{
1523  if (nlIsZero(c)) return NULL;
1524  number n=npInit(nlModP(c,npPrimeM),nacRing);
1525  if (npIsZero(n)) return NULL;
1526  npTest(n);
1527  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1528  l->s=2;
1529  l->z=(napoly)p_Init(nacRing);
1530  pGetCoeff(l->z)=n;
1531  l->n=NULL;
1532  return (number)l;
1533}
1534
1535/*2
1536* map _(a) -> _(b)
1537*/
1538number naMapQaQb(number c)
1539{
1540  if (c==NULL) return NULL;
1541  lnumber erg= (lnumber)omAlloc0Bin(rnumber_bin);
1542  lnumber src =(lnumber)c;
1543  erg->s=src->s;
1544  erg->z=napMap(src->z);
1545  erg->n=napMap(src->n);
1546  if (naMinimalPoly!=NULL)
1547  {
1548    if (p_GetExp(erg->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1549    {
1550      erg->z = napRemainder(erg->z, naMinimalPoly);
1551      if (erg->z==NULL)
1552      {
1553        number t_erg=(number)erg;
1554        naDelete(&t_erg,currRing);
1555        return (number)NULL;
1556      }
1557    }
1558    if (erg->n!=NULL)
1559    {
1560      if (p_GetExp(erg->n,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1561        erg->n = napRemainder(erg->n, naMinimalPoly);
1562      if ((p_IsConstant(erg->n,nacRing)) && nacIsOne(pGetCoeff(erg->n)))
1563        p_Delete(&(erg->n),nacRing);
1564    }
1565  }
1566  return (number)erg;
1567}
1568
1569nMapFunc naSetMap(const ring src, const ring dst)
1570{
1571  ntMapRing=src;
1572  if (rField_is_Q_a(dst)) /* -> Q(a) */
1573  {
1574    if (rField_is_Q(src))
1575    {
1576      return naMap00;   /*Q -> Q(a)*/
1577    }
1578    if (rField_is_Zp(src))
1579    {
1580      return naMapP0;  /* Z/p -> Q(a)*/
1581    }
1582    if (rField_is_Q_a(src))
1583    {
1584      int i;
1585      ntParsToCopy=0;
1586      for(i=0;i<rPar(src);i++)
1587      {
1588        if ((i>=rPar(dst))
1589        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
1590           return NULL;
1591        ntParsToCopy++;
1592      }
1593      nacMap=nacCopy;
1594      if ((ntParsToCopy==rPar(dst))&&(ntParsToCopy==rPar(src)))
1595        return naCopy;    /* Q(a) -> Q(a) */
1596      return naMapQaQb;   /* Q(a..) -> Q(a..) */
1597    }
1598  }
1599  /*-----------------------------------------------------*/
1600  if (rField_is_Zp_a(dst)) /* -> Z/p(a) */
1601  {
1602    if (rField_is_Q(src))
1603    {
1604      return naMap0P;   /*Q -> Z/p(a)*/
1605    }
1606    if (rField_is_Zp(src))
1607    {
1608      if (src->ch==dst->ch)
1609      {
1610        return naMapPP;  /* Z/p -> Z/p(a)*/
1611      }
1612      else
1613      {
1614        return naMapPP1;  /* Z/p' -> Z/p(a)*/
1615      }
1616    }
1617    if (rField_is_Zp_a(src))
1618    {
1619      if (rChar(src)==rChar(dst))
1620      {
1621        nacMap=nacCopy;
1622      }
1623      else
1624      {
1625        nacMap = npMapP;
1626      }
1627      int i;
1628      ntParsToCopy=0;
1629      for(i=0;i<rPar(src);i++)
1630      {
1631        if ((i>=rPar(dst))
1632        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
1633           return NULL;
1634        ntParsToCopy++;
1635      }
1636      if ((ntParsToCopy==rPar(dst))&&(ntParsToCopy==rPar(src))
1637      && (nacMap==nacCopy))
1638        return naCopy;    /* Z/p(a) -> Z/p(a) */
1639      return naMapQaQb;   /* Z/p(a),Z/p'(a) -> Z/p(b)*/
1640    }
1641  }
1642  return NULL;      /* default */
1643}
1644
1645#ifdef LDEBUG
1646BOOLEAN naDBTest(number a, const char *f,const int l)
1647{
1648  lnumber x=(lnumber)a;
1649  if (x == NULL)
1650    return TRUE;
1651  #ifdef LDEBUG
1652  omCheckAddrSize(a, sizeof(snumber));
1653  #endif
1654  napoly p = x->z;
1655  if (p==NULL)
1656  {
1657    Print("0/* in %s:%d\n",f,l);
1658    return FALSE;
1659  }
1660  while(p!=NULL)
1661  {
1662    if (( ntIsChar0  && nlIsZero(pGetCoeff(p)))
1663    || ((!ntIsChar0) && npIsZero(pGetCoeff(p))))
1664    {
1665      Print("coeff 0 in %s:%d\n",f,l);
1666      return FALSE;
1667    }
1668    if((naMinimalPoly!=NULL)
1669    &&(p_GetExp(p,1,nacRing)>p_GetExp(naMinimalPoly,1,nacRing))
1670    &&(p!=naMinimalPoly))
1671    {
1672      Print("deg>minpoly in %s:%d\n",f,l);
1673      return FALSE;
1674    }
1675    //if (ntIsChar0 && (((int)p->ko &3) == 0) && (p->ko->s==0) && (x->s==2))
1676    //{
1677    //  Print("normalized with non-normal coeffs in %s:%d\n",f,l);
1678    //  return FALSE;
1679    //}
1680    if (ntIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
1681      return FALSE;
1682    pIter(p);
1683  }
1684  p = x->n;
1685  while(p!=NULL)
1686  {
1687    if (ntIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
1688      return FALSE;
1689    pIter(p);
1690  }
1691  return TRUE;
1692}
1693#endif
Note: See TracBrowser for help on using the repository browser.