source: git/libpolys/coeffs/numbers.cc @ 88cceb

spielwiese
Last change on this file since 88cceb was 88cceb, checked in by Hans Schoenemann <hannes@…>, 9 years ago
fix: n_Lcm is not n_NormalizeHelper
  • Property mode set to 100644
File size: 13.4 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
71#ifdef LDEBUG
72void   nDBDummy1(number* d,char *, int) { *d=NULL; }
73BOOLEAN ndDBTest(number, const char *, const int, const coeffs)
74{
75  return TRUE;
76}
77#endif
78
79number ndFarey(number,number,const coeffs r)
80{
81  Werror("farey not implemented for %s (c=%d)",r->cfCoeffString(r),getCoeffType(r));
82  return NULL;
83}
84number ndChineseRemainder(number *,number *,int,BOOLEAN,const coeffs r)
85{
86  Werror("ChineseRemainder not implemented for %s (c=%d)",r->cfCoeffString(r),getCoeffType(r));
87  return n_Init(0,r); 
88}
89
90static int ndParDeg(number n, const coeffs r)
91{
92  return (-n_IsZero(n,r));
93}
94
95static number ndParameter(const int, const coeffs r)
96{
97  Werror("ndParameter: n_Parameter is not implemented/relevant for (coeff_type = %d)",getCoeffType(r));
98  return NULL;
99}
100
101BOOLEAN n_IsZeroDivisor( number a, const coeffs r)
102{
103  int c = n_GetChar(r);
104  BOOLEAN ret = n_IsZero(a, r);
105  if( (c != 0) && !ret )
106  {
107    number ch = n_Init( c, r ); 
108    number g = n_Gcd( ch, a, r );
109    ret = !n_IsOne (g, r);
110    n_Delete(&ch, r);
111    n_Delete(&g, r);
112  }
113  return ret; 
114}
115
116void   ndNormalize(number&, const coeffs) { }
117
118char * ndName(number, const coeffs) { return NULL; }
119
120number ndReturn0(number, const coeffs r) { return n_Init(0,r); }
121
122number ndGcd(number, number, const coeffs r) { return n_Init(1,r); }
123
124number ndIntMod(number, number, const coeffs r) { return n_Init(0,r); }
125
126number ndGetDenom(number &, const coeffs r) { return n_Init(1,r); }
127number ndGetNumerator(number &a,const coeffs r) { return n_Copy(a,r); }
128
129int ndSize(number a, const coeffs r) { return (int)n_IsZero(a,r)==FALSE; }
130
131void ndClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
132{
133  assume(r != NULL);
134
135  // no fractions
136  assume(!(  nCoeff_is_Q(r) ));
137  // all coeffs are given by integers!!!
138
139  numberCollectionEnumerator.Reset();
140
141  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
142  {
143    c = n_Init(1, r);
144    return;
145  } 
146
147  number &curr = numberCollectionEnumerator.Current();
148 
149#ifdef HAVE_RINGS
150  /// TODO: move to a separate implementation
151  if (nCoeff_is_Ring(r))
152  {
153    if (nCoeff_has_Units(r))
154    {
155      c = n_GetUnit(curr, r);
156     
157      if (!n_IsOne(c, r))
158      {
159        number inv = n_Invers(c, r);
160
161        n_InpMult(curr, inv, r);
162       
163        while( numberCollectionEnumerator.MoveNext() )
164        {
165          number &n = numberCollectionEnumerator.Current();
166          n_Normalize(n, r); // ?
167          n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
168        }
169
170        n_Delete(&inv, r);       
171      }     
172    } else c = n_Init(1, r);
173   
174    return;
175  }
176#endif
177
178  assume(!nCoeff_is_Ring(r));
179  assume(nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) || nCoeff_is_Zp_a(r) || nCoeff_is_Q_algext(r));
180
181  n_Normalize(curr, r); // Q: good/bad/ugly??
182
183  if (!n_IsOne(curr, r))
184  {
185    number t = curr; // takes over the curr! note: not a reference!!!
186
187    curr = n_Init(1, r); // ???
188   
189    number inv = n_Invers(t, r);
190   
191    while( numberCollectionEnumerator.MoveNext() )
192    {
193      number &n = numberCollectionEnumerator.Current();
194      n_InpMult(n, inv, r); // TODO: either this or directly divide!!!?
195//      n_Normalize(n, r); // ?
196    }
197   
198    n_Delete(&inv, r);
199
200    c = t;
201  } else
202    c = n_Copy(curr, r); // c == 1 and nothing else to do...
203}
204
205void ndClearDenominators(ICoeffsEnumerator& /*numberCollectionEnumerator*/, number& d, const coeffs r)
206{
207  assume( r != NULL );
208  assume( !(nCoeff_is_Q(r) || nCoeff_is_transExt(r) || nCoeff_is_algExt(r)) );
209  assume( nCoeff_is_Ring(r) || nCoeff_is_Zp(r) || nCoeff_is_numeric(r) || nCoeff_is_GF(r) );
210
211  d = n_Init(1, r);
212}
213
214number ndCopy(number a, const coeffs) { return a; }
215number ndCopyMap(number a, const coeffs aRing, const coeffs r)
216{
217  assume( getCoeffType(r) == getCoeffType(aRing) );
218  if ( nCoeff_has_simple_Alloc(r) && nCoeff_has_simple_Alloc(aRing) )
219    return a;
220        else
221    return n_Copy(a, r);
222}
223void ndKillChar(coeffs) {}
224void ndSetChar(const coeffs) {}
225
226number nd_Copy(number a, const coeffs r) { return n_Copy(a, r); }
227
228#ifdef HAVE_RINGS
229BOOLEAN ndDivBy(number, number, const coeffs) { return TRUE; } // assume a,b !=0
230int ndDivComp(number, number, const coeffs) { return 2; }
231BOOLEAN ndIsUnit(number a, const coeffs r) { return !n_IsZero(a,r); }
232number  ndExtGcd (number, number, number *, number *, const coeffs r) { return n_Init(1,r); }
233#endif
234
235CanonicalForm ndConvSingNFactoryN( number, BOOLEAN /*setChar*/, const coeffs)
236{
237  CanonicalForm term(0);
238  Werror("no conversion to factory");
239  return term;
240}
241
242number ndConvFactoryNSingN( const CanonicalForm, const coeffs)
243{
244  Werror("no conversion from factory");
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->cfAnn = ndAnn;
326    n->cfCoeffString = ndCoeffString; // should alway be changed!
327    n->cfInpMult=ndInpMult;
328    n->cfInpAdd=ndInpAdd;
329    n->cfCopy = ndCopy;
330    n->cfIntMod=ndIntMod; /* dummy !! */
331    n->cfNormalize=ndNormalize;
332    n->cfGcd  = ndGcd;
333    n->cfNormalizeHelper  = ndGcd; /* tricky, isn't it ?*/
334    n->cfLcm  = ndGcd; /* tricky, isn't it ?*/
335    n->cfInitMPZ = ndInitMPZ;
336    n->cfMPZ = ndMPZ;
337
338    // n->cfKillChar = ndKillChar; /* dummy */
339    n->cfSetChar = ndSetChar; /* dummy */
340    // temp. removed to catch all the coeffs which miss to implement this!
341
342    n->cfChineseRemainder = ndChineseRemainder;
343    n->cfFarey = ndFarey;
344    n->cfParDeg = ndParDeg;
345   
346    n->cfParameter = ndParameter;
347
348    n->cfClearContent = ndClearContent;
349    n->cfClearDenominators = ndClearDenominators;
350
351#ifdef HAVE_RINGS
352    n->cfDivComp = ndDivComp;
353    n->cfDivBy = ndDivBy;
354    n->cfIsUnit = ndIsUnit;
355    n->cfExtGcd = ndExtGcd;
356    //n->cfGetUnit = (nMapFunc)NULL;
357#endif
358
359#ifdef fACTORY
360    n->convSingNFactoryN=ndConvSingNFactoryN;
361    n->convFactoryNSingN=ndConvFactoryNSingN;
362#endif
363   
364    BOOLEAN nOK=TRUE;
365    // init
366    if ((t<=nLastCoeffs) && (nInitCharTable[t]!=NULL))
367      nOK = (nInitCharTable[t])(n,parameter);
368    else
369       Werror("Sorry: the coeff type [%d] was not registered: it is missing in nInitCharTable", (int)t);
370    if (nOK)
371    {
372      omFreeSize(n,sizeof(*n));
373      return NULL;
374    }
375    cf_root=n;
376    // post init settings:
377    if (n->cfRePart==NULL) n->cfRePart=n->cfCopy;
378    if (n->cfExactDiv==NULL) n->cfExactDiv=n->cfDiv;
379    if (n->cfSubringGcd==NULL) n->cfSubringGcd=n->cfGcd;
380   
381#ifdef HAVE_RINGS
382    if (n->cfGetUnit==NULL) n->cfGetUnit=n->cfCopy;
383#endif
384
385    if(n->cfWriteShort==NULL)
386      n->cfWriteShort = n->cfWriteLong;
387
388    assume(n->nCoeffIsEqual!=NULL);
389    assume(n->cfSetChar!=NULL);
390    assume(n->cfCoeffString!=ndCoeffString);
391    assume(n->cfMult!=NULL);
392    assume(n->cfSub!=NULL);
393    assume(n->cfAdd!=NULL);
394    assume(n->cfDiv!=NULL);
395    assume(n->cfIntMod!=NULL);
396    assume(n->cfExactDiv!=NULL);
397    assume(n->cfInit!=NULL);
398    assume(n->cfInitMPZ!=NULL);
399    assume(n->cfSize!=NULL);
400    assume(n->cfInt!=NULL);
401    assume(n->cfMPZ!=NULL);
402    //assume(n->n->cfDivComp!=NULL);
403    //assume(n->cfIsUnit!=NULL);
404    //assume(n->cfGetUnit!=NULL);
405    //assume(n->cfExtGcd!=NULL);
406    assume(n->cfInpNeg!=NULL);
407    assume(n->cfCopy!=NULL);
408
409    assume(n->cfWriteLong!=NULL);
410    assume(n->cfWriteShort!=NULL);
411
412    assume(n->iNumberOfParameters>= 0);
413
414    assume( (n->iNumberOfParameters == 0 && n->pParameterNames == NULL) ||
415            (n->iNumberOfParameters >  0 && n->pParameterNames != NULL) );           
416
417    assume(n->cfParameter!=NULL);
418    assume(n->cfParDeg!=NULL);
419     
420    assume(n->cfRead!=NULL);
421    assume(n->cfNormalize!=NULL);
422    assume(n->cfGreater!=NULL);
423    //assume(n->cfDivBy!=NULL);
424    assume(n->cfEqual!=NULL);
425    assume(n->cfIsZero!=NULL);
426    assume(n->cfIsOne!=NULL);
427    assume(n->cfIsMOne!=NULL);
428    assume(n->cfGreaterZero!=NULL);
429    assume(n->cfPower!=NULL);
430    assume(n->cfGetDenom!=NULL);
431    assume(n->cfGetNumerator!=NULL);
432    assume(n->cfGcd!=NULL);
433    assume(n->cfNormalizeHelper!=NULL);
434    assume(n->cfDelete!=NULL);
435    assume(n->cfSetMap!=NULL);
436    assume(n->cfName!=NULL);
437    assume(n->cfInpMult!=NULL);
438//    assume(n->cfInit_bigint!=NULL);
439    assume(n->cfCoeffWrite != NULL);
440
441    assume(n->cfClearContent != NULL);
442    assume(n->cfClearDenominators != NULL);
443   
444#ifdef LDEBUG
445    if(n->cfDBTest==NULL)
446    { n->cfDBTest=ndDBTest;Warn("cfDBTest is NULL for coeff %d",t); }
447#endif
448    assume(n->type==t);
449     
450#ifndef SING_NDEBUG
451    if(n->cfKillChar==NULL) Warn("cfKillChar is NULL for coeff %d",t);
452    if(n->cfWriteLong==NULL) Warn("cfWrite is NULL for coeff %d",t);
453    if(n->cfWriteShort==NULL) Warn("cfWriteShort is NULL for coeff %d",t);
454    if(n->cfCoeffString==ndCoeffString) Warn("cfCoeffString is undefined for coeff %d",t);
455#endif
456     
457   if( n->nNULL == NULL )
458     n->nNULL = n_Init(0, n); // may still remain NULL
459  }
460  else
461  {
462    n->ref++;
463  }
464  return n;
465}
466
467void nKillChar(coeffs r)
468{
469  if (r!=NULL)
470  {
471    r->ref--;
472    if (r->ref<=0)
473    {
474      n_Procs_s tmp;
475      n_Procs_s* n=&tmp;
476      tmp.next=cf_root;
477      while((n->next!=NULL) && (n->next!=r)) n=n->next;
478      if (n->next==r)
479      {
480        n->next=n->next->next;
481        if (cf_root==r) cf_root=n->next;
482        r->cfDelete(&(r->nNULL),r);
483        if (r->cfKillChar!=NULL) r->cfKillChar(r);
484        omFreeSize((void *)r, sizeof(n_Procs_s));
485        r=NULL;
486      }
487      else
488      {
489        WarnS("cf_root list destroyed");
490      }
491    }
492  }
493}
494
495
496n_coeffType nRegister(n_coeffType n, cfInitCharProc p)
497{
498  if (n==n_unknown)
499  {
500    nLastCoeffs=(n_coeffType)(int(nLastCoeffs)+1);
501    if (nInitCharTable==nInitCharTableDefault)
502    {
503      nInitCharTable=(cfInitCharProc*)omAlloc0(
504                                          ((int)nLastCoeffs+1)*sizeof(cfInitCharProc));
505      memcpy(nInitCharTable,nInitCharTableDefault,
506              ((int)nLastCoeffs)*sizeof(cfInitCharProc));
507    }
508    else
509    {
510      nInitCharTable=(cfInitCharProc*)omReallocSize(nInitCharTable,
511                                          ((int)nLastCoeffs)*sizeof(cfInitCharProc),
512                                          (((int)nLastCoeffs)+1)*sizeof(cfInitCharProc));
513    }
514
515    nInitCharTable[nLastCoeffs]=p;
516    return nLastCoeffs;
517  }
518  else
519  {
520    if (nInitCharTable[n]!=NULL) Print("coeff %d already initialized\n",n);
521    nInitCharTable[n]=p;
522    return n;
523  }
524}
525
526
527void n_Print(number& a,  const coeffs r)
528{ 
529   assume(r != NULL); 
530   n_Test(a,r); 
531   
532   StringSetS(""); 
533   n_Write(a, r); 
534   { char* s = StringEndS(); Print("%s", s); omFree(s); }
535}
Note: See TracBrowser for help on using the repository browser.