source: git/libpolys/coeffs/numbers.cc @ 46eef0

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