source: git/libpolys/coeffs/coeffs.h @ 6a70f3

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