source: git/libpolys/coeffs/numbers.cc @ 16f511

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