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

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