source: git/libpolys/coeffs/numbers.cc @ 045efb

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