source: git/kernel/numbers.cc @ 3a67ea7

spielwiese
Last change on this file since 3a67ea7 was 206e158, checked in by Oliver Wienand <wienand@…>, 17 years ago
structs.h, numbers.*, rmodulo*: new method nComp nIntDiv(0, a) = module / a in rmodulo ringgb.*: adapted for more generic rings ring.h: rField_is_Domain new k*: adapted for gbs over Z/m git-svn-id: file:///usr/local/Singular/svn/trunk@10034 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.5 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/* $Id: numbers.cc,v 1.9 2007-05-11 10:48:04 wienand Exp $ */
5
6/*
7* ABSTRACT: interface to coefficient aritmetics
8*/
9
10#include <string.h>
11#include <stdlib.h>
12#include "mod2.h"
13#include "structs.h"
14#include "febase.h"
15#include "kstd1.h"
16#include "numbers.h"
17#include "longrat.h"
18#include "longalg.h"
19#include "modulop.h"
20#include "gnumpfl.h"
21#include "gnumpc.h"
22#include "ring.h"
23#include "ffields.h"
24#include "shortfl.h"
25#ifdef HAVE_RING2TOM
26#include "rmodulo2m.h"
27#endif
28#ifdef HAVE_RINGMODN
29#include "rmodulon.h"
30#endif
31
32//static int characteristic = 0;
33extern int IsPrime(int p);
34
35void   (*nNew)(number *a);
36number (*nInit)(int i);
37number (*nPar)(int i);
38int    (*nParDeg)(number n);
39int    (*nSize)(number n);
40int    (*nInt)(number &n);
41numberfunc nMult, nSub, nAdd, nDiv, nIntDiv, nIntMod, nExactDiv;
42number (*nNeg)(number a);
43number (*nInvers)(number a);
44void   (*nNormalize)(number &a);
45number (*nCopy)(number a);
46number (*nRePart)(number a);
47number (*nImPart)(number a);
48#ifdef HAVE_RINGS
49BOOLEAN (*nDivBy)(number a,number b);
50int     (*nComp)(number a,number b);
51#endif
52BOOLEAN (*nGreater)(number a,number b);
53BOOLEAN (*nEqual)(number a,number b);
54BOOLEAN (*nIsZero)(number a);
55BOOLEAN (*nIsOne)(number a);
56BOOLEAN (*nIsMOne)(number a);
57BOOLEAN (*nGreaterZero)(number a);
58void    (*nWrite)(number &a);
59char *  (*nRead)(char *s,number *a);
60void    (*nPower)(number a, int i, number * result);
61number  (*nGcd)(number a, number b, const ring r);
62number  (*nLcm)(number a, number b, const ring r);
63char * (*nName)(number n);
64void   (*n__Delete)(number *a, const ring r);
65
66/*0 implementation*/
67number nNULL; /* the 0 as constant */
68
69
70n_Procs_s *cf_root=NULL;
71
72void   nDummy1(number* d) { *d=NULL; }
73void   ndDelete(number* d, const ring r) { *d=NULL; }
74void   ndInpMult(number &a, number b, const ring r)
75{
76  number n=n_Mult(a,b,r);
77  n_Delete(&a,r);
78  a=n;
79}
80
81#ifdef LDEBUG
82void   nDBDummy1(number* d,char *f, int l) { *d=NULL; }
83#endif
84
85void   nDummy2(number& d) { }
86
87char * ndName(number n) { return NULL; }
88
89number ndPar(int i) { return nInit(0); }
90
91number ndReturn0(number n) { return nInit(0); }
92
93int    ndParDeg(number n) { return 0; }
94
95number ndGcd(number a, number b, const ring r) { return r->cf->nInit(1); }
96
97number ndIntMod(number a, number b) { return nInit(0); }
98
99number ndGetDenom(number &n, const ring r) { return n_Init(1,r); }
100
101int ndSize(number a) { return (int)nIsZero(a)==FALSE; }
102
103number ndCopy(number a) { return a; }
104number nd_Copy(number a,const ring r) { return r->cf->nCopy(a); }
105
106#ifdef HAVE_RINGS
107BOOLEAN ndDivBy(number a, number b) { return TRUE; }
108int ndComp(number a, number b) { return 0; }
109#endif
110
111/*2
112* init operations for characteristic c (complete==TRUE)
113* init nDelete    for characteristic c (complete==FALSE)
114*/
115void nSetChar(ring r)
116{
117  int c=rInternalChar(r);
118
119  n__Delete= r->cf->cfDelete;
120  if (rField_is_Extension(r))
121  {
122    naSetChar(c,r);
123  }
124#ifdef HAVE_RING2TOM
125  /*----------------------ring Z / 2^m----------------*/
126  else if (rField_is_Ring_2toM(r))
127  {
128    nr2mSetExp(c, r);
129  }
130#endif 
131#ifdef HAVE_RINGMODN
132  /*----------------------ring Z / n----------------*/
133  else if (rField_is_Ring_ModN(r))
134  {
135    nrnSetExp(c, r);
136  }
137#endif
138  else if (rField_is_Zp(r))
139  /*----------------------char. p----------------*/
140  {
141    npSetChar(c, r);
142  }
143  /* -------------- GF(p^m) -----------------------*/
144  else if (rField_is_GF(r))
145  {
146    nfSetChar(c,r->parameter);
147  }
148  /* -------------- R -----------------------*/
149  //if (c==(-1))
150  else if (rField_is_R(r))
151  {
152  }
153  /* -------------- long R -----------------------*/
154  /* -------------- long C -----------------------*/
155  else if ((rField_is_long_R(r))
156  || (rField_is_long_C(r)))
157  {
158    setGMPFloatDigits(r->float_len,r->float_len2);
159  }
160#ifdef TEST
161  /* -------------- R -----------------------*/
162  //if (c==(-1))
163  else if (!rField_is_R(r) && !rField_is_Q(r))
164  {
165    WerrorS("unknown field");
166  }
167#endif
168  nNew   = r->cf->nNew;
169  nNormalize=r->cf->nNormalize;
170  nInit  = r->cf->nInit;
171  nPar   = r->cf->nPar;
172  nParDeg= r->cf->nParDeg;
173  nInt   = r->cf->nInt;
174  nAdd   = r->cf->nAdd;
175  nSub   = r->cf->nSub;
176  nMult  = r->cf->nMult;
177  nDiv   = r->cf->nDiv;
178  nExactDiv= r->cf->nExactDiv;
179  nIntDiv= r->cf->nIntDiv;
180  nIntMod= r->cf->nIntMod;
181  nNeg   = r->cf->nNeg;
182  nInvers= r->cf->nInvers;
183  nCopy  = r->cf->nCopy;
184#ifdef HAVE_RINGS
185  nComp  = r->cf->nComp;
186  nDivBy = r->cf->nDivBy;
187#endif
188  nGreater = r->cf->nGreater;
189  nEqual = r->cf->nEqual;
190  nIsZero = r->cf->nIsZero;
191  nIsOne = r->cf->nIsOne;
192  nIsMOne = r->cf->nIsMOne;
193  nGreaterZero = r->cf->nGreaterZero;
194  nWrite = r->cf->nWrite;
195  nRead = r->cf->nRead;
196  nPower = r->cf->nPower;
197  nGcd  = r->cf->nGcd;
198  nLcm  = r->cf->nLcm;
199  nName= r->cf->nName;
200  nSize  = r->cf->nSize;
201  nRePart = r->cf->nRePart;
202  nImPart = r->cf->nImPart;
203  nNULL=r->cf->nNULL;
204}
205
206/*2
207* init operations for ring r
208*/
209void nInitChar(ring r)
210{
211  int c=rInternalChar(r);
212  n_coeffType t=rFieldType(r);
213
214  if (rField_is_Extension(r))
215  {
216    if (r->algring==NULL)
217    {
218      int ch=-c;
219      if (c==1) ch=0;
220      r->algring=(ring) rDefault(ch,r->P,r->parameter);
221      //r->algring->ShortOut=r->ShortOut;
222      // includes: nInitChar(r->algring);
223    }
224  }
225
226  n_Procs_s *n=cf_root;
227  while((n!=NULL)
228    && ((n->nChar!=c) || (n->type!=t)))
229      n=n->next;
230  if (n==NULL)
231  {
232    n=(n_Procs_s*)omAlloc0(sizeof(n_Procs_s));
233    n->next=cf_root;
234    n->ref=1;
235    n->nChar=c;
236    n->type=t;
237    cf_root=n;
238  }
239  else if ((n->nChar==c) && (n->type==t))
240  {
241    n->ref++;
242    r->cf=n;
243    return;
244  }
245  else
246  {
247    WerrorS("nInitChar failed");
248    return;
249  }
250  r->cf=n;
251  n->nChar = c;
252  n->nPar  = ndPar;
253  n->nParDeg=ndParDeg;
254  n->nSize = ndSize;
255  n->n_GetDenom= ndGetDenom;
256  n->nName =  ndName;
257  n->nImPart=ndReturn0;
258  n->cfDelete= ndDelete;
259  n->nNew=nDummy1;
260  n->nInpMult=ndInpMult;
261  n->cfCopy=nd_Copy;
262  n->nIntMod=ndIntMod; /* dummy !! */
263  n->nNormalize=nDummy2;
264  n->nGcd  = ndGcd;
265  n->nLcm  = ndGcd; /* tricky, isn't it ?*/
266#ifdef HAVE_RINGS
267  n->nComp = ndComp;
268  n->nDivBy = ndDivBy;
269#endif
270  if (rField_is_Extension(r))
271  {
272    //naInitChar(c,TRUE,r);
273    n->cfDelete = naDelete;
274    n-> nNew       = naNew;
275    n-> nNormalize = naNormalize;
276    n->nInit       = naInit;
277    n->nPar        = naPar;
278    n->nParDeg     = naParDeg;
279    n->nInt        = naInt;
280    n->nAdd        = naAdd;
281    n->nSub        = naSub;
282    n->nMult       = naMult;
283    n->nDiv        = naDiv;
284    n->nExactDiv   = naDiv;
285    n->nIntDiv     = naIntDiv;
286    n->nNeg        = naNeg;
287    n->nInvers     = naInvers;
288    n->nCopy       = naCopy;
289    n->cfCopy      = na_Copy;
290    n->nGreater    = naGreater;
291    n->nEqual      = naEqual;
292    n->nIsZero     = naIsZero;
293    n->nIsOne      = naIsOne;
294    n->nIsMOne     = naIsMOne;
295    n->nGreaterZero= naGreaterZero;
296    n->nWrite      = naWrite;
297    n->nRead       = naRead;
298    n->nPower      = naPower;
299    n->nGcd        = naGcd;
300    n->nLcm        = naLcm;
301    n->cfSetMap    = naSetMap;
302    n->nName       = naName;
303    n->nSize       = naSize;
304    n->n_GetDenom   = naGetDenom;
305#ifdef LDEBUG
306    n->nDBTest     = naDBTest;
307#endif
308  }
309#ifdef HAVE_RING2TOM
310  /* -------------- Z/2^m ----------------------- */
311  else if (rField_is_Ring_2toM(r))
312  {
313     nr2mInitExp(c,r);
314     n->nInit  = nr2mInit;
315     n->nCopy  = ndCopy;
316     n->nInt   = nr2mInt;
317     n->nAdd   = nr2mAdd;
318     n->nSub   = nr2mSub;
319     n->nMult  = nr2mMult;
320     n->nDiv   = nr2mDiv;
321     n->nIntDiv       = nr2mIntDiv;
322     n->nExactDiv= nr2mDiv;
323     n->nNeg   = nr2mNeg;
324     n->nInvers= nr2mInvers;
325     n->nDivBy = nr2mDivBy;
326     n->nComp = nr2mComp;
327     n->nGreater = nr2mGreater;
328     n->nEqual = nr2mEqual;
329     n->nIsZero = nr2mIsZero;
330     n->nIsOne = nr2mIsOne;
331     n->nIsMOne = nr2mIsMOne;
332     n->nGreaterZero = nr2mGreaterZero;
333     n->nWrite = nr2mWrite;
334     n->nRead = nr2mRead;
335     n->nPower = nr2mPower;
336     n->cfSetMap = nr2mSetMap;
337     n->nNormalize = nDummy2;
338     n->nLcm          = nr2mLcm;
339     n->nGcd          = nr2mGcd;
340//     n->nGetUnit = nr2mGetUnit; //TODO OLIVER
341     n->nName= ndName;
342#ifdef LDEBUG
343     n->nDBTest=nr2mDBTest;
344#endif
345  }
346#endif
347#ifdef HAVE_RINGMODN
348  /* -------------- Z/n ----------------------- */
349  else if (rField_is_Ring_ModN(r))
350  {
351     nrnInitExp(c,r);
352     n->nInit  = nrnInit;
353     n->nCopy  = ndCopy;
354     n->nInt   = nrnInt;
355     n->nAdd   = nrnAdd;
356     n->nSub   = nrnSub;
357     n->nMult  = nrnMult;
358     n->nDiv   = nrnDiv;
359     n->nIntDiv       = nrnIntDiv;
360     n->nExactDiv= nrnDiv;
361     n->nNeg   = nrnNeg;
362     n->nInvers= nrnInvers;
363     n->nDivBy = nrnDivBy;
364     n->nComp = nrnComp;
365     n->nGreater = nrnGreater;
366     n->nEqual = nrnEqual;
367     n->nIsZero = nrnIsZero;
368     n->nIsOne = nrnIsOne;
369     n->nIsMOne = nrnIsMOne;
370     n->nGreaterZero = nrnGreaterZero;
371     n->nWrite = nrnWrite;
372     n->nRead = nrnRead;
373     n->nPower = nrnPower;
374     n->cfSetMap = nrnSetMap;
375     n->nNormalize = nDummy2;
376     n->nLcm          = nrnLcm;
377     n->nGcd          = nrnGcd;
378//     n->nGetUnit = nrnGetUnit; //TODO OLIVER
379     n->nName= ndName;
380#ifdef LDEBUG
381     n->nDBTest=nrnDBTest;
382#endif
383  }
384#endif
385  else if (rField_is_Q(r))
386  {
387    n->cfDelete= nlDelete;
388    n->nNew   = nlNew;
389    n->nNormalize=nlNormalize;
390    n->nInit  = nlInit;
391    n->nInt   = nlInt;
392    n->nAdd   = nlAdd;
393    n->nSub   = nlSub;
394    n->nMult  = nlMult;
395    n->nInpMult=nlInpMult;
396    n->nDiv   = nlDiv;
397    n->nExactDiv= nlExactDiv;
398    n->nIntDiv= nlIntDiv;
399    n->nIntMod= nlIntMod;
400    n->nNeg   = nlNeg;
401    n->nInvers= nlInvers;
402    n->nCopy  = nlCopy;
403    n->nGreater = nlGreater;
404    n->nEqual = nlEqual;
405    n->nIsZero = nlIsZero;
406    n->nIsOne = nlIsOne;
407    n->nIsMOne = nlIsMOne;
408    n->nGreaterZero = nlGreaterZero;
409    n->nWrite = nlWrite;
410    n->nRead = nlRead;
411    n->nPower = nlPower;
412    n->nGcd  = nlGcd;
413    n->nLcm  = nlLcm;
414    n->cfSetMap = nlSetMap;
415    n->nSize  = nlSize;
416    n->n_GetDenom = nlGetDenom;
417#ifdef LDEBUG
418    n->nDBTest=nlDBTest;
419#endif
420  }
421  else if (rField_is_Zp(r))
422  /*----------------------char. p----------------*/
423  {
424    npInitChar(c,r);
425    n->nInit  = npInit;
426    n->nInt   = npInt;
427    n->nAdd   = npAdd;
428    n->nSub   = npSub;
429    n->nMult  = npMult;
430    n->nDiv   = npDiv;
431    n->nExactDiv= npDiv;
432    n->nNeg   = npNeg;
433    n->nInvers= npInvers;
434    n->nCopy  = ndCopy;
435    n->nGreater = npGreater;
436    n->nEqual = npEqual;
437    n->nIsZero = npIsZero;
438    n->nIsOne = npIsOne;
439    n->nIsMOne = npIsMOne;
440    n->nGreaterZero = npGreaterZero;
441    n->nWrite = npWrite;
442    n->nRead = npRead;
443    n->nPower = npPower;
444    n->cfSetMap = npSetMap;
445    /* nName= ndName; */
446    /*nSize  = ndSize;*/
447#ifdef LDEBUG
448    n->nDBTest=npDBTest;
449#endif
450#ifdef NV_OPS
451    if (c>NV_MAX_PRIME)
452    {
453      n->nMult  = nvMult;
454      n->nDiv   = nvDiv;
455      n->nExactDiv= nvDiv;
456      n->nInvers= nvInvers;
457    }
458#endif
459  }
460  /* -------------- GF(p^m) -----------------------*/
461  else if (rField_is_GF(r))
462  {
463    //nfSetChar(c,r->parameter);
464    n->nInit  = nfInit;
465    n->nPar   = nfPar;
466    n->nParDeg= nfParDeg;
467    n->nInt   = nfInt;
468    n->nAdd   = nfAdd;
469    n->nSub   = nfSub;
470    n->nMult  = nfMult;
471    n->nDiv   = nfDiv;
472    n->nExactDiv= nfDiv;
473    n->nNeg   = nfNeg;
474    n->nInvers= nfInvers;
475    n->nCopy  = ndCopy;
476    n->nGreater = nfGreater;
477    n->nEqual = nfEqual;
478    n->nIsZero = nfIsZero;
479    n->nIsOne = nfIsOne;
480    n->nIsMOne = nfIsMOne;
481    n->nGreaterZero = nfGreaterZero;
482    n->nWrite = nfWrite;
483    n->nRead = nfRead;
484    n->nPower = nfPower;
485    n->cfSetMap = nfSetMap;
486    n->nName= nfName;
487    /*nSize  = ndSize;*/
488#ifdef LDEBUG
489    n->nDBTest=nfDBTest;
490#endif
491  }
492  /* -------------- R -----------------------*/
493  //if (c==(-1))
494  else if (rField_is_R(r))
495  {
496    n->nInit  = nrInit;
497    n->nInt   = nrInt;
498    n->nAdd   = nrAdd;
499    n->nSub   = nrSub;
500    n->nMult  = nrMult;
501    n->nDiv   = nrDiv;
502    n->nExactDiv= nrDiv;
503    n->nNeg   = nrNeg;
504    n->nInvers= nrInvers;
505    n->nCopy  = ndCopy;
506    n->nGreater = nrGreater;
507    n->nEqual = nrEqual;
508    n->nIsZero = nrIsZero;
509    n->nIsOne = nrIsOne;
510    n->nIsMOne = nrIsMOne;
511    n->nGreaterZero = nrGreaterZero;
512    n->nWrite = nrWrite;
513    n->nRead = nrRead;
514    n->nPower = nrPower;
515    n->cfSetMap=nrSetMap;
516    /* nName= ndName; */
517    /*nSize  = ndSize;*/
518#ifdef LDEBUG
519    n->nDBTest=nrDBTest;
520#endif
521  }
522  /* -------------- long R -----------------------*/
523  else if (rField_is_long_R(r))
524  {
525    n->cfDelete= ngfDelete;
526    n->nNew=ngfNew;
527    n->nInit  = ngfInit;
528    n->nInt   = ngfInt;
529    n->nAdd   = ngfAdd;
530    n->nSub   = ngfSub;
531    n->nMult  = ngfMult;
532    n->nDiv   = ngfDiv;
533    n->nExactDiv= ngfDiv;
534    n->nNeg   = ngfNeg;
535    n->nInvers= ngfInvers;
536    n->nCopy  = ngfCopy;
537    n->nGreater = ngfGreater;
538    n->nEqual = ngfEqual;
539    n->nIsZero = ngfIsZero;
540    n->nIsOne = ngfIsOne;
541    n->nIsMOne = ngfIsMOne;
542    n->nGreaterZero = ngfGreaterZero;
543    n->nWrite = ngfWrite;
544    n->nRead = ngfRead;
545    n->nPower = ngfPower;
546    n->cfSetMap=ngfSetMap;
547    n->nName= ndName;
548    n->nSize  = ndSize;
549#ifdef LDEBUG
550    n->nDBTest=ngfDBTest;
551#endif
552  }
553  /* -------------- long C -----------------------*/
554  else if (rField_is_long_C(r))
555  {
556    n->cfDelete= ngcDelete;
557    n->nNew=ngcNew;
558    n->nNormalize=nDummy2;
559    n->nInit  = ngcInit;
560    n->nInt   = ngcInt;
561    n->nAdd   = ngcAdd;
562    n->nSub   = ngcSub;
563    n->nMult  = ngcMult;
564    n->nDiv   = ngcDiv;
565    n->nExactDiv= ngcDiv;
566    n->nNeg   = ngcNeg;
567    n->nInvers= ngcInvers;
568    n->nCopy  = ngcCopy;
569    n->nGreater = ngcGreater;
570    n->nEqual = ngcEqual;
571    n->nIsZero = ngcIsZero;
572    n->nIsOne = ngcIsOne;
573    n->nIsMOne = ngcIsMOne;
574    n->nGreaterZero = ngcGreaterZero;
575    n->nWrite = ngcWrite;
576    n->nRead = ngcRead;
577    n->nPower = ngcPower;
578    n->cfSetMap=ngcSetMap;
579    n->nPar=ngcPar;
580    n->nRePart=ngcRePart;
581    n->nImPart=ngcImPart;
582    /*nSize  = ndSize;*/
583#ifdef LDEBUG
584    n->nDBTest=ngcDBTest;
585#endif
586  }
587#ifdef TEST
588  else
589  {
590    WerrorS("unknown field");
591  }
592#endif
593  if (!errorreported)
594  {
595    n->nNULL=n->nInit(0);
596    if (n->nRePart==NULL)
597      n->nRePart=n->nCopy;
598    if (n->nIntDiv==NULL)
599      n->nIntDiv=n->nDiv;
600  }
601}
602
603void nKillChar(ring r)
604{
605  if (r!=NULL)
606  {
607    if (r->cf!=NULL)
608    {
609      r->cf->ref--;
610      if (r->cf->ref<=0)
611      {
612        n_Procs_s tmp;
613        n_Procs_s* n=&tmp;
614        tmp.next=cf_root;
615        while((n->next!=NULL) && (n->next!=r->cf)) n=n->next;
616        if (n->next==r->cf)
617        {
618          n->next=n->next->next;
619          if (cf_root==r->cf) cf_root=n->next;
620          r->cf->cfDelete(&(r->cf->nNULL),r);
621          switch(r->cf->type)
622          {
623            case n_Zp:
624                 #ifdef HAVE_DIV_MOD
625                 if (r->cf->npInvTable!=NULL)
626                 omFreeSize( (ADDRESS)r->cf->npInvTable,
627                             r->cf->npPrimeM*sizeof(CARDINAL) );
628                 #else
629                 if (r->cf->npExpTable!=NULL)
630                 {
631                   omFreeSize( (ADDRESS)r->cf->npExpTable,
632                               r->cf->npPrimeM*sizeof(CARDINAL) );
633                   omFreeSize( (ADDRESS)r->cf->npLogTable,
634                               r->cf->npPrimeM*sizeof(CARDINAL) );
635                 }
636                 #endif
637                 break;
638            case n_Zp_a:
639            case n_Q_a:
640                 {
641                   number n=r->minpoly;
642                   if (n!=NULL)
643                   {
644                     r->minpoly=NULL;
645                     if (r==currRing) naMinimalPoly=NULL;
646                     naDelete(&n,r);
647                   }
648                 }
649                 break;
650
651            default:
652                 break;
653          }
654          omFreeSize((ADDRESS)r->cf, sizeof(n_Procs_s));
655          r->cf=NULL;
656        }
657        else
658        {
659          WarnS("cf_root list destroyed");
660        }
661      }
662    }
663    if (r->algring!=NULL)
664    {
665      rKill(r->algring);
666      r->algring=NULL;
667    }
668  }
669}
Note: See TracBrowser for help on using the repository browser.