source: git/libpolys/coeffs/numbers.cc @ 6cce775

spielwiese
Last change on this file since 6cce775 was 5b5409b, checked in by Hans Schoenemann <hannes@…>, 10 years ago
flint stuff: move optional parts to the end in coeffs
  • Property mode set to 100644
File size: 13.2 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#ifdef HAVE_CONFIG_H
13#include "libpolysconfig.h"
14#endif /* HAVE_CONFIG_H */
15#include <misc/auxiliary.h>
16
17#include <factory/factory.h>
18
19#include "coeffs.h"
20#include <coeffs/numbers.h>
21
22#include <reporter/reporter.h>
23#include <omalloc/omalloc.h>
24#include <coeffs/numbers.h>
25#include <coeffs/longrat.h>
26#include <coeffs/modulop.h>
27#include <coeffs/gnumpfl.h>
28#include <coeffs/gnumpc.h>
29#include <coeffs/ffields.h>
30#include <coeffs/shortfl.h>
31
32#ifdef HAVE_RINGS
33#include <coeffs/rmodulo2m.h>
34#include <coeffs/rmodulon.h>
35#include <coeffs/rintegers.h>
36#endif
37
38#ifdef HAVE_POLYEXTENSIONS
39#include <polys/ext_fields/algext.h>
40#include <polys/ext_fields/transext.h>
41#endif
42
43
44
45//static int characteristic = 0;
46//extern int IsPrime(int p);
47
48n_Procs_s *cf_root=NULL;
49
50void   nNew(number* d) { *d=NULL; }
51void   ndDelete(number* d, const coeffs) { *d=NULL; }
52void   ndInpMult(number &a, number b, const coeffs r)
53{
54  number n=n_Mult(a,b,r);
55  n_Delete(&a,r);
56  a=n;
57}
58void ndInpAdd(number &a, number b, const coeffs r)
59{
60  number n=n_Add(a,b,r);
61  n_Delete(&a,r);
62  a=n;
63}
64
65#ifdef LDEBUG
66void   nDBDummy1(number* d,char *, int) { *d=NULL; }
67BOOLEAN ndDBTest(number, const char *, const int, const coeffs)
68{
69  return TRUE;
70}
71#endif
72
73number ndFarey(number,number,const coeffs r)
74{
75  Werror("farey not implemented for (c=%d)",getCoeffType(r));
76  return NULL;
77}
78number ndChineseRemainder(number *,number *,int,BOOLEAN,const coeffs r)
79{
80  Werror("ChineseRemainder not implemented for (c=%d)",getCoeffType(r));
81  return n_Init(0,r); 
82}
83
84static int ndParDeg(number n, const coeffs r)
85{
86  return (-n_IsZero(n,r));
87}
88
89static number ndParameter(const int, const coeffs r)
90{
91  Werror("ndParameter: n_Parameter is not implemented/relevant for (coeff_type = %d)",getCoeffType(r));
92  return NULL;
93}
94
95BOOLEAN n_IsZeroDivisor( number a, const coeffs r)
96{
97  int c = n_GetChar(r);
98  BOOLEAN ret = n_IsZero(a, r);
99  if( (c != 0) && !ret )
100  {
101    number ch = n_Init( c, r ); 
102    number g = n_Gcd( ch, a, r );
103    ret = !n_IsOne (g, r);
104    n_Delete(&ch, r);
105    n_Delete(&g, r);
106  }
107  return ret; 
108}
109
110void   ndNormalize(number&, const coeffs) { }
111
112char * ndName(number, const coeffs) { return NULL; }
113
114number ndReturn0(number, const coeffs r) { return n_Init(0,r); }
115
116number ndGcd(number, number, const coeffs r) { return n_Init(1,r); }
117
118number ndIntMod(number, number, const coeffs r) { return n_Init(0,r); }
119
120number ndGetDenom(number &, const coeffs r) { return n_Init(1,r); }
121number ndGetNumerator(number &a,const coeffs r) { return n_Copy(a,r); }
122
123int ndSize(number a, const coeffs r) { return (int)n_IsZero(a,r)==FALSE; }
124
125void ndClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
126{
127  assume(r != NULL);
128
129  // no fractions
130  assume(!(  nCoeff_is_Q(r) ));
131  // all coeffs are given by integers!!!
132
133  numberCollectionEnumerator.Reset();
134
135  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
136  {
137    c = n_Init(1, r);
138    return;
139  } 
140
141  number &curr = numberCollectionEnumerator.Current();
142 
143#ifdef HAVE_RINGS
144  /// TODO: move to a separate implementation
145  if (nCoeff_is_Ring(r))
146  {
147    if (nCoeff_has_Units(r))
148    {
149      c = n_GetUnit(curr, r);
150     
151      if (!n_IsOne(c, r))
152      {
153        number inv = n_Invers(c, r);
154
155        n_InpMult(curr, inv, r);
156       
157        while( numberCollectionEnumerator.MoveNext() )
158        {
159          number &n = numberCollectionEnumerator.Current();
160          n_Normalize(n, r); // ?
161          n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
162        }
163
164        n_Delete(&inv, r);       
165      }     
166    } else c = n_Init(1, r);
167   
168    return;
169  }
170#endif
171
172  assume(!nCoeff_is_Ring(r));
173  assume(nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) || nCoeff_is_Zp_a(r) || nCoeff_is_Q_algext(r));
174
175  n_Normalize(curr, r); // Q: good/bad/ugly??
176
177  if (!n_IsOne(curr, r))
178  {
179    number t = curr; // takes over the curr! note: not a reference!!!
180
181    curr = n_Init(1, r); // ???
182   
183    number inv = n_Invers(t, r);
184   
185    while( numberCollectionEnumerator.MoveNext() )
186    {
187      number &n = numberCollectionEnumerator.Current();
188      n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
189//      n_Normalize(n, r); // ?
190    }
191   
192    n_Delete(&inv, r);
193
194    c = t;
195  } else
196    c = n_Copy(curr, r); // c == 1 and nothing else to do...
197}
198
199void ndClearDenominators(ICoeffsEnumerator& /*numberCollectionEnumerator*/, number& d, const coeffs r)
200{
201  assume( r != NULL );
202  assume( !(nCoeff_is_Q(r) || nCoeff_is_transExt(r) || nCoeff_is_algExt(r)) );
203  assume( nCoeff_is_Ring(r) || nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) );
204
205  d = n_Init(1, r);
206}
207
208number ndCopy(number a, const coeffs) { return a; }
209number ndCopyMap(number a, const coeffs aRing, const coeffs r)
210{
211  assume( getCoeffType(r) == getCoeffType(aRing) );
212  if ( nCoeff_has_simple_Alloc(r) && nCoeff_has_simple_Alloc(aRing) )
213    return a;
214        else
215    return n_Copy(a, r);
216}
217void ndKillChar(coeffs) {}
218void ndSetChar(const coeffs) {}
219
220number nd_Copy(number a, const coeffs r) { return n_Copy(a, r); }
221
222#ifdef HAVE_RINGS
223BOOLEAN ndDivBy(number, number, const coeffs) { return TRUE; } // assume a,b !=0
224int ndDivComp(number, number, const coeffs) { return 2; }
225BOOLEAN ndIsUnit(number a, const coeffs r) { return !n_IsZero(a,r); }
226number  ndExtGcd (number, number, number *, number *, const coeffs r) { return n_Init(1,r); }
227#endif
228
229CanonicalForm ndConvSingNFactoryN( number, BOOLEAN /*setChar*/, const coeffs)
230{
231  CanonicalForm term(0);
232  Werror("no conversion to factory");
233  return term;
234}
235
236number ndConvFactoryNSingN( const CanonicalForm, const coeffs)
237{
238  Werror("no conversion from factory");
239  return NULL;
240}
241
242number  ndInit_bigint(number, const coeffs, const coeffs)
243{
244  Werror("no conversion from bigint to this field");
245  return NULL;
246}
247
248/**< [in, out] a bigint number >= 0  */
249/**< [out] the GMP equivalent    */
250/// Converts a non-negative bigint number into a GMP number.
251void ndMPZ(mpz_t result, number &n, const coeffs r)
252{
253  mpz_init_set_si( result, n_Int(n, r) );
254}
255
256number ndInitMPZ(mpz_t m, const coeffs r)
257{ 
258  return n_Init( mpz_get_si(m), r);
259}
260
261
262BOOLEAN ndCoeffIsEqual(const coeffs r, n_coeffType n, void *)
263{
264  /* test, if r is an instance of nInitCoeffs(n,parameter) */
265  /* if paramater is not needed */
266  return (n==r->type);
267}
268
269static n_coeffType nLastCoeffs=n_CF;
270cfInitCharProc nInitCharTableDefault[]=
271{ NULL,        /*n_unknown */
272 npInitChar,   /* n_Zp */
273 nlInitChar,   /* n_Q */
274 nrInitChar,   /* n_R */
275 nfInitChar,   /* n_GF */
276 ngfInitChar,  /* n_long_R */
277 #ifdef HAVE_POLYEXTENSIONS
278 naInitChar,  /* n_algExt */
279 ntInitChar,  /* n_transExt */
280 #else
281 NULL,        /* n_algExt */
282 NULL,        /* n_transExt */
283 #endif   
284 ngcInitChar,  /* n_long_C */
285 #ifdef HAVE_RINGS
286 nrzInitChar,  /* n_Z */
287 nrnInitChar,  /* n_Zn */
288 nrnInitChar,  /* n_Znm */
289 nr2mInitChar, /* n_Z2m */
290 #else
291 NULL,         /* n_Z */
292 NULL,         /* n_Zn */
293 NULL,         /* n_Znm */
294 NULL,         /* n_Z2m */
295 #endif
296 NULL   /* n_CF */
297};
298
299static cfInitCharProc *nInitCharTable=nInitCharTableDefault;
300/*2
301* init operations for coeffs r
302*/
303coeffs nInitChar(n_coeffType t, void * parameter)
304{
305  n_Procs_s *n=cf_root;
306
307  while((n!=NULL) && (n->nCoeffIsEqual!=NULL) && (!n->nCoeffIsEqual(n,t,parameter)))
308      n=n->next;
309
310  if (n==NULL)
311  {
312    n=(n_Procs_s*)omAlloc0(sizeof(n_Procs_s));
313    n->next=cf_root;
314    n->ref=1;
315    n->type=t;
316
317    // default entries (different from NULL) for some routines:
318    n->nCoeffIsEqual = ndCoeffIsEqual;
319    n->cfSize = ndSize;
320    n->cfGetDenom= ndGetDenom;
321    n->cfGetNumerator= ndGetNumerator;
322    n->cfName =  ndName;
323    n->cfImPart=ndReturn0;
324    n->cfDelete= ndDelete;
325    n->cfInpMult=ndInpMult;
326    n->cfInpAdd=ndInpAdd;
327    n->cfCopy = ndCopy;
328    n->cfIntMod=ndIntMod; /* dummy !! */
329    n->cfNormalize=ndNormalize;
330    n->cfGcd  = ndGcd;
331    n->cfLcm  = ndGcd; /* tricky, isn't it ?*/
332    n->cfInit_bigint = ndInit_bigint;
333    n->cfInitMPZ = ndInitMPZ;
334    n->cfMPZ = ndMPZ;
335
336    // n->cfKillChar = ndKillChar; /* dummy */
337    n->cfSetChar = ndSetChar; /* dummy */
338    // temp. removed to catch all the coeffs which miss to implement this!
339
340    n->cfChineseRemainder = ndChineseRemainder;
341    n->cfFarey = ndFarey;
342    n->cfParDeg = ndParDeg;
343   
344    n->cfParameter = ndParameter;
345
346    n->cfClearContent = ndClearContent;
347    n->cfClearDenominators = ndClearDenominators;
348
349#ifdef HAVE_RINGS
350    n->cfDivComp = ndDivComp;
351    n->cfDivBy = ndDivBy;
352    n->cfIsUnit = ndIsUnit;
353    n->cfExtGcd = ndExtGcd;
354    //n->cfGetUnit = (nMapFunc)NULL;
355#endif
356
357#ifdef fACTORY
358    n->convSingNFactoryN=ndConvSingNFactoryN;
359    n->convFactoryNSingN=ndConvFactoryNSingN;
360#endif
361   
362    BOOLEAN nOK=TRUE;
363    // init
364    if ((t<=nLastCoeffs) && (nInitCharTable[t]!=NULL))
365      nOK = (nInitCharTable[t])(n,parameter);
366    else
367       Werror("Sorry: the coeff type [%d] was not registered: it is missing in nInitCharTable", (int)t);
368    if (nOK)
369    {
370      omFreeSize(n,sizeof(*n));
371      return NULL;
372    }
373    cf_root=n;
374    // post init settings:
375    if (n->cfRePart==NULL) n->cfRePart=n->cfCopy;
376    if (n->cfIntDiv==NULL) n->cfIntDiv=n->cfDiv;
377   
378#ifdef HAVE_RINGS
379    if (n->cfGetUnit==NULL) n->cfGetUnit=n->cfCopy;
380#endif
381
382    if(n->cfWriteShort==NULL)
383      n->cfWriteShort = n->cfWriteLong;
384
385    assume(n->nCoeffIsEqual!=NULL);
386    assume(n->cfSetChar!=NULL);
387    assume(n->cfMult!=NULL);
388    assume(n->cfSub!=NULL);
389    assume(n->cfAdd!=NULL);
390    assume(n->cfDiv!=NULL);
391    assume(n->cfIntDiv!=NULL);
392    assume(n->cfIntMod!=NULL);
393    assume(n->cfExactDiv!=NULL);
394    assume(n->cfInit!=NULL);
395    assume(n->cfInitMPZ!=NULL);
396    assume(n->cfSize!=NULL);
397    assume(n->cfInt!=NULL);
398    assume(n->cfMPZ!=NULL);
399    //assume(n->n->cfDivComp!=NULL);
400    //assume(n->cfIsUnit!=NULL);
401    //assume(n->cfGetUnit!=NULL);
402    //assume(n->cfExtGcd!=NULL);
403    assume(n->cfNeg!=NULL);
404    assume(n->cfCopy!=NULL);
405    assume(n->cfRePart!=NULL);
406    assume(n->cfImPart!=NULL);
407
408    assume(n->cfWriteLong!=NULL);
409    assume(n->cfWriteShort!=NULL);
410
411    assume(n->iNumberOfParameters>= 0);
412
413    assume( (n->iNumberOfParameters == 0 && n->pParameterNames == NULL) ||
414            (n->iNumberOfParameters >  0 && n->pParameterNames != NULL) );           
415
416    assume(n->cfParameter!=NULL);
417    assume(n->cfParDeg!=NULL);
418     
419    assume(n->cfRead!=NULL);
420    assume(n->cfNormalize!=NULL);
421    assume(n->cfGreater!=NULL);
422    //assume(n->cfDivBy!=NULL);
423    assume(n->cfEqual!=NULL);
424    assume(n->cfIsZero!=NULL);
425    assume(n->cfIsOne!=NULL);
426    assume(n->cfIsMOne!=NULL);
427    assume(n->cfGreaterZero!=NULL);
428    assume(n->cfPower!=NULL);
429    assume(n->cfGetDenom!=NULL);
430    assume(n->cfGetNumerator!=NULL);
431    assume(n->cfGcd!=NULL);
432    assume(n->cfLcm!=NULL);
433    assume(n->cfDelete!=NULL);
434    assume(n->cfSetMap!=NULL);
435    assume(n->cfName!=NULL);
436    assume(n->cfInpMult!=NULL);
437//    assume(n->cfInit_bigint!=NULL);
438    assume(n->cfCoeffWrite != NULL);
439
440    assume(n->cfClearContent != NULL);
441    assume(n->cfClearDenominators != NULL);
442   
443#ifdef LDEBUG
444    if(n->cfDBTest==NULL)
445    { n->cfDBTest=ndDBTest;Warn("cfDBTest is NULL for coeff %d",t); }
446#endif
447    assume(n->type==t);
448     
449#ifndef NDEBUG
450    if(n->cfKillChar==NULL) Warn("cfKillChar is NULL for coeff %d",t);
451    if(n->cfWriteLong==NULL) Warn("cfWrite is NULL for coeff %d",t);
452    if(n->cfWriteShort==NULL) Warn("cfWriteShort is NULL for coeff %d",t);
453#endif
454     
455   if( n->nNULL == NULL )
456     n->nNULL = n_Init(0, n); // may still remain NULL
457  }
458  else
459  {
460    n->ref++;
461  }
462  return n;
463}
464
465void nKillChar(coeffs r)
466{
467  if (r!=NULL)
468  {
469    r->ref--;
470    if (r->ref<=0)
471    {
472      n_Procs_s tmp;
473      n_Procs_s* n=&tmp;
474      tmp.next=cf_root;
475      while((n->next!=NULL) && (n->next!=r)) n=n->next;
476      if (n->next==r)
477      {
478        n->next=n->next->next;
479        if (cf_root==r) cf_root=n->next;
480        r->cfDelete(&(r->nNULL),r);
481        if (r->cfKillChar!=NULL) r->cfKillChar(r);
482        omFreeSize((void *)r, sizeof(n_Procs_s));
483        r=NULL;
484      }
485      else
486      {
487        WarnS("cf_root list destroyed");
488      }
489    }
490  }
491}
492
493
494n_coeffType nRegister(n_coeffType n, cfInitCharProc p)
495{
496  if (n==n_unknown)
497  {
498    nLastCoeffs=(n_coeffType)(int(nLastCoeffs)+1);
499    if (nInitCharTable==nInitCharTableDefault)
500    {
501      nInitCharTable=(cfInitCharProc*)omAlloc0(
502                                          nLastCoeffs*sizeof(cfInitCharProc));
503      memcpy(nInitCharTable,nInitCharTableDefault,
504              (nLastCoeffs-1)*sizeof(cfInitCharProc));
505    }
506    else
507    {
508      nInitCharTable=(cfInitCharProc*)omReallocSize(nInitCharTable,
509                                          (((int)nLastCoeffs)-1)*sizeof(cfInitCharProc),
510                                          ((int)nLastCoeffs)*sizeof(cfInitCharProc));
511    }
512
513    nInitCharTable[nLastCoeffs]=p;
514    return nLastCoeffs;
515  }
516  else
517  {
518    if (nInitCharTable[n]!=NULL) Print("coeff %d already initialized\n",n);
519    nInitCharTable[n]=p;
520    return n;
521  }
522}
523
524
525void n_Print(number& a,  const coeffs r)
526{ 
527   assume(r != NULL); 
528   n_Test(a,r); 
529   
530   StringSetS(""); 
531   n_Write(a, r); 
532   { char* s = StringEndS(); Print("%s", s); omFree(s); }
533}
Note: See TracBrowser for help on using the repository browser.