source: git/kernel/numbers.cc @ 009d80

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