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

spielwiese
Last change on this file since e5618c was e5618c, checked in by Yue Ren <ren@…>, 9 years ago
chg: final version for Singular release
  • Property mode set to 100644
File size: 41.7 KB
Line 
1/*! \file coeffs/coeffs.h Coefficient rings, fields and other domains suitable for Singular polynomials
2
3  The main interface for Singular coefficients: \ref coeffs is the main handler for Singular numbers
4*/
5/****************************************
6*  Computer Algebra System SINGULAR     *
7****************************************/
8
9#ifndef COEFFS_H
10#define COEFFS_H
11
12#include <misc/auxiliary.h>
13#include <omalloc/omalloc.h>
14
15#include <misc/sirandom.h>
16/* for assume: */
17#include <reporter/reporter.h>
18#include <reporter/s_buff.h>
19
20#include <coeffs/si_gmp.h>
21#include <coeffs/Enumerator.h>
22#include <coeffs/numstats.h> // for STATISTIC(F) counting macro
23
24class CanonicalForm;
25
26enum n_coeffType
27{
28  n_unknown=0,
29  n_Zp, /**< \F{p < 2^31} */
30  n_Q,  /**< rational (GMP) numbers */
31  n_R,  /**< single prescision (6,6) real numbers */
32  n_GF, /**< \GF{p^n < 2^16} */
33  n_long_R, /**< real floating point (GMP) numbers */
34  n_algExt,  /**< used for all algebraic extensions, i.e.,
35                the top-most extension in an extension tower
36                is algebraic */
37  n_transExt,  /**< used for all transcendental extensions, i.e.,
38                  the top-most extension in an extension tower
39                  is transcendental */
40  n_long_C, /**< complex floating point (GMP) numbers */
41  n_Z, /**< only used if HAVE_RINGS is defined: ? */
42  n_Zn, /**< only used if HAVE_RINGS is defined: ? */
43  n_Znm, /**< only used if HAVE_RINGS is defined: ? */
44  n_Z2m, /**< only used if HAVE_RINGS is defined: ? */
45  n_CF /**< ? */
46};
47
48extern unsigned short fftable[];
49
50struct snumber;
51typedef struct snumber *   number;
52
53/* standard types */
54struct ip_sring;
55typedef struct ip_sring *         ring;
56typedef struct ip_sring const *   const_ring;
57
58/// @class coeffs coeffs.h coeffs/coeffs.h
59///
60/// The main handler for Singular numbers which are suitable for Singular polynomials.
61///
62/// With it one may implement a ring, a field, a domain etc.
63///
64struct n_Procs_s;
65typedef struct  n_Procs_s  *coeffs;
66typedef struct  n_Procs_s  const * const_coeffs;
67
68typedef number (*numberfunc)(number a, number b, const coeffs r);
69
70/// maps "a", which lives in src, into dst
71typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
72
73
74/// Abstract interface for an enumerator of number coefficients for an
75/// object, e.g. a polynomial
76typedef IEnumerator<number> ICoeffsEnumerator;
77
78/// goes over coeffs given by the ICoeffsEnumerator and changes them.
79/// Additionally returns a number;
80typedef void (*nCoeffsEnumeratorFunc)(ICoeffsEnumerator& numberCollectionEnumerator, number& output, const coeffs r);
81
82extern omBin rnumber_bin;
83
84#define FREE_RNUMBER(x) omFreeBin((void *)x, rnumber_bin)
85#define ALLOC_RNUMBER() (number)omAllocBin(rnumber_bin)
86#define ALLOC0_RNUMBER() (number)omAlloc0Bin(rnumber_bin)
87
88
89/// Creation data needed for finite fields
90typedef struct
91{
92  int GFChar;
93  int GFDegree;
94  const char* GFPar_name;
95} GFInfo;
96
97typedef struct
98{
99  short      float_len; /**< additional char-flags, rInit */
100  short      float_len2; /**< additional char-flags, rInit */
101  const char* par_name; /**< parameter name */
102} LongComplexInfo;
103
104
105enum n_coeffRep
106{
107  n_rep_unknown=0,
108  n_rep_int,      /**< (int), see modulop.h */
109  n_rep_gap_rat,  /**< (number), see longrat.h */
110  n_rep_gap_gmp,  /**< (), see rinteger.h, new impl. */
111  n_rep_poly,     /**< (poly), see algext.h */
112  n_rep_rat_fct,  /**< (fraction), see transext.h */
113  n_rep_gmp,      /**< (mpz_ptr), see rmodulon,h */
114  n_rep_float,    /**< (float), see shortfl.h */
115  n_rep_gmp_float,  /**< (gmp_float), see  */
116  n_rep_gmp_complex,/**< (gmp_complex), see gnumpc.h */
117  n_rep_gf        /**< (int), see ffields.h */
118};
119
120struct n_Procs_s
121{
122   // administration of coeffs:
123   coeffs next;
124   int     ref;
125   n_coeffRep rep;
126   n_coeffType type;
127   /// how many variables of factory are already used by this coeff
128   int     factoryVarOffset;
129
130   // general properties:
131   /// TRUE, if nNew/nDelete/nCopy are dummies
132   BOOLEAN has_simple_Alloc;
133   /// TRUE, if std should make polynomials monic (if nInvers is cheap)
134   /// if false, then a gcd routine is used for a content computation
135   BOOLEAN has_simple_Inverse;
136
137   /// TRUE, if cf is a field
138   BOOLEAN is_field;
139   /// TRUE, if cf is a domain
140   BOOLEAN is_domain;
141
142   // tests for numbers.cc:
143   BOOLEAN (*nCoeffIsEqual)(const coeffs r, n_coeffType n, void * parameter);
144
145   /// output of coeff description via Print
146   void (*cfCoeffWrite)(const coeffs r, BOOLEAN details);
147
148   /// string output of coeff description
149   char* (*cfCoeffString)(const coeffs r);
150
151   /// default name of cf, should substitue cfCoeffWrite, cfCoeffString
152   char* (*cfCoeffName)(const coeffs r);
153
154   // ?
155   // initialisation:
156   //void (*cfInitChar)(coeffs r, int parameter); // do one-time initialisations
157   void (*cfKillChar)(coeffs r); //  undo all initialisations
158                                // or NULL
159   void (*cfSetChar)(const coeffs r); // initialisations after each ring change
160                                // or NULL
161   // general stuff
162   //   if the ring has a meaningful Euclidean structure, hopefully
163   //   supported by cfQuotRem, then
164   //     IntMod, Div should give the same result
165   //     Div(a,b) = QuotRem(a,b, &IntMod(a,b))
166   //   if the ring is not Euclidean or a field, then IntMod should return 0
167   //   and Div the exact quotient. It is assumed that the function is
168   //   ONLY called on Euclidean rings or in the case of an exact division.
169   //
170   //   cfDiv does an exact division, but has to handle illegal input
171   //   cfExactDiv does an exact division, but no error checking
172   //   (I'm not sure I understant and even less that this makes sense)
173   numberfunc cfMult, cfSub ,cfAdd ,cfDiv, cfIntMod, cfExactDiv;
174
175   /// init with an integer
176   number  (*cfInit)(long i,const coeffs r);
177
178   /// init with a GMP integer
179   number  (*cfInitMPZ)(mpz_t i, const coeffs r);
180
181   /// how complicated, (0) => 0, or positive
182   int     (*cfSize)(number n, const coeffs r);
183
184   /// convertion to long, 0 if impossible
185   long    (*cfInt)(number &n, const coeffs r);
186
187   /// Converts a non-negative number n into a GMP number, 0 if impossible
188   void     (*cfMPZ)(mpz_t result, number &n, const coeffs r);
189
190   /// changes argument  inline: a:= -a
191   /// return -a! (no copy is returned)
192   /// the result should be assigned to the original argument: e.g. a = n_InpNeg(a,r)
193   number  (*cfInpNeg)(number a, const coeffs r);
194   /// return 1/a
195   number  (*cfInvers)(number a, const coeffs r);
196   /// return a copy of a
197   number  (*cfCopy)(number a, const coeffs r);
198   number  (*cfRePart)(number a, const coeffs r);
199   number  (*cfImPart)(number a, const coeffs r);
200
201   /// print a given number (long format)
202   void    (*cfWriteLong)(number &a, const coeffs r);
203
204   /// print a given number in a shorter way, if possible
205   /// e.g. in K(a): a2 instead of a^2
206   void    (*cfWriteShort)(number &a, const coeffs r);
207
208   // it is legal, but not always useful to have cfRead(s, a, r)
209   //   just return s again.
210   // Useful application (read constants which are not an projection
211   // from int/bigint:
212   // Let ring r = R,x,dp;
213   // where R is a coeffs having "special" "named" elements (ie.
214   // the primitive element in some algebraic extension).
215   // If there is no interpreter variable of the same name, it is
216   // difficult to create non-trivial elements in R.
217   // Hence one can use the string to allow creation of R-elts using the
218   // unbound name of the special element.
219   const char *  (*cfRead)(const char * s, number * a, const coeffs r);
220   void    (*cfNormalize)(number &a, const coeffs r);
221   BOOLEAN (*cfGreater)(number a,number b, const coeffs r),
222            /// tests
223           (*cfEqual)(number a,number b, const coeffs r),
224           (*cfIsZero)(number a, const coeffs r),
225           (*cfIsOne)(number a, const coeffs r),
226           (*cfIsMOne)(number a, const coeffs r),
227       //GreaterZero is used for printing of polynomials:
228       //  a "+" is only printed in front of a coefficient
229       //  if the element is >0. It is assumed that any element
230       //  failing this will start printing with a leading "-"
231           (*cfGreaterZero)(number a, const coeffs r);
232
233   void    (*cfPower)(number a, int i, number * result, const coeffs r);
234   number  (*cfGetDenom)(number &n, const coeffs r);
235   number  (*cfGetNumerator)(number &n, const coeffs r);
236   //CF: a Euclidean ring is a commutative, unitary ring with an Euclidean
237   //  function f s.th. for all a,b in R, b ne 0, we can find q, r s.th.
238   //  a = qb+r and either r=0 or f(r) < f(b)
239   //  Note that neither q nor r nor f(r) are unique.
240   number  (*cfGcd)(number a, number b, const coeffs r);
241   number  (*cfSubringGcd)(number a, number b, const coeffs r);
242   number  (*cfExtGcd)(number a, number b, number *s, number *t,const coeffs r);
243   //given a and b in a Euclidean setting, return s,t,u,v sth.
244   //  sa + tb = gcd
245   //  ua + vb = 0
246   //  sv + tu = 1
247   //  ie. the 2x2 matrix (s t | u v) is unimodular and maps (a,b) to (g, 0)
248   //CF: note, in general, this cannot be derived from ExtGcd due to
249   //    zero divisors
250   number  (*cfXExtGcd)(number a, number b, number *s, number *t, number *u, number *v, const coeffs r);
251   //in a Euclidean ring, return the Euclidean norm as a bigint (of type number)
252   number  (*cfEucNorm)(number a, const coeffs r);
253   //in a principal ideal ring (with zero divisors): the annihilator
254   // NULL otherwise
255   number  (*cfAnn)(number a, const coeffs r);
256   //find a "canonical representative of a modulo the units of r
257   //return NULL if a is already normalized
258   //otherwise, the factor.
259   //(for Z: make positive, for z/nZ make the gcd with n
260   //aparently it is GetUnit!
261   //in a Euclidean ring, return the quotient and compute the remainder
262   //rem can be NULL
263   number  (*cfQuotRem)(number a, number b, number *rem, const coeffs r);
264   number  (*cfLcm)(number a, number b, const coeffs r);
265   number  (*cfNormalizeHelper)(number a, number b, const coeffs r);
266   void    (*cfDelete)(number * a, const coeffs r);
267
268   //CF: tries to find a canonical map from src -> dst
269   nMapFunc (*cfSetMap)(const coeffs src, const coeffs dst);
270
271   void    (*cfWriteFd)(number a, FILE *f, const coeffs r);
272   number  (*cfReadFd)( s_buff f, const coeffs r);
273
274   /// Inplace: a *= b
275   void    (*cfInpMult)(number &a, number b, const coeffs r);
276
277   /// Inplace: a += b
278   void    (*cfInpAdd)(number &a, number b, const coeffs r);
279
280   /// rational reconstruction: "best" rational a/b with a/b = p mod n
281   //  or a = bp mod n
282   //  CF: no idea what this would be in general
283   //     it seems to be extended to operate coefficient wise in extensions.
284   //     I presume then n in coeffs_BIGINT while p in coeffs
285   number  (*cfFarey)(number p, number n, const coeffs);
286
287   /// chinese remainder
288   /// returns X with X mod q[i]=x[i], i=0..rl-1
289   //CF: by the looks of it: q[i] in Z (coeffs_BIGINT)
290   //    strange things happen in naChineseRemainder for example.
291   number  (*cfChineseRemainder)(number *x, number *q,int rl, BOOLEAN sym,const coeffs);
292
293   /// degree for coeffcients: -1 for 0, 0 for "constants", ...
294   int (*cfParDeg)(number x,const coeffs r);
295
296   /// create i^th parameter or NULL if not possible
297   number  (*cfParameter)(const int i, const coeffs r);
298
299   /// a function returning random elements
300   number (*cfRandom)(siRandProc p, number p1, number p2, const coeffs cf);
301
302   /// function pointer behind n_ClearContent
303   nCoeffsEnumeratorFunc cfClearContent;
304
305   /// function pointer behind n_ClearDenominators
306   nCoeffsEnumeratorFunc cfClearDenominators;
307
308   /// conversion to CanonicalForm(factory) to number
309   number (*convFactoryNSingN)( const CanonicalForm n, const coeffs r);
310   CanonicalForm (*convSingNFactoryN)( number n, BOOLEAN setChar, const coeffs r );
311
312
313   /// the 0 as constant, NULL by default
314   number nNULL;
315
316   /// Number of Parameters in the coeffs (default 0)
317   int iNumberOfParameters;
318
319   /// array containing the names of Parameters (default NULL)
320   char const **  pParameterNames;
321   // NOTE that it replaces the following:
322// char* complex_parameter; //< the name of sqrt(-1) in n_long_C , i.e. 'i' or 'j' etc...?
323// char * m_nfParameter; //< the name of parameter in n_GF
324
325   /////////////////////////////////////////////
326   // the union stuff
327
328   //-------------------------------------------
329
330  /* for extension fields we need to be able to represent polynomials,
331     so here is the polynomial ring: */
332  ring          extRing;
333
334  //number     minpoly;  //< no longer needed: replaced by
335  //                     //< extRing->qideal->[0]
336
337
338  int        ch;  /* characteristic, set by the local *InitChar methods;
339                     In field extensions or extensions towers, the
340                     characteristic can be accessed from any of the
341                     intermediate extension fields, i.e., in this case
342                     it is redundant along the chain of field extensions;
343                     CONTRARY to SINGULAR as it was, we do NO LONGER use
344                     negative values for ch;
345                     for rings, ch will also be set and is - per def -
346                     the smallest number of 1's that sum up to zero;
347                     however, in this case ch may not fit in an int,
348                     thus ch may contain a faulty value */
349
350  short      float_len; /* additional char-flags, rInit */
351  short      float_len2; /* additional char-flags, rInit */
352
353//  BOOLEAN   CanShortOut; //< if the elements can be printed in short format
354//                       // this is set to FALSE if a parameter name has >2 chars
355//  BOOLEAN   ShortOut; //< if the elements should print in short format
356
357// ---------------------------------------------------
358  // for n_GF
359
360  int m_nfCharQ;  ///< the number of elements: q
361  int m_nfM1;       ///< representation of -1
362  int m_nfCharP;  ///< the characteristic: p
363  int m_nfCharQ1; ///< q-1
364  unsigned short *m_nfPlus1Table;
365  int *m_nfMinPoly;
366
367// ---------------------------------------------------
368// for Zp:
369  unsigned short *npInvTable;
370  unsigned short *npExpTable;
371  unsigned short *npLogTable;
372   //   int npPrimeM; // NOTE: npPrimeM is deprecated, please use ch instead!
373  int npPminus1M; ///< characteristic - 1
374//-------------------------------------------
375   int     (*cfDivComp)(number a,number b,const coeffs r);
376   BOOLEAN (*cfIsUnit)(number a,const coeffs r);
377   number  (*cfGetUnit)(number a,const coeffs r);
378   //CF: test if b divides a
379   BOOLEAN (*cfDivBy)(number a, number b, const coeffs r);
380  /* The following members are for representing the ring Z/n,
381     where n is not a prime. We distinguish four cases:
382     1.) n has at least two distinct prime factors. Then
383         modBase stores n, modExponent stores 1, modNumber
384         stores n, and mod2mMask is not used;
385     2.) n = p^k for some odd prime p and k > 1. Then
386         modBase stores p, modExponent stores k, modNumber
387         stores n, and mod2mMask is not used;
388     3.) n = 2^k for some k > 1; moreover, 2^k - 1 fits in
389         an unsigned long. Then modBase stores 2, modExponent
390         stores k, modNumber is not used, and mod2mMask stores
391         2^k - 1, i.e., the bit mask '111..1' of length k.
392     4.) n = 2^k for some k > 1; but 2^k - 1 does not fit in
393         an unsigned long. Then modBase stores 2, modExponent
394         stores k, modNumber stores n, and mod2mMask is not
395         used;
396     Cases 1.), 2.), and 4.) are covered by the implementation
397     in the files rmodulon.h and rmodulon.cc, whereas case 3.)
398     is implemented in the files rmodulo2m.h and rmodulo2m.cc. */
399  mpz_ptr    modBase;
400  unsigned long modExponent;
401  mpz_ptr    modNumber;
402  unsigned long mod2mMask;
403  //returns coeffs with updated ch, modNumber and modExp
404  coeffs (*cfQuot1)(number c, const coeffs r);
405
406  /*CF: for blackbox rings, contains data needed to define the ring.
407   * contents depends on the actual example.*/
408  void * data;
409#ifdef LDEBUG
410   // must be last entry:
411   /// Test: is "a" a correct number?
412   // DB as in debug, not data base.
413   BOOLEAN (*cfDBTest)(number a, const char *f, const int l, const coeffs r);
414#endif
415};
416
417// test properties and type
418/// Returns the type of coeffs domain
419static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
420{ assume(r != NULL); return r->type; }
421
422/// one-time initialisations for new coeffs
423/// in case of an error return NULL
424coeffs nInitChar(n_coeffType t, void * parameter);
425
426/// "copy" coeffs, i.e. increment ref
427static FORCE_INLINE coeffs nCopyCoeff(const coeffs r)
428{ assume(r!=NULL); r->ref++; return r;}
429
430/// undo all initialisations
431void nKillChar(coeffs r);
432
433/// initialisations after each ring change
434static FORCE_INLINE void nSetChar(const coeffs r)
435{ STATISTIC(nSetChar);  assume(r!=NULL); assume(r->cfSetChar != NULL); r->cfSetChar(r); }
436
437void           nNew(number * a);
438#define n_New(n, r)           nNew(n)
439
440
441/// Return the characteristic of the coeff. domain.
442static FORCE_INLINE int n_GetChar(const coeffs r)
443{ STATISTIC(n_GetChar); assume(r != NULL); return r->ch; }
444
445
446// the access methods (part 2):
447
448/// return a copy of 'n'
449static FORCE_INLINE number n_Copy(number n,    const coeffs r)
450{ STATISTIC(n_Copy);   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
451
452/// delete 'p'
453static FORCE_INLINE void   n_Delete(number* p, const coeffs r)
454{ STATISTIC(n_Delete);   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
455
456/// TRUE iff 'a' and 'b' represent the same number;
457/// they may have different representations
458static FORCE_INLINE BOOLEAN n_Equal(number a, number b, const coeffs r)
459{ STATISTIC(n_Equal); assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
460
461/// TRUE iff 'n' represents the zero element
462static FORCE_INLINE BOOLEAN n_IsZero(number n, const coeffs r)
463{ STATISTIC(n_IsZero); assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
464
465/// TRUE iff 'n' represents the one element
466static FORCE_INLINE BOOLEAN n_IsOne(number n,  const coeffs r)
467{ STATISTIC(n_IsOne); assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
468
469/// TRUE iff 'n' represents the additive inverse of the one element, i.e. -1
470static FORCE_INLINE BOOLEAN n_IsMOne(number n, const coeffs r)
471{ STATISTIC(n_IsMOne); assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
472
473/// ordered fields: TRUE iff 'n' is positive;
474/// in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2), where m is the long
475///          representing n
476/// in C:    TRUE iff (Im(n) != 0 and Im(n) >= 0) or
477///                   (Im(n) == 0 and Re(n) >= 0)
478/// in K(a)/<p(a)>: TRUE iff (n != 0 and (LC(n) > 0 or deg(n) > 0))
479/// in K(t_1, ..., t_n): TRUE iff (LC(numerator(n) is a constant and > 0)
480///                            or (LC(numerator(n) is not a constant)
481/// in Z/2^kZ: TRUE iff 0 < n <= 2^(k-1)
482/// in Z/mZ: TRUE iff the internal mpz is greater than zero
483/// in Z: TRUE iff n > 0
484///
485/// !!! Recommendation: remove implementations for unordered fields
486/// !!!                 and raise errors instead, in these cases
487/// !!! Do not follow this recommendation: while writing polys,
488/// !!! between 2 monomials will be an additional + iff !n_GreaterZero(next coeff)
489///     Then change definition to include n_GreaterZero => printing does NOT
490///     start with -
491///
492static FORCE_INLINE BOOLEAN n_GreaterZero(number n, const coeffs r)
493{ STATISTIC(n_GreaterZero); assume(r != NULL); assume(r->cfGreaterZero!=NULL); return r->cfGreaterZero(n,r); }
494
495/// ordered fields: TRUE iff 'a' is larger than 'b';
496/// in Z/pZ: TRUE iff la > lb, where la and lb are the long's representing
497//                             a and b, respectively
498/// in C:    TRUE iff (Im(a) > Im(b))
499/// in K(a)/<p(a)>: TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b))
500/// in K(t_1, ..., t_n): TRUE only if one or both numerator polynomials are
501///                      zero or if their degrees are equal. In this case,
502///                      TRUE if LC(numerator(a)) > LC(numerator(b))
503/// in Z/2^kZ: TRUE if n_DivBy(a, b)
504/// in Z/mZ: TRUE iff the internal mpz's fulfill the relation '>'
505/// in Z: TRUE iff a > b
506///
507/// !!! Recommendation: remove implementations for unordered fields
508/// !!!                 and raise errors instead, in these cases
509static FORCE_INLINE BOOLEAN n_Greater(number a, number b, const coeffs r)
510{ STATISTIC(n_Greater); assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
511
512#ifdef HAVE_RINGS
513static FORCE_INLINE int n_DivComp(number a, number b, const coeffs r)
514{ STATISTIC(n_DivComp); assume(r != NULL); assume(r->cfDivComp!=NULL); return r->cfDivComp (a,b,r); }
515
516/// TRUE iff n has a multiplicative inverse in the given coeff field/ring r
517static FORCE_INLINE BOOLEAN n_IsUnit(number n, const coeffs r)
518{ STATISTIC(n_IsUnit); assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
519
520/// in Z: 1
521/// in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that
522///                                   is co-prime with k
523/// in Z/2^kZ: largest odd divisor of n (taken in Z)
524/// other cases: not implemented
525// CF: shold imply that n/GetUnit(n) is normalized in Z/kZ
526//   it would make more sense to return the inverse...
527static FORCE_INLINE number n_GetUnit(number n, const coeffs r)
528{ STATISTIC(n_GetUnit); assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
529
530static FORCE_INLINE coeffs n_CoeffRingQuot1(number c, const coeffs r)
531{ STATISTIC(n_CoeffRingQuot1); assume(r != NULL); assume(r->cfQuot1 != NULL); return r->cfQuot1(c, r); }
532#endif
533
534/// a number representing i in the given coeff field/ring r
535static FORCE_INLINE number n_Init(long i,       const coeffs r)
536{ STATISTIC(n_Init); assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
537
538/// conversion of a GMP integer to number
539static FORCE_INLINE number n_InitMPZ(mpz_t n,     const coeffs r)
540{ STATISTIC(n_InitMPZ); assume(r != NULL); assume(r->cfInitMPZ != NULL); return r->cfInitMPZ(n,r); }
541
542/// conversion of n to an int; 0 if not possible
543/// in Z/pZ: the representing int lying in (-p/2 .. p/2]
544static FORCE_INLINE int n_Int(number &n,       const coeffs r)
545{ STATISTIC(n_Int); assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
546
547/// conversion of n to a GMP integer; 0 if not possible
548static FORCE_INLINE void n_MPZ(mpz_t result, number &n,       const coeffs r)
549{ STATISTIC(n_MPZ); assume(r != NULL); assume(r->cfMPZ!=NULL); r->cfMPZ(result, n, r); }
550
551
552/// in-place negation of n
553/// MUST BE USED: n = n_InpNeg(n) (no copy is returned)
554static FORCE_INLINE number n_InpNeg(number n,     const coeffs r)
555{ STATISTIC(n_InpNeg); assume(r != NULL); assume(r->cfInpNeg!=NULL); return r->cfInpNeg(n,r); }
556
557/// return the multiplicative inverse of 'a';
558/// raise an error if 'a' is not invertible
559///
560/// !!! Recommendation: rename to 'n_Inverse'
561static FORCE_INLINE number n_Invers(number a,  const coeffs r)
562{ STATISTIC(n_Invers); assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
563
564/// return a non-negative measure for the complexity of n;
565/// return 0 only when n represents zero;
566/// (used for pivot strategies in matrix computations with entries from r)
567static FORCE_INLINE int    n_Size(number n,    const coeffs r)
568{ STATISTIC(n_Size); assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
569
570/// inplace-normalization of n;
571/// produces some canonical representation of n;
572///
573/// !!! Recommendation: remove this method from the user-interface, i.e.,
574/// !!!                 this should be hidden
575static FORCE_INLINE void   n_Normalize(number& n, const coeffs r)
576{ STATISTIC(n_Normalize); assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
577
578/// write to the output buffer of the currently used reporter
579//CF: the "&" should be removed, as one wants to write constants as well
580static FORCE_INLINE void   n_WriteLong(number& n,  const coeffs r)
581{ STATISTIC(n_WriteLong); assume(r != NULL); assume(r->cfWriteLong!=NULL); r->cfWriteLong(n,r); }
582
583/// write to the output buffer of the currently used reporter
584/// in a shortest possible way, e.g. in K(a): a2 instead of a^2
585static FORCE_INLINE void   n_WriteShort(number& n,  const coeffs r)
586{ STATISTIC(n_WriteShort); assume(r != NULL); assume(r->cfWriteShort!=NULL); r->cfWriteShort(n,r); }
587
588static FORCE_INLINE void   n_Write(number& n,  const coeffs r, const BOOLEAN bShortOut = TRUE)
589{ STATISTIC(n_Write); if (bShortOut) n_WriteShort(n, r); else n_WriteLong(n, r); }
590
591
592/// !!! Recommendation: This method is too cryptic to be part of the user-
593/// !!!                 interface. As defined here, it is merely a helper
594/// !!!                 method for parsing number input strings.
595static FORCE_INLINE const char *n_Read(const char * s, number * a, const coeffs r)
596{ STATISTIC(n_Read); assume(r != NULL); assume(r->cfRead!=NULL); return r->cfRead(s, a, r); }
597
598/// return the denominator of n
599/// (if elements of r are by nature not fractional, result is 1)
600static FORCE_INLINE number n_GetDenom(number& n, const coeffs r)
601{ STATISTIC(n_GetDenom); assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
602
603/// return the numerator of n
604/// (if elements of r are by nature not fractional, result is n)
605static FORCE_INLINE number n_GetNumerator(number& n, const coeffs r)
606{ STATISTIC(n_GetNumerator); assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
607
608/// return the quotient of 'a' and 'b', i.e., a/b;
609/// raise an error if 'b' is not invertible in r
610/// exception in Z: raises an error if 'a' is not divisible by 'b'
611static FORCE_INLINE number n_Div(number a, number b, const coeffs r)
612{ STATISTIC(n_Div); assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
613
614/// assume that there is a canonical subring in cf and we know
615/// that division is possible for these a and b in the subring,
616/// n_ExactDiv performs it, may skip additional tests.
617/// Can always be substituted by n_Div at the cost of larger  computing time.
618static FORCE_INLINE number n_ExactDiv(number a, number b, const coeffs r)
619{ STATISTIC(n_ExactDiv); assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
620
621/// for r a field, return n_Init(0,r)
622/// otherwise: n_Div(a,b,r)*b+n_IntMod(a,b,r)==a
623static FORCE_INLINE number n_IntMod(number a, number b, const coeffs r)
624{ STATISTIC(n_IntMod); assume(r != NULL); return r->cfIntMod(a,b,r); }
625
626/// fill res with the power a^b
627static FORCE_INLINE void   n_Power(number a, int b, number *res, const coeffs r)
628{ STATISTIC(n_Power); assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
629
630/// return the product of 'a' and 'b', i.e., a*b
631static FORCE_INLINE number n_Mult(number a, number b, const coeffs r)
632{ STATISTIC(n_Mult); assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
633
634/// multiplication of 'a' and 'b';
635/// replacement of 'a' by the product a*b
636static FORCE_INLINE void n_InpMult(number &a, number b, const coeffs r)
637{ STATISTIC(n_InpMult); assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
638
639/// addition of 'a' and 'b';
640/// replacement of 'a' by the sum a+b
641static FORCE_INLINE void n_InpAdd(number &a, number b, const coeffs r)
642{ STATISTIC(n_InpAdd); assume(r != NULL); assume(r->cfInpAdd!=NULL); r->cfInpAdd(a,b,r);
643
644#ifdef HAVE_NUMSTATS
645  // avoid double counting
646  if( r->cfIsZero(a,r) ) STATISTIC(n_CancelOut);
647#endif
648}
649
650/// return the sum of 'a' and 'b', i.e., a+b
651static FORCE_INLINE number n_Add(number a, number b, const coeffs r)
652{ STATISTIC(n_Add); assume(r != NULL); assume(r->cfAdd!=NULL); const number sum = r->cfAdd(a, b, r);
653
654#ifdef HAVE_NUMSTATS
655  // avoid double counting
656  if( r->cfIsZero(sum,r) ) STATISTIC(n_CancelOut);
657#endif
658
659 return sum;
660}
661
662/// return the difference of 'a' and 'b', i.e., a-b
663static FORCE_INLINE number n_Sub(number a, number b, const coeffs r)
664{ STATISTIC(n_Sub); assume(r != NULL); assume(r->cfSub!=NULL); const number d = r->cfSub(a, b, r);
665
666#ifdef HAVE_NUMSTATS
667  // avoid double counting
668  if( r->cfIsZero(d,r) ) STATISTIC(n_CancelOut);
669#endif
670
671  return d;
672}
673
674/// in Z: return the gcd of 'a' and 'b'
675/// in Z/nZ, Z/2^kZ: computed as in the case Z
676/// in Z/pZ, C, R: not implemented
677/// in Q: return the gcd of the numerators of 'a' and 'b'
678/// in K(a)/<p(a)>: not implemented
679/// in K(t_1, ..., t_n): not implemented
680static FORCE_INLINE number n_Gcd(number a, number b, const coeffs r)
681{ STATISTIC(n_Gcd); assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
682static FORCE_INLINE number n_SubringGcd(number a, number b, const coeffs r)
683{ STATISTIC(n_SubringGcd); assume(r != NULL); assume(r->cfSubringGcd!=NULL); return r->cfSubringGcd(a,b,r); }
684
685/// beware that ExtGCD is only relevant for a few chosen coeff. domains
686/// and may perform something unexpected in some cases...
687static FORCE_INLINE number n_ExtGcd(number a, number b, number *s, number *t, const coeffs r)
688{ STATISTIC(n_ExtGcd); assume(r != NULL); assume(r->cfExtGcd!=NULL); return r->cfExtGcd (a,b,s,t,r); }
689static FORCE_INLINE number n_XExtGcd(number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
690{ STATISTIC(n_XExtGcd); assume(r != NULL); assume(r->cfXExtGcd!=NULL); return r->cfXExtGcd (a,b,s,t,u,v,r); }
691static FORCE_INLINE number  n_EucNorm(number a, const coeffs r)
692{ STATISTIC(n_EucNorm); assume(r != NULL); assume(r->cfEucNorm!=NULL); return r->cfEucNorm (a,r); }
693/// if r is a ring with zero divisors, return an annihilator!=0 of b
694/// otherwise return NULL
695static FORCE_INLINE number  n_Ann(number a, const coeffs r)
696{ STATISTIC(n_Ann); assume(r != NULL); return r->cfAnn (a,r); }
697static FORCE_INLINE number  n_QuotRem(number a, number b, number *q, const coeffs r)
698{ STATISTIC(n_QuotRem); assume(r != NULL); assume(r->cfQuotRem!=NULL); return r->cfQuotRem (a,b,q,r); }
699
700
701/// in Z: return the lcm of 'a' and 'b'
702/// in Z/nZ, Z/2^kZ: computed as in the case Z
703/// in Z/pZ, C, R: not implemented
704/// in K(a)/<p(a)>: not implemented
705/// in K(t_1, ..., t_n): not implemented
706static FORCE_INLINE number n_Lcm(number a, number b, const coeffs r)
707{ STATISTIC(n_Lcm); assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
708
709/// assume that r is a quotient field (otherwise, return 1)
710/// for arguments (a1/a2,b1/b2) return (lcm(a1,b2)/1)
711static FORCE_INLINE number n_NormalizeHelper(number a, number b, const coeffs r)
712{ STATISTIC(n_NormalizeHelper); assume(r != NULL); assume(r->cfNormalizeHelper!=NULL); return r->cfNormalizeHelper(a,b,r); }
713
714/// set the mapping function pointers for translating numbers from src to dst
715static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
716{ STATISTIC(n_SetMap); assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
717
718#ifdef LDEBUG
719/// test whether n is a correct number;
720/// only used if LDEBUG is defined
721static FORCE_INLINE BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
722{ STATISTIC(n_Test); assume(r != NULL); assume(r->cfDBTest != NULL); return r->cfDBTest(n, filename, linenumber, r); }
723#else
724// is it really necessary to define this function in any case?
725/// test whether n is a correct number;
726/// only used if LDEBUG is defined
727static FORCE_INLINE BOOLEAN n_DBTest(number, const char*, const int, const coeffs)
728{ STATISTIC(n_Test);  return TRUE; }
729#endif
730
731/// output the coeff description
732static FORCE_INLINE void   n_CoeffWrite(const coeffs r, BOOLEAN details = TRUE)
733{ STATISTIC(n_CoeffWrite); assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r, details); }
734
735// Tests:
736static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
737{ assume(r != NULL); return (getCoeffType(r)==n_Z2m); }
738
739static FORCE_INLINE BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
740{ assume(r != NULL); return (getCoeffType(r)==n_Zn); }
741
742static FORCE_INLINE BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
743{ assume(r != NULL); return (getCoeffType(r)==n_Znm); }
744
745static FORCE_INLINE BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
746{ assume(r != NULL); return (getCoeffType(r)==n_Z); }
747
748static FORCE_INLINE BOOLEAN nCoeff_is_Ring(const coeffs r)
749{ assume(r != NULL); return (r->is_field==0); }
750
751/// returns TRUE, if r is a field or r has no zero divisors (i.e is a domain)
752static FORCE_INLINE BOOLEAN nCoeff_is_Domain(const coeffs r)
753{
754  assume(r != NULL);
755  return (r->is_domain);
756}
757
758/// test whether 'a' is divisible 'b';
759/// for r encoding a field: TRUE iff 'b' does not represent zero
760/// in Z: TRUE iff 'b' divides 'a' (with remainder = zero)
761/// in Z/nZ: TRUE iff (a = 0 and b divides n in Z) or
762///                   (a != 0 and b/gcd(a, b) is co-prime with n, i.e.
763///                                              a unit in Z/nZ)
764/// in Z/2^kZ: TRUE iff ((a = 0 mod 2^k) and (b = 0 or b is a power of 2))
765///                  or ((a, b <> 0) and (b/gcd(a, b) is odd))
766static FORCE_INLINE BOOLEAN n_DivBy(number a, number b, const coeffs r)
767{ STATISTIC(n_DivBy); assume(r != NULL);
768#ifdef HAVE_RINGS
769  if( nCoeff_is_Ring(r) )
770  {
771    assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r);
772  }
773#endif
774  return !n_IsZero(b, r);
775}
776
777static FORCE_INLINE number n_ChineseRemainderSym(number *a, number *b, int rl, BOOLEAN sym,const coeffs r)
778{ STATISTIC(n_ChineseRemainderSym); assume(r != NULL); assume(r->cfChineseRemainder != NULL); return r->cfChineseRemainder(a,b,rl,sym,r); }
779
780static FORCE_INLINE number n_Farey(number a, number b, const coeffs r)
781{ STATISTIC(n_Farey); assume(r != NULL); assume(r->cfFarey != NULL); return r->cfFarey(a,b,r); }
782
783static FORCE_INLINE int n_ParDeg(number n, const coeffs r)
784{ STATISTIC(n_ParDeg); assume(r != NULL); assume(r->cfParDeg != NULL); return r->cfParDeg(n,r); }
785
786/// Returns the number of parameters
787static FORCE_INLINE int n_NumberOfParameters(const coeffs r)
788{ STATISTIC(n_NumberOfParameters); assume(r != NULL); return r->iNumberOfParameters; }
789
790/// Returns a (const!) pointer to (const char*) names of parameters
791static FORCE_INLINE char const * * n_ParameterNames(const coeffs r)
792{ STATISTIC(n_ParameterNames); assume(r != NULL); return r->pParameterNames; }
793
794/// return the (iParameter^th) parameter as a NEW number
795/// NOTE: parameter numbering: 1..n_NumberOfParameters(...)
796static FORCE_INLINE number n_Param(const int iParameter, const coeffs r)
797{ assume(r != NULL);
798  assume((iParameter >= 1) || (iParameter <= n_NumberOfParameters(r)));
799  assume(r->cfParameter != NULL);
800  STATISTIC(n_Param); return r->cfParameter(iParameter, r);
801}
802
803static FORCE_INLINE number  n_RePart(number i, const coeffs cf)
804{ STATISTIC(n_RePart); assume(cf != NULL); assume(cf->cfRePart!=NULL); return cf->cfRePart(i,cf); }
805
806static FORCE_INLINE number  n_ImPart(number i, const coeffs cf)
807{ STATISTIC(n_ImPart); assume(cf != NULL); assume(cf->cfImPart!=NULL); return cf->cfImPart(i,cf); }
808
809/// returns TRUE, if r is not a field and r has non-trivial units
810static FORCE_INLINE BOOLEAN nCoeff_has_Units(const coeffs r)
811{ assume(r != NULL); return ((getCoeffType(r)==n_Zn) || (getCoeffType(r)==n_Z2m) || (getCoeffType(r)==n_Znm)); }
812
813static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
814{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
815
816static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
817{ assume(r != NULL); return ((getCoeffType(r)==n_Zp) && (r->ch == p)); }
818
819static FORCE_INLINE BOOLEAN nCoeff_is_Q(const coeffs r)
820{ assume(r != NULL); return getCoeffType(r)==n_Q && (r->is_field); }
821
822static FORCE_INLINE BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
823{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
824// (r->ringtype == 0) && (r->ch ==  -1); ??
825
826static FORCE_INLINE BOOLEAN nCoeff_is_R(const coeffs r)
827{ assume(r != NULL); return getCoeffType(r)==n_R; }
828
829static FORCE_INLINE BOOLEAN nCoeff_is_GF(const coeffs r)
830{ assume(r != NULL); return getCoeffType(r)==n_GF; }
831
832static FORCE_INLINE BOOLEAN nCoeff_is_GF(const coeffs r, int q)
833{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
834
835/* TRUE iff r represents an algebraic or transcendental extension field */
836static FORCE_INLINE BOOLEAN nCoeff_is_Extension(const coeffs r)
837{
838  assume(r != NULL);
839  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
840}
841
842/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
843   svn trunk);
844   intension: should be TRUE iff the given r is an extension field above
845   some Z/pZ;
846   actually: TRUE iff the given r is an extension tower of arbitrary
847   height above some field of characteristic p (may be Z/pZ or some
848   Galois field of characteristic p) */
849static FORCE_INLINE BOOLEAN nCoeff_is_Zp_a(const coeffs r)
850{
851  assume(r != NULL);
852  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) != 0) && nCoeff_is_Extension(r));
853}
854
855/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
856   svn trunk);
857   intension: should be TRUE iff the given r is an extension field above
858   Z/pZ (with p as provided);
859   actually: TRUE iff the given r is an extension tower of arbitrary
860   height above some field of characteristic p (may be Z/pZ or some
861   Galois field of characteristic p) */
862static FORCE_INLINE BOOLEAN nCoeff_is_Zp_a(const coeffs r, int p)
863{
864  assume(r != NULL);
865  assume(p != 0);
866  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) == p) && nCoeff_is_Extension(r));
867}
868
869/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
870   svn trunk);
871   intension: should be TRUE iff the given r is an extension field
872   above Q;
873   actually: TRUE iff the given r is an extension tower of arbitrary
874   height above some field of characteristic 0 (may be Q, R, or C) */
875static FORCE_INLINE BOOLEAN nCoeff_is_Q_a(const coeffs r)
876{
877  assume(r != NULL);
878  return ((n_GetChar(r) == 0) && nCoeff_is_Extension(r));
879}
880
881
882
883
884static FORCE_INLINE BOOLEAN nCoeff_is_long_R(const coeffs r)
885{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
886
887static FORCE_INLINE BOOLEAN nCoeff_is_long_C(const coeffs r)
888{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
889
890static FORCE_INLINE BOOLEAN nCoeff_is_CF(const coeffs r)
891{ assume(r != NULL); return getCoeffType(r)==n_CF; }
892
893/// TRUE, if the computation of the inverse is fast,
894/// i.e. prefer leading coeff. 1 over content
895static FORCE_INLINE BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
896{ assume(r != NULL); return r->has_simple_Inverse; }
897
898/// TRUE if n_Delete/n_New are empty operations
899static FORCE_INLINE BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
900{ assume(r != NULL); return r->has_simple_Alloc; }
901
902/// TRUE iff r represents an algebraic extension field
903static FORCE_INLINE BOOLEAN nCoeff_is_algExt(const coeffs r)
904{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
905
906/// is it an alg. ext. of Q?
907static FORCE_INLINE BOOLEAN nCoeff_is_Q_algext(const coeffs r)
908{ assume(r != NULL); return ((n_GetChar(r) == 0) && nCoeff_is_algExt(r)); }
909
910/// TRUE iff r represents a transcendental extension field
911static FORCE_INLINE BOOLEAN nCoeff_is_transExt(const coeffs r)
912{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
913
914/// BOOLEAN n_Test(number a, const coeffs r)
915#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
916
917/// Computes the content and (inplace) divides it out on a collection
918/// of numbers
919/// number @em c is the content (i.e. the GCD of all the coeffs, which
920/// we divide out inplace)
921/// NOTE: it assumes all coefficient numbers to be integer!!!
922/// NOTE/TODO: see also the description by Hans
923/// TODO: rename into n_ClearIntegerContent
924static FORCE_INLINE void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
925{ STATISTIC(n_ClearContent); assume(r != NULL); r->cfClearContent(numberCollectionEnumerator, c, r); }
926
927/// (inplace) Clears denominators on a collection of numbers
928/// number @em d is the LCM of all the coefficient denominators (i.e. the number
929/// with which all the number coeffs. were multiplied)
930/// NOTE/TODO: see also the description by Hans
931static FORCE_INLINE void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& d, const coeffs r)
932{ STATISTIC(n_ClearDenominators); assume(r != NULL); r->cfClearDenominators(numberCollectionEnumerator, d, r); }
933
934// convenience helpers (no number returned - but the input enumeration
935// is to be changed
936// TODO: do we need separate hooks for these as our existing code does
937// *different things* there: compare p_Cleardenom (which calls
938// *p_Content) and p_Cleardenom_n (which doesn't)!!!
939
940static FORCE_INLINE void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
941{ STATISTIC(n_ClearContent); number c; n_ClearContent(numberCollectionEnumerator, c, r); n_Delete(&c, r); }
942
943static FORCE_INLINE void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
944{ STATISTIC(n_ClearDenominators); assume(r != NULL); number d; n_ClearDenominators(numberCollectionEnumerator, d, r); n_Delete(&d, r); }
945
946
947/// print a number (BEWARE of string buffers!)
948/// mostly for debugging
949void   n_Print(number& a,  const coeffs r);
950
951
952
953/// TODO: make it a virtual method of coeffs, together with:
954/// Decompose & Compose, rParameter & rPar
955static FORCE_INLINE char * nCoeffString(const coeffs cf)
956{ STATISTIC(nCoeffString); assume( cf != NULL ); return cf->cfCoeffString(cf); }
957
958
959static FORCE_INLINE char * nCoeffName (const coeffs cf)
960{ STATISTIC(nCoeffName); assume( cf != NULL ); return cf->cfCoeffName(cf); }
961
962static FORCE_INLINE number n_Random(siRandProc p, number p1, number p2, const coeffs cf)
963{ STATISTIC(n_Random); assume( cf != NULL ); assume( cf->cfRandom != NULL );  return cf->cfRandom(p, p1, p2, cf); }
964
965/// io via ssi:
966static FORCE_INLINE void n_WriteFd(number a, FILE *f, const coeffs r)
967{ STATISTIC(n_WriteFd); assume(r != NULL); assume(r->cfWriteFd != NULL); return r->cfWriteFd(a, f, r); }
968
969/// io via ssi:
970static FORCE_INLINE number n_ReadFd( s_buff f, const coeffs r)
971{ STATISTIC(n_ReadFd); assume(r != NULL); assume(r->cfReadFd != NULL); return r->cfReadFd(f, r); }
972
973
974// the following wrappers went to numbers.cc since they needed factory
975// knowledge!
976number n_convFactoryNSingN( const CanonicalForm n, const coeffs r);
977
978CanonicalForm n_convSingNFactoryN( number n, BOOLEAN setChar, const coeffs r );
979
980
981// TODO: remove the following functions...
982// the following 2 inline functions are just convenience shortcuts for Frank's code:
983static FORCE_INLINE void number2mpz(number n, coeffs c, mpz_t m){ n_MPZ(m, n, c); }
984static FORCE_INLINE number mpz2number(mpz_t m, coeffs c){ return n_InitMPZ(m, c); }
985
986#endif
987
Note: See TracBrowser for help on using the repository browser.