source: git/libpolys/coeffs/numbers.cc @ b807aa0

jengelh-datetimespielwiese
Last change on this file since b807aa0 was b807aa0, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
minor improvements at coeffs add: doxygen chg: avoid access to internals AFAP + more assumes chg: eliminate compiler warning about an unused function argument
  • Property mode set to 100644
File size: 10.6 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4
5/*
6* ABSTRACT: interface to coefficient aritmetics
7*/
8
9#include <string.h>
10#include <stdlib.h>
11
12#include "config.h"
13#include <misc/auxiliary.h>
14
15#ifdef HAVE_FACTORY
16#include <factory/factory.h>
17#endif
18
19
20#include "coeffs.h"
21#include <coeffs/numbers.h>
22
23#include <reporter/reporter.h>
24#include <omalloc/omalloc.h>
25#include <coeffs/numbers.h>
26#include <coeffs/longrat.h>
27#include <coeffs/modulop.h>
28#include <coeffs/gnumpfl.h>
29#include <coeffs/gnumpc.h>
30#include <coeffs/ffields.h>
31#include <coeffs/shortfl.h>
32
33#ifdef HAVE_RINGS
34#include <coeffs/rmodulo2m.h>
35#include <coeffs/rmodulon.h>
36#include <coeffs/rintegers.h>
37#endif
38
39#ifdef HAVE_POLYEXTENSIONS
40#include <polys/ext_fields/algext.h>
41#include <polys/ext_fields/transext.h>
42#endif
43
44
45
46//static int characteristic = 0;
47extern int IsPrime(int p);
48
49n_Procs_s *cf_root=NULL;
50
51void   nNew(number* d) { *d=NULL; }
52void   ndDelete(number* d, const coeffs) { *d=NULL; }
53void   ndInpMult(number &a, number b, const coeffs r)
54{
55  number n=n_Mult(a,b,r);
56  n_Delete(&a,r);
57  a=n;
58}
59void ndInpAdd(number &a, number b, const coeffs r)
60{
61  number n=n_Add(a,b,r);
62  n_Delete(&a,r);
63  a=n;
64}
65
66#ifdef LDEBUG
67void   nDBDummy1(number* d,char *, int) { *d=NULL; }
68BOOLEAN ndDBTest(number, const char *, const int, const coeffs)
69{
70  return TRUE;
71}
72#endif
73
74number ndFarey(number,number,const coeffs r)
75{
76  Werror("farey not implemented for (c=%d)",getCoeffType(r));
77  return NULL;
78}
79number ndChineseRemainder(number *,number *,int,const coeffs r)
80{
81  Werror("ChineseRemainder not implemented for (c=%d)",getCoeffType(r));
82  return n_Init(0,r); 
83}
84
85static int ndParDeg(number n, const coeffs r)
86{
87  return (-n_IsZero(n,r));
88}
89
90static number ndParameter(const int, const coeffs r)
91{
92  Werror("ndParameter: n_Parameter is not implemented/relevant for (coeff_type = %d)",getCoeffType(r));
93  return NULL;
94}
95
96BOOLEAN n_IsZeroDivisor( number a, const coeffs r)
97{
98  int c = n_GetChar(r);
99  BOOLEAN ret = n_IsZero(a, r);
100  if( (c != 0) && !ret )
101  {
102    number ch = n_Init( c, r ); 
103    number g = n_Gcd( ch, a, r );
104    ret = !n_IsOne (g, r);
105    n_Delete(&ch, r);
106    n_Delete(&g, r);
107  }
108  return ret; 
109}
110
111void   ndNormalize(number&, const coeffs) { }
112
113char * ndName(number, const coeffs) { return NULL; }
114
115number ndReturn0(number, const coeffs r) { return n_Init(0,r); }
116
117number ndGcd(number, number, const coeffs r) { return n_Init(1,r); }
118
119number ndIntMod(number, number, const coeffs r) { return n_Init(0,r); }
120
121number ndGetDenom(number &, const coeffs r) { return n_Init(1,r); }
122number ndGetNumerator(number &a,const coeffs r) { return n_Copy(a,r); }
123
124int ndSize(number a, const coeffs r) { return (int)n_IsZero(a,r)==FALSE; }
125
126number ndCopy(number a, const coeffs) { return a; }
127number ndCopyMap(number a, const coeffs aRing, const coeffs r)
128{
129  assume( getCoeffType(r) == getCoeffType(aRing) );
130  if ( nCoeff_has_simple_Alloc(r) && nCoeff_has_simple_Alloc(aRing) )
131    return a;
132        else
133    return n_Copy(a, r);
134}
135void ndKillChar(coeffs) {}
136void ndSetChar(const coeffs) {}
137
138number nd_Copy(number a, const coeffs r) { return n_Copy(a, r); }
139
140#ifdef HAVE_RINGS
141BOOLEAN ndDivBy(number, number, const coeffs) { return TRUE; } // assume a,b !=0
142int ndDivComp(number, number, const coeffs) { return 2; }
143BOOLEAN ndIsUnit(number a, const coeffs r) { return !n_IsZero(a,r); }
144number  ndExtGcd (number, number, number *, number *, const coeffs r) { return n_Init(1,r); }
145#endif
146
147#ifdef HAVE_FACTORY
148CanonicalForm ndConvSingNFactoryN( number, BOOLEAN /*setChar*/, const coeffs)
149{
150  CanonicalForm term(0);
151  Werror("no conversion to factory");
152  return term;
153}
154
155number ndConvFactoryNSingN( const CanonicalForm, const coeffs)
156{
157  Werror("no conversion from factory");
158  return NULL;
159}
160#endif
161
162number  ndInit_bigint(number, const coeffs, const coeffs)
163{
164  Werror("no conversion from bigint to this field");
165  return NULL;
166}
167
168/**< [in, out] a bigint number >= 0  */
169/**< [out] the GMP equivalent    */
170/// Converts a non-negative bigint number into a GMP number.
171void ndMPZ(mpz_t result, number &n, const coeffs r)
172{
173  mpz_init_set_si( result, n_Int(n, r) );
174}
175
176number ndInitMPZ(mpz_t m, const coeffs r)
177{ 
178  return n_Init( mpz_get_si(m), r);
179}
180
181
182BOOLEAN ndCoeffIsEqual(const coeffs r, n_coeffType n, void *)
183{
184  /* test, if r is an instance of nInitCoeffs(n,parameter) */
185  /* if paramater is not needed */
186  return (n==r->type);
187}
188
189static n_coeffType nLastCoeffs=n_CF;
190cfInitCharProc nInitCharTableDefault[]=
191{ NULL,        /*n_unknown */
192 npInitChar,   /* n_Zp */
193 nlInitChar,   /* n_Q */
194 nrInitChar,   /* n_R */
195 nfInitChar,   /* n_GF */
196 ngfInitChar,  /* n_long_R */
197 #ifdef HAVE_POLYEXTENSIONS
198 naInitChar,  /* n_algExt */
199 ntInitChar,  /* n_transExt */
200 #else
201 NULL,        /* n_algExt */
202 NULL,        /* n_transExt */
203 #endif   
204 ngcInitChar,  /* n_long_C */
205 #ifdef HAVE_RINGS
206 nrzInitChar,  /* n_Z */
207 nrnInitChar,  /* n_Zn */
208 NULL,         /* n_Zpn */
209 nr2mInitChar, /* n_Z2m */
210 #else
211 NULL,         /* n_Z */
212 NULL,         /* n_Zn */
213 NULL,         /* n_Zpn */
214 NULL,         /* n_Z2m */
215 #endif
216 NULL   /* n_CF */
217};
218
219static cfInitCharProc *nInitCharTable=nInitCharTableDefault;
220/*2
221* init operations for coeffs r
222*/
223coeffs nInitChar(n_coeffType t, void * parameter)
224{
225  n_Procs_s *n=cf_root;
226
227  while((n!=NULL) && (n->nCoeffIsEqual!=NULL) && (!n->nCoeffIsEqual(n,t,parameter)))
228      n=n->next;
229
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->type=t;
236
237    // default entries (different from NULL) for some routines:
238    n->cfSize = ndSize;
239    n->cfGetDenom= ndGetDenom;
240    n->cfGetNumerator= ndGetNumerator;
241    n->cfName =  ndName;
242    n->cfImPart=ndReturn0;
243    n->cfDelete= ndDelete;
244    n->cfInpMult=ndInpMult;
245    n->cfCopy = ndCopy;
246    n->cfIntMod=ndIntMod; /* dummy !! */
247    n->cfNormalize=ndNormalize;
248    n->cfGcd  = ndGcd;
249    n->cfLcm  = ndGcd; /* tricky, isn't it ?*/
250    n->cfInit_bigint = ndInit_bigint;
251    n->cfInitMPZ = ndInitMPZ;
252    n->cfMPZ = ndMPZ;
253
254    //n->cfKillChar = ndKillChar; /* dummy */
255    n->cfSetChar = ndSetChar; /* dummy */
256    // temp. removed to catch all the coeffs which miss to implement this!
257
258    n->cfChineseRemainder = ndChineseRemainder;
259    n->cfFarey = ndFarey;
260    n->cfParDeg = ndParDeg;
261   
262    n->cfParameter = ndParameter;
263
264#ifdef HAVE_RINGS
265    n->cfDivComp = ndDivComp;
266    n->cfDivBy = ndDivBy;
267    n->cfIsUnit = ndIsUnit;
268    n->cfExtGcd = ndExtGcd;
269    //n->cfGetUnit = (nMapFunc)NULL;
270#endif
271
272#ifdef fACTORY
273    n->convSingNFactoryN=ndConvSingNFactoryN;
274    n->convFactoryNSingN=ndConvFactoryNSingN;
275#endif
276   
277    BOOLEAN nOK=TRUE;
278    // init
279    if ((t<=nLastCoeffs) && (nInitCharTable[t]!=NULL))
280      nOK = (nInitCharTable[t])(n,parameter);
281    else
282       Werror("Sorry: the coeff type [%d] was not registered: it is missing in nInitCharTable", (int)t);
283    if (nOK)
284    {
285      omFreeSize(n,sizeof(*n));
286      return NULL;
287    }
288    cf_root=n;
289    // post init settings:
290    if (n->cfRePart==NULL) n->cfRePart=n->cfCopy;
291    if (n->cfIntDiv==NULL) n->cfIntDiv=n->cfDiv;
292   
293#ifdef HAVE_RINGS
294    if (n->cfGetUnit==NULL) n->cfGetUnit=n->cfCopy;
295#endif
296
297    if(n->cfWriteShort==NULL)
298      n->cfWriteShort = n->cfWriteLong;
299
300    assume(n->nCoeffIsEqual!=NULL);
301    assume(n->cfSetChar!=NULL);
302    assume(n->cfMult!=NULL);
303    assume(n->cfSub!=NULL);
304    assume(n->cfAdd!=NULL);
305    assume(n->cfDiv!=NULL);
306    assume(n->cfIntDiv!=NULL);
307    assume(n->cfIntMod!=NULL);
308    assume(n->cfExactDiv!=NULL);
309    assume(n->cfInit!=NULL);
310    assume(n->cfInitMPZ!=NULL);
311    assume(n->cfSize!=NULL);
312    assume(n->cfInt!=NULL);
313    assume(n->cfMPZ!=NULL);
314    //assume(n->n->cfDivComp!=NULL);
315    //assume(n->cfIsUnit!=NULL);
316    //assume(n->cfGetUnit!=NULL);
317    //assume(n->cfExtGcd!=NULL);
318    assume(n->cfNeg!=NULL);
319    assume(n->cfCopy!=NULL);
320    assume(n->cfRePart!=NULL);
321    assume(n->cfImPart!=NULL);
322
323    assume(n->cfWriteLong!=NULL);
324    assume(n->cfWriteShort!=NULL);
325
326    assume(n->iNumberOfParameters>= 0);
327
328    assume( (n->iNumberOfParameters == 0 && n->pParameterNames == NULL) ||
329            (n->iNumberOfParameters >  0 && n->pParameterNames != NULL) );           
330
331    assume(n->cfParameter!=NULL);
332    assume(n->cfParDeg!=NULL);
333     
334    assume(n->cfRead!=NULL);
335    assume(n->cfNormalize!=NULL);
336    assume(n->cfGreater!=NULL);
337    //assume(n->cfDivBy!=NULL);
338    assume(n->cfEqual!=NULL);
339    assume(n->cfIsZero!=NULL);
340    assume(n->cfIsOne!=NULL);
341    assume(n->cfIsMOne!=NULL);
342    assume(n->cfGreaterZero!=NULL);
343    assume(n->cfPower!=NULL);
344    assume(n->cfGetDenom!=NULL);
345    assume(n->cfGetNumerator!=NULL);
346    assume(n->cfGcd!=NULL);
347    assume(n->cfLcm!=NULL);
348    assume(n->cfDelete!=NULL);
349    assume(n->cfSetMap!=NULL);
350    assume(n->cfName!=NULL);
351    assume(n->cfInpMult!=NULL);
352//    assume(n->cfInit_bigint!=NULL);
353    assume(n->cfCoeffWrite != NULL);
354#ifdef LDEBUG
355    assume(n->cfDBTest!=NULL);
356#endif
357    assume(n->type==t);
358     
359#ifndef NDEBUG
360    if(n->cfKillChar==NULL) Warn("cfKillChar is NULL for coeff %d",t);
361    if(n->cfWriteLong==NULL) Warn("cfWrite is NULL for coeff %d",t);
362    if(n->cfWriteShort==NULL) Warn("cfWriteShort is NULL for coeff %d",t);
363#endif
364     
365   if( n->nNULL == NULL )
366     n->nNULL = n_Init(0, n); // may still remain NULL
367  }
368  else
369  {
370    n->ref++;
371  }
372  return n;
373}
374
375void nKillChar(coeffs r)
376{
377  if (r!=NULL)
378  {
379    r->ref--;
380    if (r->ref<=0)
381    {
382      n_Procs_s tmp;
383      n_Procs_s* n=&tmp;
384      tmp.next=cf_root;
385      while((n->next!=NULL) && (n->next!=r)) n=n->next;
386      if (n->next==r)
387      {
388        n->next=n->next->next;
389        if (cf_root==r) cf_root=n->next;
390        r->cfDelete(&(r->nNULL),r);
391        if (r->cfKillChar!=NULL) r->cfKillChar(r);
392        omFreeSize((void *)r, sizeof(n_Procs_s));
393        r=NULL;
394      }
395      else
396      {
397        WarnS("cf_root list destroyed");
398      }
399    }
400  }
401}
402
403
404n_coeffType nRegister(n_coeffType n, cfInitCharProc p)
405{
406  if (n==n_unknown)
407  {
408    nLastCoeffs=(n_coeffType)(int(nLastCoeffs)+1);
409    if (nInitCharTable==nInitCharTableDefault)
410    {
411      nInitCharTable=(cfInitCharProc*)omAlloc0(
412                                          nLastCoeffs*sizeof(cfInitCharProc));
413      memcpy(nInitCharTable,nInitCharTableDefault,
414              (nLastCoeffs-1)*sizeof(cfInitCharProc));
415    }
416    else
417    {
418      nInitCharTable=(cfInitCharProc*)omReallocSize(nInitCharTable,
419                                          (((int)nLastCoeffs)-1)*sizeof(cfInitCharProc),
420                                          ((int)nLastCoeffs)*sizeof(cfInitCharProc));
421    }
422
423    nInitCharTable[nLastCoeffs]=p;
424    return nLastCoeffs;
425  }
426  else
427  {
428    if (nInitCharTable[n]!=NULL) Print("coeff %d already initialized\n",n);
429    nInitCharTable[n]=p;
430    return n;
431  }
432}
433
Note: See TracBrowser for help on using the repository browser.