source: git/libpolys/coeffs/coeffs.h @ a44bcf

spielwiese
Last change on this file since a44bcf was b56249, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Misc fixes due to building on Mac OS X 10.6 fix: no pyobject-building if configured without dynamic loading chg: minor include reordering + forward declarations + cosmetics fix: AM_COND_IF may be undefined in older automake/autoconf fix: distribute ALL tested tests fix: no double definition of NATNUMBER/int_number in structs.h fix: n_ExtGcd is not always related to HAVE_RINGS
  • Property mode set to 100644
File size: 32.4 KB
RevLine 
[7d90aa]1#ifndef COEFFS_H
2#define COEFFS_H
3/****************************************
4*  Computer Algebra System SINGULAR     *
5****************************************/
6/*
7* ABSTRACT
8*/
9
[18cb65]10#include <misc/auxiliary.h>
[227efd]11/* for assume: */
[18cb65]12#include <reporter/reporter.h>
[9144617]13
[2d805a]14#include <coeffs/si_gmp.h>
[7d90aa]15
[98474f]16#include <coeffs/Enumerator.h>
17
[eca225]18#ifdef HAVE_FACTORY
[9eb0f9]19class CanonicalForm;
[eca225]20#endif
21
[7d90aa]22enum n_coeffType
23{
24  n_unknown=0,
[b807aa0]25  n_Zp, /**< \F{p < ?} */
26  n_Q,  /**< rational (GMP) numbers */
27  n_R,  /**< single prescision (6,6) real numbers */
28  n_GF, /**< \GF{p^n < 32001?} */
29  n_long_R, /**< real (GMP) numbers */
[e676cd]30  n_algExt,  /**< used for all algebraic extensions, i.e.,
[141342]31                the top-most extension in an extension tower
32                is algebraic */
[e676cd]33  n_transExt,  /**< used for all transcendental extensions, i.e.,
[141342]34                  the top-most extension in an extension tower
35                  is transcendental */
[b807aa0]36  n_long_C, /**< complex (GMP) numbers */
37  n_Z, /**< only used if HAVE_RINGS is defined: ? */
38  n_Zn, /**< only used if HAVE_RINGS is defined: ? */
[ea25bc]39  n_Znm, /**< only used if HAVE_RINGS is defined: ? */
[b807aa0]40  n_Z2m, /**< only used if HAVE_RINGS is defined: ? */
41  n_CF /**< ? */
[7d90aa]42};
43
[dfc60c8]44extern unsigned short fftable[];
45
[91a305]46struct snumber;
47typedef struct snumber *   number;
48
[2bd9ca]49/* standard types */
50#ifdef HAVE_RINGS
51typedef unsigned long NATNUMBER;
52typedef mpz_ptr int_number;
53#endif
54
[4c6e420]55struct ip_sring;
56typedef struct ip_sring *         ring;
[cd9796]57typedef struct ip_sring const *   const_ring;
[4c6e420]58
[7d90aa]59struct n_Procs_s;
60typedef struct  n_Procs_s  *coeffs;
[cd9796]61typedef struct  n_Procs_s  const * const_coeffs;
[7d90aa]62
[94b759]63typedef number (*numberfunc)(number a, number b, const coeffs r);
[7d90aa]64
[dc093ce]65/// maps "a", which lives in src, into dst
66typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
[94b759]67
[98474f]68
69/// Abstract interface for an enumerator of number coefficients for an
70/// object, e.g. a polynomial
71typedef IEnumerator<number> ICoeffsEnumerator;
72
73/// goes over coeffs given by the ICoeffsEnumerator and changes them.
74/// Additionally returns a number;
75typedef void (*nCoeffsEnumeratorFunc)(ICoeffsEnumerator& numberCollectionEnumerator, number& output, const coeffs r);
76
77
[920581]78/// Creation data needed for finite fields
79typedef struct 
80{
81  int GFChar;
82  int GFDegree;
83  const char* GFPar_name;
84} GFInfo;
85
[32cc7e]86typedef struct
87{
88  short      float_len; /**< additional char-flags, rInit */
89  short      float_len2; /**< additional char-flags, rInit */
90  const char* par_name; /**< parameter name */
91} LongComplexInfo;
[920581]92
[7d90aa]93struct n_Procs_s
94{
95   coeffs next;
[66ce6d]96   /*unsigned int ringtype;   =0 => coefficient field,
[f0797c]97                             !=0 => coeffs from one of the rings:
98                              =1 => Z/2^mZ
99                              =2 => Z/nZ, n not a prime
100                              =3 => Z/p^mZ
101                              =4 => Z */
[8e0242]102
[8f8b75]103   // general properties:
[193c6b]104   /// TRUE, if nNew/nDelete/nCopy are dummies
105   BOOLEAN has_simple_Alloc;
106   /// TRUE, if std should make polynomials monic (if nInvers is cheap)
[3dbe0bf]107   /// if false, then a gcd routine is used for a content computation
[193c6b]108   BOOLEAN has_simple_Inverse;
[8f8b75]109
110   // tests for numbers.cc:
[aff5ae]111   BOOLEAN (*nCoeffIsEqual)(const coeffs r, n_coeffType n, void * parameter);
[8f8b75]112
[c7e3d7]113   /// output of coeff description via Print
[03f7b5]114   void (*cfCoeffWrite)(const coeffs r, BOOLEAN details);
[c7e3d7]115
[94b759]116   // ?
[3de81d0]117   // initialisation:
[4d92d7]118   //void (*cfInitChar)(coeffs r, int parameter); // do one-time initialisations
[3de81d0]119   void (*cfKillChar)(coeffs r); //  undo all initialisations
120                                // or NULL
[2336d0]121   void (*cfSetChar)(const coeffs r); // initialisations after each ring change
[3de81d0]122                                // or NULL
[7d90aa]123   // general stuff
[7bbbef]124   numberfunc cfMult, cfSub ,cfAdd ,cfDiv, cfIntDiv, cfIntMod, cfExactDiv;
[045efb]125   
[8e0242]126   /// init with an integer
[2f3764]127   number  (*cfInit)(long i,const coeffs r);
[045efb]128
129   /// init with a GMP integer
130   number  (*cfInitMPZ)(mpz_t i, const coeffs r);
131   
[77e585]132   /// how complicated, (0) => 0, or positive
[7bbbef]133   int     (*cfSize)(number n, const coeffs r);
[045efb]134   
135   /// convertion to int, 0 if impossible
[7bbbef]136   int     (*cfInt)(number &n, const coeffs r);
[b12b7c]137
[045efb]138   /// Converts a non-negative number n into a GMP number, 0 if impossible
139   void     (*cfMPZ)(mpz_t result, number &n, const coeffs r);
140   
[db3180c]141   /// changes argument  inline: a:= -a
[0461f0]142   /// return -a! (no copy is returned)
143   /// the result should be assigned to the original argument: e.g. a = n_Neg(a,r)
[7bbbef]144   number  (*cfNeg)(number a, const coeffs r);
[db3180c]145   /// return 1/a
[7bbbef]146   number  (*cfInvers)(number a, const coeffs r);
[db3180c]147   /// return a copy of a
[7d90aa]148   number  (*cfCopy)(number a, const coeffs r);
[7bbbef]149   number  (*cfRePart)(number a, const coeffs r);
150   number  (*cfImPart)(number a, const coeffs r);
[ce1f78]151
152   /// print a given number (long format)
153   void    (*cfWriteLong)(number &a, const coeffs r);
154   
155   /// print a given number in a shorter way, if possible
156   /// e.g. in K(a): a2 instead of a^2
157   void    (*cfWriteShort)(number &a, const coeffs r);
158   
[7bbbef]159   const char *  (*cfRead)(const char * s, number * a, const coeffs r);
160   void    (*cfNormalize)(number &a, const coeffs r);
[b56249]161   
[7d90aa]162#ifdef HAVE_RINGS
[b56249]163   int     (*cfDivComp)(number a,number b,const coeffs r);
164   BOOLEAN (*cfIsUnit)(number a,const coeffs r);
165   number  (*cfGetUnit)(number a,const coeffs r);
166   BOOLEAN (*cfDivBy)(number a, number b, const coeffs r);
[7d90aa]167#endif
[b56249]168
169   
170   BOOLEAN (*cfGreater)(number a,number b, const coeffs r),
[77e585]171            /// tests
[7bbbef]172           (*cfEqual)(number a,number b, const coeffs r),
173           (*cfIsZero)(number a, const coeffs r),
174           (*cfIsOne)(number a, const coeffs r),
175           (*cfIsMOne)(number a, const coeffs r),
176           (*cfGreaterZero)(number a, const coeffs r);
[8a8c9e]177
[7bbbef]178   void    (*cfPower)(number a, int i, number * result, const coeffs r);
[7d90aa]179   number  (*cfGetDenom)(number &n, const coeffs r);
180   number  (*cfGetNumerator)(number &n, const coeffs r);
[7bbbef]181   number  (*cfGcd)(number a, number b, const coeffs r);
[3216ec]182   number  (*cfExtGcd)(number a, number b, number *s, number *t,const coeffs r);
[7bbbef]183   number  (*cfLcm)(number a, number b, const coeffs r);
[7d90aa]184   void    (*cfDelete)(number * a, const coeffs r);
185   nMapFunc (*cfSetMap)(const coeffs src, const coeffs dst);
[77e585]186
187   /// For extensions (writes into global string buffer)
[7bbbef]188   char *  (*cfName)(number n, const coeffs r);
[77e585]189
[eca225]190   /// Inplace: a *= b
[7bbbef]191   void    (*cfInpMult)(number &a, number b, const coeffs r);
[61b2e16]192
[860bce]193   /// maps the bigint i (from dummy == coeffs_BIGINT!!!) into the
[61b2e16]194   /// coeffs dst
195   /// TODO: to be exchanged with a map!!!
[7bbbef]196   number  (*cfInit_bigint)(number i, const coeffs dummy, const coeffs dst);
[77e585]197
[7938a0f]198   /// rational reconstruction: best rational with mod p=n
199   number  (*cfFarey)(number p, number n, const coeffs);
200
201   /// chinese remainder
202   /// returns X with X mod q[i]=x[i], i=0..rl-1
[de27d8]203   number  (*cfChineseRemainder)(number *x, number *q,int rl, BOOLEAN sym,const coeffs);
[7938a0f]204
[48a41a]205   /// degree for coeffcients: -1 for 0, 0 for "constants", ...
206   int (*cfParDeg)(number x,const coeffs r);
207
[7fee876]208   /// create i^th parameter or NULL if not possible
209   number  (*cfParameter)(const int i, const coeffs r);
[98474f]210       
211   /// function pointer behind n_ClearContent
212   nCoeffsEnumeratorFunc cfClearContent;
213
214   /// function pointer behind n_ClearDenominators
215   nCoeffsEnumeratorFunc cfClearDenominators;
[7fee876]216
[eca225]217#ifdef HAVE_FACTORY
218   number (*convFactoryNSingN)( const CanonicalForm n, const coeffs r);
[abb4787]219   CanonicalForm (*convSingNFactoryN)( number n, BOOLEAN setChar, const coeffs r );
[eca225]220#endif
221
222
[7d90aa]223#ifdef LDEBUG
[bd6142]224   /// Test: is "a" a correct number?
[b12b7c]225   BOOLEAN (*cfDBTest)(number a, const char *f, const int l, const coeffs r);
[7d90aa]226#endif
227
[f630e4]228   /// the 0 as constant, NULL by default
229   number nNULL; 
[7d90aa]230   int     char_flag;
231   int     ref;
[fc4977]232   /// how many variables of factort are already used by this coeff
233   int     factoryVarOffset;
[7d90aa]234   n_coeffType type;
[e77676]235
[7fee876]236
237   /// Number of Parameters in the coeffs (default 0)
238   int iNumberOfParameters;
239
240   /// array containing the names of Parameters (default NULL)
241   char const * const * pParameterNames;
242   // NOTE that it replaces the following:
243// char* complex_parameter; //< the name of sqrt(-1) in n_long_C , i.e. 'i' or 'j' etc...?
244// char * m_nfParameter; //< the name of parameter in n_GF
245
[e77676]246   /////////////////////////////////////////////
247   // the union stuff
248
249   //-------------------------------------------
[4c6e420]250
[488808e]251  /* for extension fields we need to be able to represent polynomials,
252     so here is the polynomial ring: */
[6ccdd3a]253  ring          extRing;
[488808e]254
[e676cd]255  //number     minpoly;  //< no longer needed: replaced by
[dd668f]256  //                     //< extRing->qideal->[0]
[4c6e420]257
258
259//-------------------------------------------
[7d90aa]260#ifdef HAVE_RINGS
[e90dfd6]261  /* The following members are for representing the ring Z/n,
[aec5c9]262     where n is not a prime. We distinguish four cases:
[e90dfd6]263     1.) n has at least two distinct prime factors. Then
264         modBase stores n, modExponent stores 1, modNumber
265         stores n, and mod2mMask is not used;
266     2.) n = p^k for some odd prime p and k > 1. Then
267         modBase stores p, modExponent stores k, modNumber
268         stores n, and mod2mMask is not used;
269     3.) n = 2^k for some k > 1; moreover, 2^k - 1 fits in
270         an unsigned long. Then modBase stores 2, modExponent
271         stores k, modNumber is not used, and mod2mMask stores
272         2^k - 1, i.e., the bit mask '111..1' of length k.
273     4.) n = 2^k for some k > 1; but 2^k - 1 does not fit in
274         an unsigned long. Then modBase stores 2, modExponent
275         stores k, modNumber stores n, and mod2mMask is not
276         used;
277     Cases 1.), 2.), and 4.) are covered by the implementation
278     in the files rmodulon.h and rmodulon.cc, whereas case 3.)
279     is implemented in the files rmodulo2m.h and rmodulo2m.cc. */
280  int_number    modBase;
281  unsigned long modExponent;
282  int_number    modNumber;
283  unsigned long mod2mMask;
[7d90aa]284#endif
[73a9ffb]285  int        ch;  /* characteristic, set by the local *InitChar methods;
286                     In field extensions or extensions towers, the
287                     characteristic can be accessed from any of the
288                     intermediate extension fields, i.e., in this case
289                     it is redundant along the chain of field extensions;
[488808e]290                     CONTRARY to SINGULAR as it was, we do NO LONGER use
291                     negative values for ch;
292                     for rings, ch will also be set and is - per def -
293                     the smallest number of 1's that sum up to zero;
294                     however, in this case ch may not fit in an int,
295                     thus ch may contain a faulty value */
[7d90aa]296
297  short      float_len; /* additional char-flags, rInit */
298  short      float_len2; /* additional char-flags, rInit */
[d0a51ee]299
[ce1f78]300//  BOOLEAN   CanShortOut; //< if the elements can be printed in short format
301//                     // this is set to FALSE if a parameter name has >2 chars
302//  BOOLEAN   ShortOut; //< if the elements should print in short format
[d0a51ee]303
[5e3046]304// ---------------------------------------------------
305  // for n_GF
306
[488808e]307  int m_nfCharQ;  ///< the number of elements: q
[5e3046]308  int m_nfM1;       ///< representation of -1
309  int m_nfCharP;  ///< the characteristic: p
310  int m_nfCharQ1; ///< q-1
311  unsigned short *m_nfPlus1Table;
312  int *m_nfMinPoly;
[7fee876]313 
[e77676]314// ---------------------------------------------------
315// for Zp:
316#ifdef HAVE_DIV_MOD
317  unsigned short *npInvTable;
318#endif
319#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
320  unsigned short *npExpTable;
321  unsigned short *npLogTable;
322#endif
323   //   int npPrimeM; // NOTE: npPrimeM is deprecated, please use ch instead!
324  int npPminus1M; ///< characteristic - 1
[7d90aa]325};
[7bbbef]326//
327// test properties and type
328/// Returns the type of coeffs domain
329static inline n_coeffType getCoeffType(const coeffs r)
330{
[17e473]331  assume(r != NULL);
[7bbbef]332  return r->type;
333}
334
335/// one-time initialisations for new coeffs
[1cce47]336/// in case of an error return NULL
[7bbbef]337coeffs nInitChar(n_coeffType t, void * parameter);
[16f8f1]338
[7bbbef]339/// undo all initialisations
340void nKillChar(coeffs r);
[16f8f1]341
[7bbbef]342/// initialisations after each ring change
[ef3790]343static inline void nSetChar(const coeffs r)
[7bbbef]344{
[227efd]345  assume(r!=NULL); // r==NULL is an error
[32cc7e]346  assume(r->cfSetChar != NULL);
347  r->cfSetChar(r);
[7bbbef]348}
349
350void           nNew(number * a);
[91a305]351#define n_New(n, r)           nNew(n)
[7d90aa]352
[b12b7c]353
[b807aa0]354/// Return the characteristic of the coeff. domain.
355static inline int n_GetChar(const coeffs r)
356{
357  assume(r != NULL);
358  return r->ch;
359}
360
361
[227efd]362// the access methods (part 2):
[b12b7c]363
[44d5ad]364/// return a copy of 'n'
[8a8c9e]365static inline number n_Copy(number n,    const coeffs r)
[6c084af]366{   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
[16f8f1]367
[44d5ad]368/// delete 'p'
[8a8c9e]369static inline void   n_Delete(number* p, const coeffs r)
[6c084af]370{   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
[8a8c9e]371
[44d5ad]372/// TRUE iff 'a' and 'b' represent the same number;
373/// they may have different representations
[8a8c9e]374static inline BOOLEAN n_Equal(number a, number b, const coeffs r)
[6c084af]375{ assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
[16f8f1]376
[44d5ad]377/// TRUE iff 'n' represents the zero element
[8a8c9e]378static inline BOOLEAN n_IsZero(number n, const coeffs r)
[6c084af]379{ assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
[16f8f1]380
[44d5ad]381/// TRUE iff 'n' represents the one element
[8a8c9e]382static inline BOOLEAN n_IsOne(number n,  const coeffs r)
[6c084af]383{ assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
[16f8f1]384
[44d5ad]385/// TRUE iff 'n' represents the additive inverse of the one element, i.e. -1
[8a8c9e]386static inline BOOLEAN n_IsMOne(number n, const coeffs r)
[6c084af]387{ assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
[16f8f1]388
[44d5ad]389/// ordered fields: TRUE iff 'n' is positive;
390/// in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2), where m is the long
391///          representing n
392/// in C:    TRUE iff (Im(n) != 0 and Im(n) >= 0) or
393///                   (Im(n) == 0 and Re(n) >= 0)
394/// in K(a)/<p(a)>: TRUE iff (n != 0 and (LC(n) > 0 or deg(n) > 0))
395/// in K(t_1, ..., t_n): TRUE iff (LC(numerator(n) is a constant and > 0)
396///                            or (LC(numerator(n) is not a constant)
397/// in Z/2^kZ: TRUE iff 0 < n <= 2^(k-1)
398/// in Z/mZ: TRUE iff the internal mpz is greater than zero
399/// in Z: TRUE iff n > 0
400///
401/// !!! Recommendation: remove implementations for unordered fields
402/// !!!                 and raise errors instead, in these cases
[8a5c49]403/// !!! Do not follow this recommendation: while writing polys,
404/// !!! between 2 monomials will be an additional + iff !n_GreaterZero(next coeff)
405///
[8a8c9e]406static inline BOOLEAN n_GreaterZero(number n, const coeffs r)
[44d5ad]407{
408  assume(r != NULL); assume(r->cfGreaterZero!=NULL);
409  return r->cfGreaterZero(n,r);
410}
411
412/// ordered fields: TRUE iff 'a' is larger than 'b';
413/// in Z/pZ: TRUE iff la > lb, where la and lb are the long's representing
414//                             a and b, respectively
415/// in C:    TRUE iff (Im(a) > Im(b))
416/// in K(a)/<p(a)>: TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b))
417/// in K(t_1, ..., t_n): TRUE only if one or both numerator polynomials are
418///                      zero or if their degrees are equal. In this case,
419///                      TRUE if LC(numerator(a)) > LC(numerator(b))
420/// in Z/2^kZ: TRUE if n_DivBy(a, b)
421/// in Z/mZ: TRUE iff the internal mpz's fulfill the relation '>'
422/// in Z: TRUE iff a > b
423///
424/// !!! Recommendation: remove implementations for unordered fields
425/// !!!                 and raise errors instead, in these cases
[529fa4]426static inline BOOLEAN n_Greater(number a, number b, const coeffs r)
427{ assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
[16f8f1]428
[1b816a3]429#ifdef HAVE_RINGS
[b56249]430static inline int n_DivComp(number a, number b, const coeffs r)
431{ assume(r != NULL); assume(r->cfDivComp!=NULL); return r->cfDivComp (a,b,r); }
432
[44d5ad]433/// TRUE iff n has a multiplicative inverse in the given coeff field/ring r
[8a8c9e]434static inline BOOLEAN n_IsUnit(number n, const coeffs r)
[6c084af]435{ assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
[16f8f1]436
[44d5ad]437/// in Z: 1
438/// in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that
439///                                   is co-prime with k
440/// in Z/2^kZ: largest odd divisor of n (taken in Z)
441/// other cases: not implemented
[5679049]442static inline number n_GetUnit(number n, const coeffs r)
[6c084af]443{ assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
[44d898]444#endif
[16f8f1]445
[44d5ad]446/// a number representing i in the given coeff field/ring r
[2f3764]447static inline number n_Init(long i,       const coeffs r)
[6c084af]448{ assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
[b12b7c]449
[045efb]450/// conversion of a GMP integer to number
[02fe5f]451static inline number n_InitMPZ(mpz_t n,     const coeffs r)
[045efb]452{ assume(r != NULL); assume(r->cfInitMPZ != NULL); return r->cfInitMPZ(n,r); }
453
[44d5ad]454/// conversion of n to an int; 0 if not possible
455/// in Z/pZ: the representing int lying in (-p/2 .. p/2]
[d12f186]456static inline int n_Int(number &n,       const coeffs r)
[fba6f18]457{ assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
458
[045efb]459/// conversion of n to a GMP integer; 0 if not possible
460static inline void n_MPZ(mpz_t result, number &n,       const coeffs r)
461{ assume(r != NULL); assume(r->cfMPZ!=NULL); r->cfMPZ(result, n, r); }
462
463
[44d5ad]464/// in-place negation of n
[0461f0]465/// MUST BE USED: n = n_Neg(n) (no copy is returned)
[8a8c9e]466static inline number n_Neg(number n,     const coeffs r)
[6c084af]467{ assume(r != NULL); assume(r->cfNeg!=NULL); return r->cfNeg(n,r); }
[b12b7c]468
[44d5ad]469/// return the multiplicative inverse of 'a';
470/// raise an error if 'a' is not invertible
471///
472/// !!! Recommendation: rename to 'n_Inverse'
[8a8c9e]473static inline number n_Invers(number a,  const coeffs r)
[6c084af]474{ assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
[b12b7c]475
[44d5ad]476/// return a non-negative measure for the complexity of n;
477/// return 0 only when n represents zero;
478/// (used for pivot strategies in matrix computations with entries from r)
[8a8c9e]479static inline int    n_Size(number n,    const coeffs r)
[6c084af]480{ assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
[b12b7c]481
[44d5ad]482/// inplace-normalization of n;
483/// produces some canonical representation of n;
484///
485/// !!! Recommendation: remove this method from the user-interface, i.e.,
486/// !!!                 this should be hidden
[8a8c9e]487static inline void   n_Normalize(number& n, const coeffs r)
[6c084af]488{ assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
[b12b7c]489
[44d5ad]490/// write to the output buffer of the currently used reporter
[ce1f78]491static inline void   n_WriteLong(number& n,  const coeffs r)
492{ assume(r != NULL); assume(r->cfWriteLong!=NULL); r->cfWriteLong(n,r); }
493
494/// write to the output buffer of the currently used reporter
495/// in a shortest possible way, e.g. in K(a): a2 instead of a^2
496static inline void   n_WriteShort(number& n,  const coeffs r)
497{ assume(r != NULL); assume(r->cfWriteShort!=NULL); r->cfWriteShort(n,r); }
498
499static inline void   n_Write(number& n,  const coeffs r, const BOOLEAN bShortOut = TRUE)
500{ if (bShortOut) n_WriteShort(n, r); else n_WriteLong(n, r); }
501
[b12b7c]502
[44d5ad]503/// @todo: Describe me!!! --> Hans
504///
505/// !!! Recommendation: This method is to cryptic to be part of the user-
506/// !!!                 interface. As defined here, it is merely a helper
507/// !!!                 method for parsing number input strings.
[353caa]508static inline const char *n_Read(const char * s, number * a, const coeffs r)
509{ assume(r != NULL); assume(r->cfRead!=NULL); return r->cfRead(s, a, r); }
510
[44d5ad]511/// return the denominator of n
512/// (if elements of r are by nature not fractional, result is 1)
[8a8c9e]513static inline number n_GetDenom(number& n, const coeffs r)
[6c084af]514{ assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
[b12b7c]515
[44d5ad]516/// return the numerator of n
517/// (if elements of r are by nature not fractional, result is n)
[8a8c9e]518static inline number n_GetNumerator(number& n, const coeffs r)
[6c084af]519{ assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
[b12b7c]520
[44d5ad]521/// fill res with the power a^b
[8a8c9e]522static inline void   n_Power(number a, int b, number *res, const coeffs r)
[6c084af]523{ assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
[b12b7c]524
[44d5ad]525/// return the product of 'a' and 'b', i.e., a*b
[8a8c9e]526static inline number n_Mult(number a, number b, const coeffs r)
[6c084af]527{ assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
[227efd]528
[44d5ad]529/// multiplication of 'a' and 'b';
530/// replacement of 'a' by the product a*b
[8a8c9e]531static inline void n_InpMult(number &a, number b, const coeffs r)
[6c084af]532{ assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
[8a8c9e]533
[44d5ad]534/// return the difference of 'a' and 'b', i.e., a-b
[8a8c9e]535static inline number n_Sub(number a, number b, const coeffs r)
[6c084af]536{ assume(r != NULL); assume(r->cfSub!=NULL); return r->cfSub(a, b, r); }
[8a8c9e]537
[44d5ad]538/// return the sum of 'a' and 'b', i.e., a+b
[8a8c9e]539static inline number n_Add(number a, number b, const coeffs r)
[6c084af]540{ assume(r != NULL); assume(r->cfAdd!=NULL); return r->cfAdd(a, b, r); }
[b12b7c]541
[44d5ad]542/// return the quotient of 'a' and 'b', i.e., a/b;
543/// raise an error if 'b' is not invertible in r
[8a8c9e]544static inline number n_Div(number a, number b, const coeffs r)
[6c084af]545{ assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
[b12b7c]546
[44d5ad]547/// in Z: largest c such that c*b <= a
548/// in Z/nZ, Z/2^kZ: computed as in the case Z (from integers representing
549///                  'a' and 'b')
550/// in Z/pZ: return a/b
551/// in K(a)/<p(a)>: return a/b
552/// in K(t_1, ..., t_n): return a/b
553/// other fields: not implemented
[8a8c9e]554static inline number n_IntDiv(number a, number b, const coeffs r)
[6c084af]555{ assume(r != NULL); assume(r->cfIntDiv!=NULL); return r->cfIntDiv(a,b,r); }
[b12b7c]556
[9b3700]557static inline number n_IntMod(number a, number b, const coeffs r)
558{ assume(r != NULL); assume(r->cfIntMod!=NULL); return r->cfIntMod(a,b,r); }
[44d5ad]559/// @todo: Describe me!!!
560///
561/// What is the purpose of this method, especially in comparison with
562/// n_Div?
563/// !!! Recommendation: remove this method from the user-interface.
[8a8c9e]564static inline number n_ExactDiv(number a, number b, const coeffs r)
[6c084af]565{ assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
[8a8c9e]566
[44d5ad]567/// in Z: return the gcd of 'a' and 'b'
568/// in Z/nZ, Z/2^kZ: computed as in the case Z
569/// in Z/pZ, C, R: not implemented
570/// in Q: return the gcd of the numerators of 'a' and 'b'
571/// in K(a)/<p(a)>: not implemented
572/// in K(t_1, ..., t_n): not implemented
[8a8c9e]573static inline number n_Gcd(number a, number b, const coeffs r)
[6c084af]574{ assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
[b12b7c]575
[b56249]576/// beware that ExtGCD is only relevant for a few chosen coeff. domains
577/// and may perform something unexpected in some cases...
578static inline number n_ExtGcd(number a, number b, number *s, number *t, const coeffs r)
579{ assume(r != NULL); assume(r->cfExtGcd!=NULL); return r->cfExtGcd (a,b,s,t,r); }
580
[44d5ad]581/// in Z: return the lcm of 'a' and 'b'
582/// in Z/nZ, Z/2^kZ: computed as in the case Z
583/// in Z/pZ, C, R: not implemented
584/// in Q: return the lcm of the numerators of 'a' and the denominator of 'b'
585/// in K(a)/<p(a)>: not implemented
586/// in K(t_1, ..., t_n): not implemented
[5679049]587static inline number n_Lcm(number a, number b, const coeffs r)
[6c084af]588{ assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
[1389a4]589
[44d5ad]590/// set the mapping function pointers for translating numbers from src to dst
[1389a4]591static inline nMapFunc n_SetMap(const coeffs src, const coeffs dst)
[6c084af]592{ assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
[1389a4]593
[44d5ad]594/// test whether n is a correct number;
595/// only used if LDEBUG is defined
[2e4ec14]596#ifdef LDEBUG
[b12b7c]597static inline BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
[2e4ec14]598#else
599static inline BOOLEAN n_DBTest(number, const char*, const int, const coeffs)
600#endif
[2bd9ca]601{
[17e473]602  assume(r != NULL); 
[8a8c9e]603#ifdef LDEBUG
[6c084af]604  assume(r->cfDBTest != NULL); 
605  return r->cfDBTest(n, filename, linenumber, r);
[5e3046]606#else
607  return TRUE;
608#endif
[2bd9ca]609}
[a0ce49]610
[c7e3d7]611/// output the coeff description
[03f7b5]612static inline void   n_CoeffWrite(const coeffs r, BOOLEAN details = TRUE)
613{ assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r, details); }
[c7e3d7]614
[0ef3f51]615// Tests:
616static inline BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
[66ce6d]617{ assume(r != NULL); return (getCoeffType(r)==n_Z2m); }
[0ef3f51]618
619static inline BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
[66ce6d]620{ assume(r != NULL); return (getCoeffType(r)==n_Zn); }
[0ef3f51]621
622static inline BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
[66ce6d]623{ assume(r != NULL); return (getCoeffType(r)==n_Znm); }
[0ef3f51]624
625static inline BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
[66ce6d]626{ assume(r != NULL); return (getCoeffType(r)==n_Z); }
[0ef3f51]627
628static inline BOOLEAN nCoeff_is_Ring(const coeffs r)
[66ce6d]629{ assume(r != NULL); return ((getCoeffType(r)==n_Z) || (getCoeffType(r)==n_Z2m) || (getCoeffType(r)==n_Zn) || (getCoeffType(r)==n_Znm)); }
[0ef3f51]630
[7dce2d7]631/// returns TRUE, if r is not a field and r has no zero divisors (i.e is a domain)
[0ef3f51]632static inline BOOLEAN nCoeff_is_Domain(const coeffs r)
[17e473]633{
634  assume(r != NULL); 
635#ifdef HAVE_RINGS
[66ce6d]636  return (getCoeffType(r)==n_Z || ((getCoeffType(r)!=n_Z2m) && (getCoeffType(r)!=n_Zn) && (getCoeffType(r)!=n_Znm)));
[17e473]637#else
638  return TRUE;
639#endif
640}
[0ef3f51]641
[44d5ad]642/// test whether 'a' is divisible 'b';
643/// for r encoding a field: TRUE iff 'b' does not represent zero
644/// in Z: TRUE iff 'b' divides 'a' (with remainder = zero)
645/// in Z/nZ: TRUE iff (a = 0 and b divides n in Z) or
646///                   (a != 0 and b/gcd(a, b) is co-prime with n, i.e.
647///                                              a unit in Z/nZ)
648/// in Z/2^kZ: TRUE iff ((a = 0 mod 2^k) and (b = 0 or b is a power of 2))
649///                  or ((a, b <> 0) and (b/gcd(a, b) is odd))
[6a7368]650static inline BOOLEAN n_DivBy(number a, number b, const coeffs r)
651{
652  assume(r != NULL);
653#ifdef HAVE_RINGS
654  if( nCoeff_is_Ring(r) )
655  {
656    assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r);
657  }
658#endif
659  return !n_IsZero(b, r);
660}
661
[de27d8]662static inline number n_ChineseRemainderSym(number *a, number *b, int rl, BOOLEAN sym,const coeffs r)
[e8c8d5]663{
[de27d8]664  assume(r != NULL); assume(r->cfChineseRemainder != NULL); return r->cfChineseRemainder(a,b,rl,sym,r);
[e8c8d5]665}
666
[f9591a]667static inline number n_Farey(number a, number b, const coeffs r)
[e8c8d5]668{
[da5d77]669  assume(r != NULL); assume(r->cfFarey != NULL); return r->cfFarey(a,b,r);
[e8c8d5]670}
671
[48a41a]672static inline int n_ParDeg(number n, const coeffs r)
673{ 
[da5d77]674  assume(r != NULL); assume(r->cfParDeg != NULL); return r->cfParDeg(n,r); 
[48a41a]675}
676
[7fee876]677/// Returns the number of parameters
678static inline int n_NumberOfParameters(const coeffs r){ return r->iNumberOfParameters; }
679
680/// Returns a (const!) pointer to (const char*) names of parameters
681static inline char const * const * n_ParameterNames(const coeffs r){ return r->pParameterNames; }
682
683
684/// return the (iParameter^th) parameter as a NEW number
685/// NOTE: parameter numbering: 1..n_NumberOfParameters(...)
686static inline number n_Param(const int iParameter, const coeffs r)
687{
688  assume(r != NULL);
689  assume((iParameter >= 1) || (iParameter <= n_NumberOfParameters(r)));
690  assume(r->cfParameter != NULL);
691  return r->cfParameter(iParameter, r); 
692}
693
694
[a0432f]695static inline number  n_Init_bigint(number i, const coeffs dummy,
696                const coeffs dst)
697{
698  assume(dummy != NULL && dst != NULL); assume(dst->cfInit_bigint!=NULL); 
699  return dst->cfInit_bigint(i, dummy, dst);
700}
701
[cfecd2]702static inline number  n_RePart(number i, const coeffs cf)
703{
704  assume(cf != NULL); assume(cf->cfRePart!=NULL); 
705  return cf->cfRePart(i,cf);
706}
707static inline number  n_ImPart(number i, const coeffs cf)
708{
709  assume(cf != NULL); assume(cf->cfImPart!=NULL); 
[94a065c]710  return cf->cfImPart(i,cf);
[cfecd2]711}
712
[7dce2d7]713/// returns TRUE, if r is not a field and r has non-trivial units
[0ef3f51]714static inline BOOLEAN nCoeff_has_Units(const coeffs r)
[66ce6d]715{ assume(r != NULL); return ((getCoeffType(r)==n_Zn) || (getCoeffType(r)==n_Z2m) || (getCoeffType(r)==n_Znm)); }
[0ef3f51]716
717static inline BOOLEAN nCoeff_is_Zp(const coeffs r)
[17e473]718{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
[0ef3f51]719
720static inline BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
[e8fd36]721{ assume(r != NULL); return ((getCoeffType(r)==n_Zp) && (r->ch == p)); }
[0ef3f51]722
723static inline BOOLEAN nCoeff_is_Q(const coeffs r)
[17e473]724{ assume(r != NULL); return getCoeffType(r)==n_Q; }
[0ef3f51]725
726static inline BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
[17e473]727{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
728// (r->ringtype == 0) && (r->ch ==  -1); ??
729
[0ef3f51]730static inline BOOLEAN nCoeff_is_R(const coeffs r)
[17e473]731{ assume(r != NULL); return getCoeffType(r)==n_R; }
[0ef3f51]732
733static inline BOOLEAN nCoeff_is_GF(const coeffs r)
[17e473]734{ assume(r != NULL); return getCoeffType(r)==n_GF; }
[0ef3f51]735
736static inline BOOLEAN nCoeff_is_GF(const coeffs r, int q)
[17e473]737{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
[0ef3f51]738
[488808e]739/* TRUE iff r represents an algebraic or transcendental extension field */
740static inline BOOLEAN nCoeff_is_Extension(const coeffs r)
741{
742  assume(r != NULL);
743  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
744}
745
746/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
747   svn trunk);
748   intension: should be TRUE iff the given r is an extension field above
749   some Z/pZ;
750   actually: TRUE iff the given r is an extension tower of arbitrary
751   height above some field of characteristic p (may be Z/pZ or some
752   Galois field of characteristic p) */
[0ef3f51]753static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r)
[fba6f18]754{
755  assume(r != NULL);
[b807aa0]756  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) != 0) && nCoeff_is_Extension(r));
[fba6f18]757}
[0ef3f51]758
[488808e]759/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
760   svn trunk);
761   intension: should be TRUE iff the given r is an extension field above
762   Z/pZ (with p as provided);
763   actually: TRUE iff the given r is an extension tower of arbitrary
764   height above some field of characteristic p (may be Z/pZ or some
765   Galois field of characteristic p) */
[0ef3f51]766static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r, int p)
[fba6f18]767{
768  assume(r != NULL);
[b807aa0]769  assume(p != 0);
770  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) == p) && nCoeff_is_Extension(r));
[fba6f18]771}
[0ef3f51]772
[488808e]773/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
774   svn trunk);
775   intension: should be TRUE iff the given r is an extension field
776   above Q;
777   actually: TRUE iff the given r is an extension tower of arbitrary
778   height above some field of characteristic 0 (may be Q, R, or C) */
[0ef3f51]779static inline BOOLEAN nCoeff_is_Q_a(const coeffs r)
[fba6f18]780{
781  assume(r != NULL);
[dc79bd]782  return ((n_GetChar(r) == 0) && nCoeff_is_Extension(r));
[fba6f18]783}
[0ef3f51]784
[dc79bd]785
786
787
[0ef3f51]788static inline BOOLEAN nCoeff_is_long_R(const coeffs r)
[17e473]789{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
[0ef3f51]790
791static inline BOOLEAN nCoeff_is_long_C(const coeffs r)
[17e473]792{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
[0ef3f51]793
794static inline BOOLEAN nCoeff_is_CF(const coeffs r)
[17e473]795{ assume(r != NULL); return getCoeffType(r)==n_CF; }
[0ef3f51]796
[44d5ad]797/// TRUE, if the computation of the inverse is fast,
798/// i.e. prefer leading coeff. 1 over content
[0ef3f51]799static inline BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
[17e473]800{ assume(r != NULL); return r->has_simple_Inverse; }
801
[7dce2d7]802/// TRUE if n_Delete/n_New are empty operations
[0ef3f51]803static inline BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
[17e473]804{ assume(r != NULL); return r->has_simple_Alloc; }
[44d5ad]805
806/// TRUE iff r represents an algebraic extension field
[141342]807static inline BOOLEAN nCoeff_is_algExt(const coeffs r)
808{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
809
[dc79bd]810/// is it an alg. ext. of Q?
811static inline BOOLEAN nCoeff_is_Q_algext(const coeffs r)
812{ assume(r != NULL); return ((n_GetChar(r) == 0) && nCoeff_is_algExt(r)); }
813
[44d5ad]814/// TRUE iff r represents a transcendental extension field
[141342]815static inline BOOLEAN nCoeff_is_transExt(const coeffs r)
816{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
[0ef3f51]817
[2bd9ca]818/// BOOLEAN n_Test(number a, const coeffs r)
819#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
820
[44d898]821// Missing wrappers for: (TODO: review this?)
[cfecd2]822// cfIntMod, cfRead, cfName, cfInit_bigint
[b56249]823
824// HAVE_RINGS: cfDivComp, cfIsUnit, cfGetUnit, cfDivBy
825// BUT NOT cfExtGcd...!
[b12b7c]826
827
[98474f]828/// Computes the content and (inplace) divides it out on a collection
829/// of numbers
[de88371]830/// number @em c is the content (i.e. the GCD of all the coeffs, which
831/// we divide out inplace)
832/// NOTE: it assumes all coefficient numbers to be integer!!!
833/// NOTE/TODO: see also the description by Hans
834/// TODO: rename into n_ClearIntegerContent
[98474f]835static inline void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
836{
837  assume(r != NULL);
838  r->cfClearContent(numberCollectionEnumerator, c, r);
839}
840
841/// (inplace) Clears denominators on a collection of numbers
[de88371]842/// number @em d is the LCM of all the coefficient denominators (i.e. the number
843/// with which all the number coeffs. were multiplied)
844/// NOTE/TODO: see also the description by Hans
[98474f]845static inline void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& d, const coeffs r)
846{
847  assume(r != NULL);
848  r->cfClearDenominators(numberCollectionEnumerator, d, r);
849}
850
851// convenience helpers (no number returned - but the input enumeration
852// is to be changed
853// TODO: do we need separate hooks for these as our existing code does
854// *different things* there: compare p_Cleardenom (which calls
855// *p_Content) and p_Cleardenom_n (which doesn't)!!!
856
857static inline void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
858{
859  number c;
860  n_ClearContent(numberCollectionEnumerator, c, r);
861  n_Delete(&c, r);
862}
863
864static inline void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
865{
866  assume(r != NULL);
867  number d;
868  n_ClearDenominators(numberCollectionEnumerator, d, r);
869  n_Delete(&d, r);
870}
871
[21b9ef]872/// print a number (BEWARE of string buffers!)
873/// mostly for debugging
874void   n_Print(number& a,  const coeffs r);
[98474f]875
[7d90aa]876#endif
877
Note: See TracBrowser for help on using the repository browser.