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

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