source: git/kernel/longalg.cc @ 5f3629

spielwiese
Last change on this file since 5f3629 was b5cd25f, checked in by Frank Seelisch <seelisch@…>, 13 years ago
bug fix for trac ticket #334 git-svn-id: file:///usr/local/Singular/svn/trunk@14234 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 34.3 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))   /* never occurs even when la or lb
432                                     represents zero??? */
433    return NULL;
434
435  lnumber a = (lnumber)la;
436  lnumber b = (lnumber)lb;
437  lnumber lo;
438  napoly x;
439
440  #ifdef LDEBUG
441  omCheckAddrSize(a,sizeof(snumber));
442  omCheckAddrSize(b,sizeof(snumber));
443  #endif
444  naTest(la);
445  naTest(lb);
446
447  lo = (lnumber)omAllocBin(rnumber_bin);
448  lo->z = pp_Mult_qq(a->z, b->z,nacRing);
449
450  if (a->n==NULL)
451  {
452    if (b->n==NULL)
453      x = NULL;
454    else
455      x = napCopy(b->n);
456  }
457  else
458  {
459    if (b->n==NULL)
460    {
461      x = napCopy(a->n);
462    }
463    else
464    {
465      x = pp_Mult_qq(b->n, a->n, nacRing);
466    }
467  }
468  if (naMinimalPoly!=NULL)
469  {
470    if ((lo->z != NULL) &&
471        (p_GetExp(lo->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing)))
472      lo->z = napRemainder(lo->z, naMinimalPoly);
473    if ((x!=NULL) &&
474        (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing)))
475      x = napRemainder(x, naMinimalPoly);
476  }
477  if (naI!=NULL)
478  {
479    lo->z = napRedp (lo->z);
480    if (lo->z != NULL)
481       lo->z = napTailred (lo->z);
482    if (x!=NULL)
483    {
484      x = napRedp (x);
485      if (x!=NULL)
486        x = napTailred (x);
487    }
488  }
489  if ((x!=NULL) && (p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
490    p_Delete(&x,nacRing);
491  lo->n = x;
492  lo->s = 0;
493  if(lo->z==NULL)
494  {
495    omFreeBin((ADDRESS)lo, rnumber_bin);
496    lo=NULL;
497  }
498  else if (lo->n!=NULL)
499  {
500    number luu=(number)lo;
501    // if (p_IsConstant(lo->n,nacRing)) naCoefNormalize(luu);
502    // else
503                      naNormalize(luu);
504    lo=(lnumber)luu;
505  }
506  //if (naMinimalPoly==NULL) lo->s=2;
507  naTest((number)lo);
508  return (number)lo;
509}
510
511number naIntDiv(number la, number lb)
512{
513  lnumber res;
514  lnumber a = (lnumber)la;
515  lnumber b = (lnumber)lb;
516  if (a==NULL)
517  {
518    return NULL;
519  }
520  if (b==NULL)
521  {
522    WerrorS(nDivBy0);
523    return NULL;
524  }
525  assume(a->z!=NULL && b->z!=NULL);
526  assume(a->n==NULL && b->n==NULL);
527  res = (lnumber)omAllocBin(rnumber_bin);
528  res->z = napCopy(a->z);
529  res->n = napCopy(b->z);
530  res->s = 0;
531  number nres=(number)res;
532  naNormalize(nres);
533
534  //napDelete(&res->n);
535  naTest(nres);
536  return nres;
537}
538
539/*2
540*  division; lo:= la / lb
541*/
542number naDiv(number la, number lb)
543{
544  lnumber lo;
545  lnumber a = (lnumber)la;
546  lnumber b = (lnumber)lb;
547  napoly x;
548
549  if (a==NULL)
550    return NULL;
551
552  if (b==NULL)
553  {
554    WerrorS(nDivBy0);
555    return NULL;
556  }
557  #ifdef LDEBUG
558  omCheckAddrSize(a,sizeof(snumber));
559  omCheckAddrSize(b,sizeof(snumber));
560  #endif
561  lo = (lnumber)omAllocBin(rnumber_bin);
562  if (b->n!=NULL)
563    lo->z = pp_Mult_qq(a->z, b->n,nacRing);
564  else
565    lo->z = napCopy(a->z);
566  if (a->n!=NULL)
567    x = pp_Mult_qq(b->z, a->n, nacRing);
568  else
569    x = napCopy(b->z);
570  if (naMinimalPoly!=NULL)
571  {
572    if (p_GetExp(lo->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
573      lo->z = napRemainder(lo->z, naMinimalPoly);
574    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
575      x = napRemainder(x, naMinimalPoly);
576  }
577  if (naI!=NULL)
578  {
579    lo->z = napRedp (lo->z);
580    if (lo->z != NULL)
581       lo->z = napTailred (lo->z);
582    if (x!=NULL)
583    {
584      x = napRedp (x);
585      if (x!=NULL)
586        x = napTailred (x);
587    }
588  }
589  if ((p_LmIsConstant(x,nacRing)) && nacIsOne(pGetCoeff(x)))
590    p_Delete(&x,nacRing);
591  lo->n = x;
592  lo->s = 0;
593  if (lo->n!=NULL)
594  {
595    number luu=(number)lo;
596     //if (p_IsConstant(lo->n,nacRing)) naCoefNormalize(luu);
597     //else
598                         naNormalize(luu);
599    lo=(lnumber)luu;
600  }
601  //else lo->s=2;
602  naTest((number)lo);
603  return (number)lo;
604}
605
606/*2
607*  za:= - za, inplace
608*/
609number naNeg(number za)
610{
611  if (za!=NULL)
612  {
613    lnumber e = (lnumber)za;
614    naTest(za);
615    e->z = napNeg(e->z);
616  }
617  return za;
618}
619
620/*2
621* 1/a
622*/
623number naInvers(number a)
624{
625  lnumber lo;
626  lnumber b = (lnumber)a;
627  napoly x;
628
629  if (b==NULL)
630  {
631    WerrorS(nDivBy0);
632    return NULL;
633  }
634  #ifdef LDEBUG
635  omCheckAddrSize(b,sizeof(snumber));
636  #endif
637  lo = (lnumber)omAlloc0Bin(rnumber_bin);
638  lo->s = b->s;
639  if (b->n!=NULL)
640    lo->z = napCopy(b->n);
641  else
642    lo->z = p_ISet(1,nacRing);
643  x = b->z;
644  if ((!p_LmIsConstant(x,nacRing)) || !nacIsOne(pGetCoeff(x)))
645    x = napCopy(x);
646  else
647  {
648    lo->n = NULL;
649    naTest((number)lo);
650    return (number)lo;
651  }
652  if (naMinimalPoly!=NULL)
653  {
654    x = napInvers(x, naMinimalPoly);
655    x = p_Mult_q(x, lo->z,nacRing);
656    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
657      x = napRemainder(x, naMinimalPoly);
658    lo->z = x;
659    lo->n = NULL;
660    while (x!=NULL)
661    {
662      nacNormalize(pGetCoeff(x));
663      pIter(x);
664    }
665  }
666  else
667    lo->n = x;
668  if (lo->n!=NULL)
669  {
670     number luu=(number)lo;
671     //if (p_IsConstant(lo->n,nacRing)) naCoefNormalize(luu);
672     //else
673                           naNormalize(luu);
674     lo=(lnumber)luu;
675  }
676  naTest((number)lo);
677  return (number)lo;
678}
679
680
681BOOLEAN naIsZero(number za)
682{
683  lnumber zb = (lnumber)za;
684  naTest(za);
685#ifdef LDEBUG
686  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(2)");
687#endif
688  return (zb==NULL);
689}
690
691
692BOOLEAN naGreaterZero(number za)
693{
694  lnumber zb = (lnumber)za;
695#ifdef LDEBUG
696  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(3)");
697#endif
698  naTest(za);
699  if (zb!=NULL)
700  {
701    return (nacGreaterZero(pGetCoeff(zb->z))||(!p_LmIsConstant(zb->z,nacRing)));
702  }
703  /* else */ return FALSE;
704}
705
706
707/*2
708* a = b ?
709*/
710BOOLEAN naEqual (number a, number b)
711{
712  if(a==b) return TRUE;
713  if((a==NULL)&&(b!=NULL)) return FALSE;
714  if((b==NULL)&&(a!=NULL)) return FALSE;
715
716  lnumber aa=(lnumber)a;
717  lnumber bb=(lnumber)b;
718
719  int an_deg=0;
720  if(aa->n!=NULL)
721    an_deg=napDeg(aa->n);
722  int bn_deg=0;
723  if(bb->n!=NULL)
724    bn_deg=napDeg(bb->n);
725  if(an_deg+napDeg(bb->z)!=bn_deg+napDeg(aa->z))
726    return FALSE;
727#if 0
728  naNormalize(a);
729  aa=(lnumber)a;
730  naNormalize(b);
731  bb=(lnumber)b;
732  if((aa->n==NULL)&&(bb->n!=NULL)) return FALSE;
733  if((bb->n==NULL)&&(aa->n!=NULL)) return FALSE;
734  if(napComp(aa->z,bb->z)!=0) return FALSE;
735  if((aa->n!=NULL) && (napComp(aa->n,bb->n))) return FALSE;
736#endif
737  number h = naSub(a, b);
738  BOOLEAN bo = naIsZero(h);
739  naDelete(&h,currRing);
740  return bo;
741}
742
743
744/* This method will only consider the numerators of a and b.
745   Moreover it may return TRUE only if one or both numerators
746   are zero or if their degrees are equal. Then TRUE is returned iff
747   coeff(numerator(a)) > coeff(numerator(b));
748   In all other cases, FALSE will be returned. */
749BOOLEAN naGreater (number a, number b)
750{
751  int az = 0; int ad = 0;
752  if (naIsZero(a)) az = 1;
753  else ad = napDeg(((lnumber)a)->z);
754  int bz = 0; int bd = 0;
755  if (naIsZero(b)) bz = 1;
756  else bd = napDeg(((lnumber)b)->z);
757 
758  if ((az == 1) && (bz == 1)) /* a = b = 0 */ return FALSE;
759  if (az == 1) /* a = 0, b != 0 */
760  {
761    return (!nacGreaterZero(pGetCoeff(((lnumber)b)->z)));
762  }
763  if (bz == 1) /* a != 0, b = 0 */
764  {
765    return (nacGreaterZero(pGetCoeff(((lnumber)a)->z)));
766  }
767  if (ad == bd) 
768    return nacGreater(pGetCoeff(((lnumber)a)->z),
769                      pGetCoeff(((lnumber)b)->z));
770  return FALSE;
771}
772
773/*2
774* reads a number
775*/
776const char  *naRead(const char *s, number *p)
777{
778  napoly x;
779  lnumber a;
780  s = napRead(s, &x);
781  if (x==NULL)
782  {
783    *p = NULL;
784    return s;
785  }
786  *p = (number)omAlloc0Bin(rnumber_bin);
787  a = (lnumber)*p;
788  if ((naMinimalPoly!=NULL)
789  && (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing)))
790    a->z = napRemainder(x, naMinimalPoly);
791  else if (naI!=NULL)
792  {
793    a->z = napRedp(x);
794    if (a->z != NULL)
795      a->z = napTailred (a->z);
796  }
797  else
798    a->z = x;
799  if(a->z==NULL)
800  {
801    omFreeBin((ADDRESS)*p, rnumber_bin);
802    *p=NULL;
803  }
804  else
805  {
806    a->n = NULL;
807    a->s = 0;
808    naTest(*p);
809  }
810  return s;
811}
812
813/*2
814* tries to convert a number to a name
815*/
816char * naName(number n)
817{
818  lnumber ph = (lnumber)n;
819  if (ph==NULL)
820    return NULL;
821  int i;
822  char *s=(char *)omAlloc(4* ntNumbOfPar);
823  char *t=(char *)omAlloc(8);
824  s[0]='\0';
825  for (i = 0; i <= ntNumbOfPar - 1; i++)
826  {
827    int e=p_GetExp(ph->z,i+1,nacRing);
828    if (e > 0)
829    {
830      if (e >1)
831      {
832        sprintf(t,"%s%d",ntParNames[i],e);
833        strcat(s,t);
834      }
835      else
836      {
837        strcat(s,ntParNames[i]);
838      }
839    }
840  }
841  omFreeSize((ADDRESS)t,8);
842  if (s[0]=='\0')
843  {
844    omFree((ADDRESS)s);
845    return NULL;
846  }
847  return s;
848}
849
850/*2
851*  writes a number
852*/
853void naWrite(number &phn, const ring r)
854{
855  lnumber ph = (lnumber)phn;
856  if (ph==NULL)
857    StringAppendS("0");
858  else
859  {
860    phn->s = 0;
861    BOOLEAN has_denom=(ph->n!=NULL);
862    napWrite(ph->z,has_denom/*(ph->n!=NULL)*/,r);
863    if (has_denom/*(ph->n!=NULL)*/)
864    {
865      StringAppendS("/");
866      napWrite(ph->n,TRUE,r);
867    }
868  }
869}
870
871/*2
872* za == 1 ?
873*/
874BOOLEAN naIsOne(number za)
875{
876  lnumber a = (lnumber)za;
877  napoly x, y;
878  number t;
879  if (a==NULL) return FALSE;
880#ifdef LDEBUG
881  omCheckAddrSize(a,sizeof(snumber));
882  if (a->z==NULL)
883  {
884    WerrorS("internal zero error(4)");
885    return FALSE;
886  }
887#endif
888  if (a->n==NULL)
889  {
890    if (p_LmIsConstant(a->z,nacRing))
891    {
892      return nacIsOne(pGetCoeff(a->z));
893    }
894    else                 return FALSE;
895  }
896#if 0
897  x = a->z;
898  y = a->n;
899  do
900  {
901    if (napComp(x, y))
902      return FALSE;
903    else
904    {
905      t = nacSub(pGetCoeff(x), pGetCoeff(y));
906      if (!nacIsZero(t))
907      {
908        n_Delete(&t,nacRing);
909        return FALSE;
910      }
911      else
912        n_Delete(&t,nacRing);
913    }
914    pIter(x);
915    pIter(y);
916  }
917  while ((x!=NULL) && (y!=NULL));
918  if ((x!=NULL) || (y!=NULL)) return FALSE;
919  p_Delete(&a->z,nacRing);
920  p_Delete(&a->n,nacRing);
921  a->z = p_ISet(1,nacRing);
922  a->n = NULL;
923  return TRUE;
924#else
925  return FALSE;
926#endif
927}
928
929/*2
930* za == -1 ?
931*/
932BOOLEAN naIsMOne(number za)
933{
934  lnumber a = (lnumber)za;
935  napoly x, y;
936  number t;
937  if (a==NULL) return FALSE;
938#ifdef LDEBUG
939  omCheckAddrSize(a,sizeof(snumber));
940  if (a->z==NULL)
941  {
942    WerrorS("internal zero error(5)");
943    return FALSE;
944  }
945#endif
946  if (a->n==NULL)
947  {
948    if (p_LmIsConstant(a->z,nacRing)) return n_IsMOne(pGetCoeff(a->z),nacRing);
949    /*else                   return FALSE;*/
950  }
951  return FALSE;
952}
953
954/*2
955* returns the i-th power of p (i>=0)
956*/
957void naPower(number p, int i, number *rc)
958{
959  number x;
960  *rc = naInit(1,currRing);
961  for (; i > 0; i--)
962  {
963    x = naMult(*rc, p);
964    naDelete(rc,currRing);
965    *rc = x;
966  }
967}
968
969/*2
970* result =gcd(a,b)
971*/
972number naGcd(number a, number b, const ring r)
973{
974  if (a==NULL)  return naCopy(b);
975  if (b==NULL)  return naCopy(a);
976
977  lnumber x, y;
978  lnumber result = (lnumber)omAlloc0Bin(rnumber_bin);
979
980  x = (lnumber)a;
981  y = (lnumber)b;
982  if ((ntNumbOfPar == 1) && (naMinimalPoly!=NULL))
983  {
984    if (pNext(x->z)!=NULL)
985      result->z = p_Copy(x->z, r->algring);
986    else
987      result->z = napGcd0(x->z, y->z);
988  }
989  else
990#ifndef HAVE_FACTORY
991    result->z = napGcd(x->z, y->z); // change from napGcd0
992#else
993  {
994    int c=ABS(nGetChar());
995    if (c==1) c=0;
996    setCharacteristic( c );
997
998    napoly rz=napGcd(x->z, y->z);
999    CanonicalForm F, G, R;
1000    R=convSingPFactoryP(rz,r->algring);
1001    p_Normalize(x->z,nacRing);
1002    F=convSingPFactoryP(x->z,r->algring)/R;
1003    p_Normalize(y->z,nacRing);
1004    G=convSingPFactoryP(y->z,r->algring)/R;
1005    F = gcd( F, G );
1006    if (F.isOne())
1007      result->z= rz;
1008    else
1009    {
1010      p_Delete(&rz,r->algring);
1011      result->z=convFactoryPSingP( F*R,r->algring );
1012      p_Normalize(result->z,nacRing);
1013    }
1014  }
1015#endif
1016  naTest((number)result);
1017  return (number)result;
1018}
1019
1020
1021/*2
1022* ntNumbOfPar = 1:
1023* clears denominator         algebraic case;
1024* tries to simplify ratio    transcendental case;
1025*
1026* cancels monomials
1027* occuring in denominator
1028* and enumerator  ?          ntNumbOfPar != 1;
1029*
1030* #defines for Factory:
1031* FACTORY_GCD_TEST: do not apply built in gcd for
1032*   univariate polynomials, always use Factory
1033*/
1034//#define FACTORY_GCD_TEST
1035void naCoefNormalize(number pp)
1036{
1037  if (pp==NULL) return;
1038  lnumber p = (lnumber)pp;
1039  number nz; // all denom. of the numerator
1040  nz=p_GetAllDenom(p->z,nacRing);
1041  BOOLEAN norm=FALSE;
1042  if (!n_IsOne(nz,nacRing))
1043  {
1044    norm=TRUE;
1045    p->z=p_Mult_nn(p->z,nz,nacRing);
1046    if (p->n==NULL)
1047    {
1048      p->n=p_NSet(nz,nacRing);
1049    }
1050    else
1051    {
1052      p->n=p_Mult_nn(p->n,nz,nacRing);
1053      n_Delete(&nz, nacRing);
1054    }
1055  }
1056  else
1057  {
1058    n_Delete(&nz, nacRing);
1059  }
1060  if (norm)
1061  {
1062    norm=FALSE;
1063    p_Normalize(p->z,nacRing);
1064    p_Normalize(p->n,nacRing);
1065  }
1066  number nn;
1067  nn=p_GetAllDenom(p->n,nacRing);
1068  if (!n_IsOne(nn,nacRing))
1069  {
1070    norm=TRUE;
1071    p->n=p_Mult_nn(p->n,nn,nacRing);
1072    p->z=p_Mult_nn(p->z,nn,nacRing);
1073    n_Delete(&nn, nacRing);
1074  }
1075  else
1076  {
1077    n_Delete(&nn, nacRing);
1078  }
1079  if (norm)
1080  {
1081    p_Normalize(p->z,nacRing);
1082    p_Normalize(p->n,nacRing);
1083  }
1084  // remove common factors in n, z:
1085  if (p->n!=NULL)
1086  {
1087    poly pp=p->z;
1088    nz=n_Copy(pGetCoeff(pp),nacRing);
1089    pIter(pp);
1090    while(pp!=NULL)
1091    {
1092      if (n_IsOne(nz,nacRing)) break;
1093      number d=n_Gcd(nz,pGetCoeff(pp),nacRing);
1094      n_Delete(&nz,nacRing); nz=d;
1095      pIter(pp);
1096    }
1097    if (!n_IsOne(nz,nacRing))
1098    {
1099      pp=p->n;
1100      nn=n_Copy(pGetCoeff(pp),nacRing);
1101      pIter(pp);
1102      while(pp!=NULL)
1103      {
1104        if (n_IsOne(nn,nacRing)) break;
1105        number d=n_Gcd(nn,pGetCoeff(pp),nacRing);
1106        n_Delete(&nn,nacRing); nn=d;
1107        pIter(pp);
1108      }
1109      number ng=n_Gcd(nz,nn,nacRing);
1110      n_Delete(&nn,nacRing);
1111      if (!n_IsOne(ng,nacRing))
1112      {
1113        number ni=n_Invers(ng,nacRing);
1114        p->z=p_Mult_nn(p->z,ni,nacRing);
1115        p->n=p_Mult_nn(p->n,ni,nacRing);
1116        p_Normalize(p->z,nacRing);
1117        p_Normalize(p->n,nacRing);
1118        n_Delete(&ni,nacRing);
1119      }
1120      n_Delete(&ng,nacRing);
1121    }
1122    n_Delete(&nz,nacRing);
1123  }
1124  if (p->n!=NULL)
1125  {
1126    if(!nacGreaterZero(pGetCoeff(p->n)))
1127    {
1128      p->z=napNeg(p->z);
1129      p->n=napNeg(p->n);
1130    }
1131
1132    if (/*(p->n!=NULL) && */
1133    (p_IsConstant(p->n,nacRing))
1134    && (n_IsOne(pGetCoeff(p->n),nacRing)))
1135    {
1136      p_Delete(&(p->n), nacRing);
1137      p->n = NULL;
1138    }
1139  }
1140}
1141
1142void naNormalize(number &pp)
1143{
1144
1145  //naTest(pp); // input may not be "normal"
1146  lnumber p = (lnumber)pp;
1147
1148  if (p==NULL)
1149    return;
1150  naCoefNormalize(pp);
1151  p->s = 2;
1152  napoly x = p->z;
1153  napoly y = p->n;
1154
1155  BOOLEAN norm=FALSE;
1156
1157  if ((y!=NULL) && (naMinimalPoly!=NULL))
1158  {
1159    y = napInvers(y, naMinimalPoly);
1160    x = p_Mult_q(x, y,nacRing);
1161    if (p_GetExp(x,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1162      x = napRemainder(x, naMinimalPoly);
1163    p->z = x;
1164    p->n = y = NULL;
1165    norm=ntIsChar0;
1166  }
1167
1168  /* check for degree of x too high: */
1169  if ((x!=NULL) && (naMinimalPoly!=NULL) && (x!=naMinimalPoly)
1170  && (p_GetExp(x,1,nacRing)>p_GetExp(naMinimalPoly,1,nacRing)))
1171  // DO NOT REDUCE naMinimalPoly with itself
1172  {
1173    x = napRemainder(x, naMinimalPoly);
1174    p->z = x;
1175    norm=ntIsChar0;
1176  }
1177  /* normalize all coefficients in n and z (if in Q) */
1178  if (norm) 
1179  {
1180    naCoefNormalize(pp);
1181    x = p->z;
1182    y = p->n;
1183  }
1184  if (y==NULL) return;
1185
1186  if ((naMinimalPoly == NULL) && (x!=NULL) && (y!=NULL))
1187  {
1188    int i;
1189    for (i=ntNumbOfPar-1; i>=0; i--)
1190    {
1191      napoly xx=x;
1192      napoly yy=y;
1193      int m = napExpi(i, yy, xx);
1194      if (m != 0)          // in this case xx!=NULL!=yy
1195      {
1196        while (xx != NULL)
1197        {
1198          napAddExp(xx,i+1, -m);
1199          pIter(xx);
1200        }
1201        while (yy != NULL)
1202        {
1203          napAddExp(yy,i+1, -m);
1204          pIter(yy);
1205        }
1206      }
1207    }
1208  }
1209  if (p_LmIsConstant(y,nacRing)) /* i.e. => simplify to (1/c)*z / monom */
1210  {
1211    if (nacIsOne(pGetCoeff(y)))
1212    {
1213      p_LmDelete(&y,nacRing);
1214      p->n = NULL;
1215      naTest(pp);
1216      return;
1217    }
1218    number h1 = nacInvers(pGetCoeff(y));
1219    nacNormalize(h1);
1220    napMultN(x, h1);
1221    n_Delete(&h1,nacRing);
1222    p_LmDelete(&y,nacRing);
1223    p->n = NULL;
1224    naTest(pp);
1225    return;
1226  }
1227#ifndef FACTORY_GCD_TEST
1228  if (ntNumbOfPar == 1) /* apply built-in gcd */
1229  {
1230    napoly x1,y1;
1231    if (p_GetExp(x,1,nacRing) >= p_GetExp(y,1,nacRing))
1232    {
1233      x1 = napCopy(x);
1234      y1 = napCopy(y);
1235    }
1236    else
1237    {
1238      x1 = napCopy(y);
1239      y1 = napCopy(x);
1240    }
1241    napoly r;
1242    loop
1243    {
1244      r = napRemainder(x1, y1);
1245      if ((r==NULL) || (pNext(r)==NULL)) break;
1246      x1 = y1;
1247      y1 = r;
1248    }
1249    if (r!=NULL)
1250    {
1251      p_Delete(&r,nacRing);
1252      p_Delete(&y1,nacRing);
1253    }
1254    else
1255    {
1256      napDivMod(x, y1, &(p->z), &r);
1257      napDivMod(y, y1, &(p->n), &r);
1258      p_Delete(&y1,nacRing);
1259    }
1260    x = p->z;
1261    y = p->n;
1262    /* collect all denoms from y and multiply x and y by it */
1263    if (ntIsChar0)
1264    {
1265      number n=napLcm(y);
1266      napMultN(x,n);
1267      napMultN(y,n);
1268      n_Delete(&n,nacRing);
1269      while(x!=NULL)
1270      {
1271        nacNormalize(pGetCoeff(x));
1272        pIter(x);
1273      }
1274      x = p->z;
1275      while(y!=NULL)
1276      {
1277        nacNormalize(pGetCoeff(y));
1278        pIter(y);
1279      }
1280      y = p->n;
1281    }
1282    if (pNext(y)==NULL)
1283    {
1284      if (nacIsOne(pGetCoeff(y)))
1285      {
1286        if (p_GetExp(y,1,nacRing)==0)
1287        {
1288          p_LmDelete(&y,nacRing);
1289          p->n = NULL;
1290        }
1291        naTest(pp);
1292        return;
1293      }
1294    }
1295  }
1296#endif /* FACTORY_GCD_TEST */
1297#ifdef HAVE_FACTORY
1298#ifndef FACTORY_GCD_TEST
1299  else
1300#endif
1301  {
1302    napoly xx,yy;
1303    singclap_algdividecontent(x,y,xx,yy);
1304    if (xx!=NULL)
1305    {
1306      p->z=xx;
1307      p->n=yy;
1308      p_Delete(&x,nacRing);
1309      p_Delete(&y,nacRing);
1310    }
1311  }
1312#endif
1313  /* remove common factors from z and n */
1314  x=p->z;
1315  y=p->n;
1316  if(!nacGreaterZero(pGetCoeff(y)))
1317  {
1318    x=napNeg(x);
1319    y=napNeg(y);
1320  }
1321  number g=nacCopy(pGetCoeff(x));
1322  pIter(x);
1323  while (x!=NULL)
1324  {
1325    number d=nacGcd(g,pGetCoeff(x), nacRing);
1326    if(nacIsOne(d))
1327    {
1328      n_Delete(&g,nacRing);
1329      n_Delete(&d,nacRing);
1330      naTest(pp);
1331      return;
1332    }
1333    n_Delete(&g,nacRing);
1334    g = d;
1335    pIter(x);
1336  }
1337  while (y!=NULL)
1338  {
1339    number d=nacGcd(g,pGetCoeff(y), nacRing);
1340    if(nacIsOne(d))
1341    {
1342      n_Delete(&g,nacRing);
1343      n_Delete(&d,nacRing);
1344      naTest(pp);
1345      return;
1346    }
1347    n_Delete(&g,nacRing);
1348    g = d;
1349    pIter(y);
1350  }
1351  x=p->z;
1352  y=p->n;
1353  while (x!=NULL)
1354  {
1355    number d = nacIntDiv(pGetCoeff(x),g);
1356    napSetCoeff(x,d);
1357    pIter(x);
1358  }
1359  while (y!=NULL)
1360  {
1361    number d = nacIntDiv(pGetCoeff(y),g);
1362    napSetCoeff(y,d);
1363    pIter(y);
1364  }
1365  n_Delete(&g,nacRing);
1366  naTest(pp);
1367}
1368
1369/*2
1370* returns in result->n 1
1371* and in     result->z the lcm(a->z,b->n)
1372*/
1373number naLcm(number la, number lb, const ring r)
1374{
1375  lnumber result;
1376  lnumber a = (lnumber)la;
1377  lnumber b = (lnumber)lb;
1378  result = (lnumber)omAlloc0Bin(rnumber_bin);
1379  naTest(la);
1380  naTest(lb);
1381  napoly x = p_Copy(a->z, r->algring);
1382  number t = napLcm(b->z); // get all denom of b->z
1383  if (!nacIsOne(t))
1384  {
1385    number bt, rr;
1386    napoly xx=x;
1387    while (xx!=NULL)
1388    {
1389      bt = nacGcd(t, pGetCoeff(xx), r->algring);
1390      rr = nacMult(t, pGetCoeff(xx));
1391      n_Delete(&pGetCoeff(xx),r->algring);
1392      pGetCoeff(xx) = nacDiv(rr, bt);
1393      nacNormalize(pGetCoeff(xx));
1394      n_Delete(&bt,r->algring);
1395      n_Delete(&rr,r->algring);
1396      pIter(xx);
1397    }
1398  }
1399  n_Delete(&t,r->algring);
1400  result->z = x;
1401#ifdef HAVE_FACTORY
1402  if (b->n!=NULL)
1403  {
1404    result->z=singclap_alglcm(result->z,b->n);
1405    p_Delete(&x,r->algring);
1406  }
1407#endif
1408  naTest(la);
1409  naTest(lb);
1410  naTest((number)result);
1411  return ((number)result);
1412}
1413
1414/*2
1415* input: a set of constant polynomials
1416* sets the global variable naI
1417*/
1418void naSetIdeal(ideal I)
1419{
1420  int i;
1421
1422  if (idIs0(I))
1423  {
1424    for (i=naI->anz-1; i>=0; i--)
1425      p_Delete(&naI->liste[i],nacRing);
1426    omFreeBin((ADDRESS)naI, snaIdeal_bin);
1427    naI=NULL;
1428  }
1429  else
1430  {
1431    lnumber h;
1432    number a;
1433    napoly x;
1434
1435    naI=(naIdeal)omAllocBin(snaIdeal_bin);
1436    naI->anz=IDELEMS(I);
1437    naI->liste=(napoly*)omAlloc(naI->anz*sizeof(napoly));
1438    for (i=IDELEMS(I)-1; i>=0; i--)
1439    {
1440      h=(lnumber)pGetCoeff(I->m[i]);
1441      /* We only need the enumerator of h, as we expect it to be a polynomial */
1442      naI->liste[i]=napCopy(h->z);
1443      /* If it isn't normalized (lc = 1) do this */
1444      if (!nacIsOne(pGetCoeff(naI->liste[i])))
1445      {
1446        x=naI->liste[i];
1447        nacNormalize(pGetCoeff(x));
1448        a=nacCopy(pGetCoeff(x));
1449        number aa=nacInvers(a);
1450        n_Delete(&a,nacRing);
1451        napMultN(x,aa);
1452        n_Delete(&aa,nacRing);
1453      }
1454    }
1455  }
1456}
1457
1458/*2
1459* map Z/p -> Q(a)
1460*/
1461number naMapP0(number c)
1462{
1463  if (npIsZero(c)) return NULL;
1464  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1465  l->s=2;
1466  l->z=(napoly)p_Init(nacRing);
1467  int i=(int)((long)c);
1468  if (i>((long)ntMapRing->ch>>2)) i-=(long)ntMapRing->ch;
1469  pGetCoeff(l->z)=nlInit(i, nacRing);
1470  l->n=NULL;
1471  return (number)l;
1472}
1473
1474/*2
1475* map Q -> Q(a)
1476*/
1477number naMap00(number c)
1478{
1479  if (nlIsZero(c)) return NULL;
1480  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1481  l->s=0;
1482  l->z=(napoly)p_Init(nacRing);
1483  pGetCoeff(l->z)=nlCopy(c);
1484  l->n=NULL;
1485  return (number)l;
1486}
1487
1488/*2
1489* map Z/p -> Z/p(a)
1490*/
1491number naMapPP(number c)
1492{
1493  if (npIsZero(c)) return NULL;
1494  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1495  l->s=2;
1496  l->z=(napoly)p_Init(nacRing);
1497  pGetCoeff(l->z)=c; /* omit npCopy, because npCopy is a no-op */
1498  l->n=NULL;
1499  return (number)l;
1500}
1501
1502/*2
1503* map Z/p' -> Z/p(a)
1504*/
1505number naMapPP1(number c)
1506{
1507  if (npIsZero(c)) return NULL;
1508  int i=(int)((long)c);
1509  if (i>(long)ntMapRing->ch) i-=(long)ntMapRing->ch;
1510  number n=npInit(i,ntMapRing);
1511  if (npIsZero(n)) return NULL;
1512  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1513  l->s=2;
1514  l->z=(napoly)p_Init(nacRing);
1515  pGetCoeff(l->z)=n;
1516  l->n=NULL;
1517  return (number)l;
1518}
1519
1520/*2
1521* map Q -> Z/p(a)
1522*/
1523number naMap0P(number c)
1524{
1525  if (nlIsZero(c)) return NULL;
1526  number n=npInit(nlModP(c,npPrimeM),nacRing);
1527  if (npIsZero(n)) return NULL;
1528  npTest(n);
1529  lnumber l=(lnumber)omAllocBin(rnumber_bin);
1530  l->s=2;
1531  l->z=(napoly)p_Init(nacRing);
1532  pGetCoeff(l->z)=n;
1533  l->n=NULL;
1534  return (number)l;
1535}
1536
1537/*2
1538* map _(a) -> _(b)
1539*/
1540number naMapQaQb(number c)
1541{
1542  if (c==NULL) return NULL;
1543  lnumber erg= (lnumber)omAlloc0Bin(rnumber_bin);
1544  lnumber src =(lnumber)c;
1545  erg->s=src->s;
1546  erg->z=napMap(src->z);
1547  erg->n=napMap(src->n);
1548  if (naMinimalPoly!=NULL)
1549  {
1550    if (p_GetExp(erg->z,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1551    {
1552      erg->z = napRemainder(erg->z, naMinimalPoly);
1553      if (erg->z==NULL)
1554      {
1555        number t_erg=(number)erg;
1556        naDelete(&t_erg,currRing);
1557        return (number)NULL;
1558      }
1559    }
1560    if (erg->n!=NULL)
1561    {
1562      if (p_GetExp(erg->n,1,nacRing) >= p_GetExp(naMinimalPoly,1,nacRing))
1563        erg->n = napRemainder(erg->n, naMinimalPoly);
1564      if ((p_IsConstant(erg->n,nacRing)) && nacIsOne(pGetCoeff(erg->n)))
1565        p_Delete(&(erg->n),nacRing);
1566    }
1567  }
1568  return (number)erg;
1569}
1570
1571nMapFunc naSetMap(const ring src, const ring dst)
1572{
1573  ntMapRing=src;
1574  if (rField_is_Q_a(dst)) /* -> Q(a) */
1575  {
1576    if (rField_is_Q(src))
1577    {
1578      return naMap00;   /*Q -> Q(a)*/
1579    }
1580    if (rField_is_Zp(src))
1581    {
1582      return naMapP0;  /* Z/p -> Q(a)*/
1583    }
1584    if (rField_is_Q_a(src))
1585    {
1586      int i;
1587      ntParsToCopy=0;
1588      for(i=0;i<rPar(src);i++)
1589      {
1590        if ((i>=rPar(dst))
1591        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
1592           return NULL;
1593        ntParsToCopy++;
1594      }
1595      nacMap=nacCopy;
1596      if ((ntParsToCopy==rPar(dst))&&(ntParsToCopy==rPar(src)))
1597        return naCopy;    /* Q(a) -> Q(a) */
1598      return naMapQaQb;   /* Q(a..) -> Q(a..) */
1599    }
1600  }
1601  /*-----------------------------------------------------*/
1602  if (rField_is_Zp_a(dst)) /* -> Z/p(a) */
1603  {
1604    if (rField_is_Q(src))
1605    {
1606      return naMap0P;   /*Q -> Z/p(a)*/
1607    }
1608    if (rField_is_Zp(src))
1609    {
1610      if (src->ch==dst->ch)
1611      {
1612        return naMapPP;  /* Z/p -> Z/p(a)*/
1613      }
1614      else
1615      {
1616        return naMapPP1;  /* Z/p' -> Z/p(a)*/
1617      }
1618    }
1619    if (rField_is_Zp_a(src))
1620    {
1621      if (rChar(src)==rChar(dst))
1622      {
1623        nacMap=nacCopy;
1624      }
1625      else
1626      {
1627        nacMap = npMapP;
1628      }
1629      int i;
1630      ntParsToCopy=0;
1631      for(i=0;i<rPar(src);i++)
1632      {
1633        if ((i>=rPar(dst))
1634        ||(strcmp(src->parameter[i],dst->parameter[i])!=0))
1635           return NULL;
1636        ntParsToCopy++;
1637      }
1638      if ((ntParsToCopy==rPar(dst))&&(ntParsToCopy==rPar(src))
1639      && (nacMap==nacCopy))
1640        return naCopy;    /* Z/p(a) -> Z/p(a) */
1641      return naMapQaQb;   /* Z/p(a),Z/p'(a) -> Z/p(b)*/
1642    }
1643  }
1644  return NULL;      /* default */
1645}
1646
1647#ifdef LDEBUG
1648BOOLEAN naDBTest(number a, const char *f,const int l)
1649{
1650  lnumber x=(lnumber)a;
1651  if (x == NULL)
1652    return TRUE;
1653  #ifdef LDEBUG
1654  omCheckAddrSize(a, sizeof(snumber));
1655  #endif
1656  napoly p = x->z;
1657  if (p==NULL)
1658  {
1659    Print("0/* in %s:%d\n",f,l);
1660    return FALSE;
1661  }
1662  while(p!=NULL)
1663  {
1664    if (( ntIsChar0  && nlIsZero(pGetCoeff(p)))
1665    || ((!ntIsChar0) && npIsZero(pGetCoeff(p))))
1666    {
1667      Print("coeff 0 in %s:%d\n",f,l);
1668      return FALSE;
1669    }
1670    if((naMinimalPoly!=NULL)
1671    &&(p_GetExp(p,1,nacRing)>p_GetExp(naMinimalPoly,1,nacRing))
1672    &&(p!=naMinimalPoly))
1673    {
1674      Print("deg>minpoly in %s:%d\n",f,l);
1675      return FALSE;
1676    }
1677    //if (ntIsChar0 && (((int)p->ko &3) == 0) && (p->ko->s==0) && (x->s==2))
1678    //{
1679    //  Print("normalized with non-normal coeffs in %s:%d\n",f,l);
1680    //  return FALSE;
1681    //}
1682    if (ntIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
1683      return FALSE;
1684    pIter(p);
1685  }
1686  p = x->n;
1687  while(p!=NULL)
1688  {
1689    if (ntIsChar0 && !(nlDBTest(pGetCoeff(p),f,l)))
1690      return FALSE;
1691    pIter(p);
1692  }
1693  return TRUE;
1694}
1695#endif
Note: See TracBrowser for help on using the repository browser.