source: git/libpolys/coeffs/coeffs.h @ 0acf3e

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