source: git/libpolys/coeffs/coeffs.h @ 5b5409b

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