source: git/kernel/longalg.cc @ 896561

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