source: git/libpolys/coeffs/coeffs.h @ 777f8b

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