source: git/libpolys/coeffs/coeffs.h @ 7ee1907

spielwiese
Last change on this file since 7ee1907 was 7ee1907, checked in by Hans Schoenemann <hannes@…>, 12 years ago
chg: update to ssi-3
  • Property mode set to 100644
File size: 27.2 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#ifdef HAVE_FACTORY
17class CanonicalForm;
18#endif
19
20enum n_coeffType
21{
22  n_unknown=0,
23  n_Zp,
24  n_Q,
25  n_R,
26  n_GF,
27  n_long_R,
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,
35  // only used if HAVE_RINGS is defined:
36  n_Z,
37  n_Zn,
38  n_Zpn, // does no longer exist?
39  n_Z2m,
40  n_CF
41};
42
43extern unsigned short fftable[];
44
45struct snumber;
46typedef struct snumber *   number;
47
48/* standard types */
49#ifdef HAVE_RINGS
50typedef unsigned long NATNUMBER;
51typedef mpz_ptr int_number;
52#endif
53
54struct ip_sring;
55typedef struct ip_sring *         ring;
56
57struct n_Procs_s;
58typedef struct  n_Procs_s  *coeffs;
59
60typedef number (*numberfunc)(number a, number b, const coeffs r);
61
62/// maps "a", which lives in src, into dst
63typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
64
65/// Creation data needed for finite fields
66typedef struct 
67{
68  int GFChar;
69  int GFDegree;
70  const char* GFPar_name;
71} GFInfo;
72
73typedef struct
74{
75  short      float_len; /**< additional char-flags, rInit */
76  short      float_len2; /**< additional char-flags, rInit */
77  const char* par_name; /**< parameter name */
78} LongComplexInfo;
79
80struct n_Procs_s
81{
82   coeffs next;
83   unsigned int ringtype;  /* =0 => coefficient field,
84                             !=0 => coeffs from one of the rings:
85                              =1 => Z/2^mZ
86                              =2 => Z/nZ, n not a prime
87                              =3 => Z/p^mZ
88                              =4 => Z */
89
90   // general properties:
91   /// TRUE, if nNew/nDelete/nCopy are dummies
92   BOOLEAN has_simple_Alloc;
93   /// TRUE, if std should make polynomials monic (if nInvers is cheap)
94   /// if false, then a gcd routine is used for a content computation
95   BOOLEAN has_simple_Inverse;
96
97   // tests for numbers.cc:
98   BOOLEAN (*nCoeffIsEqual)(const coeffs r, n_coeffType n, void * parameter);
99
100   /// output of coeff description via Print
101   void (*cfCoeffWrite)(const coeffs r, BOOLEAN details);
102
103   // ?
104   // initialisation:
105   //void (*cfInitChar)(coeffs r, int parameter); // do one-time initialisations
106   void (*cfKillChar)(coeffs r); //  undo all initialisations
107                                // or NULL
108   void (*cfSetChar)(const coeffs r); // initialisations after each ring change
109                                // or NULL
110   // general stuff
111   numberfunc cfMult, cfSub ,cfAdd ,cfDiv, cfIntDiv, cfIntMod, cfExactDiv;
112   
113   /// init with an integer
114   number  (*cfInit)(long i,const coeffs r);
115
116   /// init with a GMP integer
117   number  (*cfInitMPZ)(mpz_t i, const coeffs r);
118   
119   /// how complicated, (0) => 0, or positive
120   int     (*cfSize)(number n, const coeffs r);
121   
122   /// convertion to int, 0 if impossible
123   int     (*cfInt)(number &n, const coeffs r);
124
125   /// Converts a non-negative number n into a GMP number, 0 if impossible
126   void     (*cfMPZ)(mpz_t result, number &n, const coeffs r);
127   
128#ifdef HAVE_RINGS
129   int     (*cfDivComp)(number a,number b,const coeffs r);
130   BOOLEAN (*cfIsUnit)(number a,const coeffs r);
131   number  (*cfGetUnit)(number a,const coeffs r);
132   number  (*cfExtGcd)(number a, number b, number *s, number *t,const coeffs r);
133#endif
134
135   /// changes argument  inline: a:= -a
136   /// return -a! (no copy is returned)
137   /// the result should be assigned to the original argument: e.g. a = n_Neg(a,r)
138   number  (*cfNeg)(number a, const coeffs r);
139   /// return 1/a
140   number  (*cfInvers)(number a, const coeffs r);
141   /// return a copy of a
142   number  (*cfCopy)(number a, const coeffs r);
143   number  (*cfRePart)(number a, const coeffs r);
144   number  (*cfImPart)(number a, const coeffs r);
145   void    (*cfWrite)(number &a, const coeffs r);
146   const char *  (*cfRead)(const char * s, number * a, const coeffs r);
147   void    (*cfNormalize)(number &a, const coeffs r);
148   BOOLEAN (*cfGreater)(number a,number b, const coeffs r),
149#ifdef HAVE_RINGS
150           (*cfDivBy)(number a, number b, const coeffs r),
151#endif
152            /// tests
153           (*cfEqual)(number a,number b, const coeffs r),
154           (*cfIsZero)(number a, const coeffs r),
155           (*cfIsOne)(number a, const coeffs r),
156           (*cfIsMOne)(number a, const coeffs r),
157           (*cfGreaterZero)(number a, const coeffs r);
158
159   void    (*cfPower)(number a, int i, number * result, const coeffs r);
160   number  (*cfGetDenom)(number &n, const coeffs r);
161   number  (*cfGetNumerator)(number &n, const coeffs r);
162   number  (*cfGcd)(number a, number b, const coeffs r);
163   number  (*cfLcm)(number a, number b, const coeffs r);
164   void    (*cfDelete)(number * a, const coeffs r);
165   nMapFunc (*cfSetMap)(const coeffs src, const coeffs dst);
166
167   /// For extensions (writes into global string buffer)
168   char *  (*cfName)(number n, const coeffs r);
169
170   /// Inplace: a *= b
171   void    (*cfInpMult)(number &a, number b, const coeffs r);
172
173   /// maps the bigint i (from dummy == coeffs_BIGINT!!!) into the
174   /// coeffs dst
175   /// TODO: to be exchanged with a map!!!
176   number  (*cfInit_bigint)(number i, const coeffs dummy, const coeffs dst);
177
178   /// rational reconstruction: best rational with mod p=n
179   number  (*cfFarey)(number p, number n, const coeffs);
180
181   /// chinese remainder
182   /// returns X with X mod q[i]=x[i], i=0..rl-1
183   number  (*cfChineseRemainder)(number *x, number *q,int rl, const coeffs);
184
185   /// degree for coeffcients: -1 for 0, 0 for "constants", ...
186   int (*cfParDeg)(number x,const coeffs r);
187
188#ifdef HAVE_FACTORY
189   number (*convFactoryNSingN)( const CanonicalForm n, const coeffs r);
190   CanonicalForm (*convSingNFactoryN)( number n, BOOLEAN setChar, const coeffs r );
191#endif
192
193
194#ifdef LDEBUG
195   /// Test: is "a" a correct number?
196   BOOLEAN (*cfDBTest)(number a, const char *f, const int l, const coeffs r);
197#endif
198
199   number nNULL; /* the 0 as constant */
200   int     char_flag;
201   int     ref;
202   /// how many variables of factort are already used by this coeff
203   int     factoryVarOffset;
204   n_coeffType type;
205
206   /////////////////////////////////////////////
207   // the union stuff
208
209   //-------------------------------------------
210
211  /* for extension fields we need to be able to represent polynomials,
212     so here is the polynomial ring: */
213  ring          extRing;
214
215  //number     minpoly;  //< no longer needed: replaced by
216  //                     //< extRing->minideal->[0]
217
218
219//-------------------------------------------
220  char* complex_parameter; //< the name of sqrt(-1), i.e. 'i' or 'j' etc...?
221
222#ifdef HAVE_RINGS
223  /* The following members are for representing the ring Z/n,
224     where n is not a prime. We distinguish four cases:
225     1.) n has at least two distinct prime factors. Then
226         modBase stores n, modExponent stores 1, modNumber
227         stores n, and mod2mMask is not used;
228     2.) n = p^k for some odd prime p and k > 1. Then
229         modBase stores p, modExponent stores k, modNumber
230         stores n, and mod2mMask is not used;
231     3.) n = 2^k for some k > 1; moreover, 2^k - 1 fits in
232         an unsigned long. Then modBase stores 2, modExponent
233         stores k, modNumber is not used, and mod2mMask stores
234         2^k - 1, i.e., the bit mask '111..1' of length k.
235     4.) n = 2^k for some k > 1; but 2^k - 1 does not fit in
236         an unsigned long. Then modBase stores 2, modExponent
237         stores k, modNumber stores n, and mod2mMask is not
238         used;
239     Cases 1.), 2.), and 4.) are covered by the implementation
240     in the files rmodulon.h and rmodulon.cc, whereas case 3.)
241     is implemented in the files rmodulo2m.h and rmodulo2m.cc. */
242  int_number    modBase;
243  unsigned long modExponent;
244  int_number    modNumber;
245  unsigned long mod2mMask;
246#endif
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  char * m_nfParameter;
276
277// ---------------------------------------------------
278// for Zp:
279#ifdef HAVE_DIV_MOD
280  unsigned short *npInvTable;
281#endif
282#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
283  unsigned short *npExpTable;
284  unsigned short *npLogTable;
285#endif
286   //   int npPrimeM; // NOTE: npPrimeM is deprecated, please use ch instead!
287  int npPminus1M; ///< characteristic - 1
288};
289//
290// test properties and type
291/// Returns the type of coeffs domain
292static inline n_coeffType getCoeffType(const coeffs r)
293{
294  assume(r != NULL);
295  return r->type;
296}
297
298/// one-time initialisations for new coeffs
299/// in case of an error return NULL
300coeffs nInitChar(n_coeffType t, void * parameter);
301
302/// undo all initialisations
303void nKillChar(coeffs r);
304
305/// initialisations after each ring change
306static inline void nSetChar(const coeffs r)
307{
308  assume(r!=NULL); // r==NULL is an error
309  assume(r->cfSetChar != NULL);
310  r->cfSetChar(r);
311}
312
313void           nNew(number * a);
314#define n_New(n, r)           nNew(n)
315
316
317// the access methods (part 2):
318
319/// return a copy of 'n'
320static inline number n_Copy(number n,    const coeffs r)
321{   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
322
323/// delete 'p'
324static inline void   n_Delete(number* p, const coeffs r)
325{   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
326
327/// TRUE iff 'a' and 'b' represent the same number;
328/// they may have different representations
329static inline BOOLEAN n_Equal(number a, number b, const coeffs r)
330{ assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
331
332/// TRUE iff 'n' represents the zero element
333static inline BOOLEAN n_IsZero(number n, const coeffs r)
334{ assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
335
336/// TRUE iff 'n' represents the one element
337static inline BOOLEAN n_IsOne(number n,  const coeffs r)
338{ assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
339
340/// TRUE iff 'n' represents the additive inverse of the one element, i.e. -1
341static inline BOOLEAN n_IsMOne(number n, const coeffs r)
342{ assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
343
344/// ordered fields: TRUE iff 'n' is positive;
345/// in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2), where m is the long
346///          representing n
347/// in C:    TRUE iff (Im(n) != 0 and Im(n) >= 0) or
348///                   (Im(n) == 0 and Re(n) >= 0)
349/// in K(a)/<p(a)>: TRUE iff (n != 0 and (LC(n) > 0 or deg(n) > 0))
350/// in K(t_1, ..., t_n): TRUE iff (LC(numerator(n) is a constant and > 0)
351///                            or (LC(numerator(n) is not a constant)
352/// in Z/2^kZ: TRUE iff 0 < n <= 2^(k-1)
353/// in Z/mZ: TRUE iff the internal mpz is greater than zero
354/// in Z: TRUE iff n > 0
355///
356/// !!! Recommendation: remove implementations for unordered fields
357/// !!!                 and raise errors instead, in these cases
358/// !!! Do not follow this recommendation: while writing polys,
359/// !!! between 2 monomials will be an additional + iff !n_GreaterZero(next coeff)
360///
361static inline BOOLEAN n_GreaterZero(number n, const coeffs r)
362{
363  assume(r != NULL); assume(r->cfGreaterZero!=NULL);
364  return r->cfGreaterZero(n,r);
365}
366
367/// ordered fields: TRUE iff 'a' is larger than 'b';
368/// in Z/pZ: TRUE iff la > lb, where la and lb are the long's representing
369//                             a and b, respectively
370/// in C:    TRUE iff (Im(a) > Im(b))
371/// in K(a)/<p(a)>: TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b))
372/// in K(t_1, ..., t_n): TRUE only if one or both numerator polynomials are
373///                      zero or if their degrees are equal. In this case,
374///                      TRUE if LC(numerator(a)) > LC(numerator(b))
375/// in Z/2^kZ: TRUE if n_DivBy(a, b)
376/// in Z/mZ: TRUE iff the internal mpz's fulfill the relation '>'
377/// in Z: TRUE iff a > b
378///
379/// !!! Recommendation: remove implementations for unordered fields
380/// !!!                 and raise errors instead, in these cases
381static inline BOOLEAN n_Greater(number a, number b, const coeffs r)
382{ assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
383
384#ifdef HAVE_RINGS
385/// TRUE iff n has a multiplicative inverse in the given coeff field/ring r
386static inline BOOLEAN n_IsUnit(number n, const coeffs r)
387{ assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
388
389static inline number n_ExtGcd(number a, number b, number *s, number *t, const coeffs r)
390{ assume(r != NULL); assume(r->cfExtGcd!=NULL); return r->cfExtGcd (a,b,s,t,r); }
391
392static inline int n_DivComp(number a, number b, const coeffs r)
393{ assume(r != NULL); assume(r->cfDivComp!=NULL); return r->cfDivComp (a,b,r); }
394
395/// in Z: 1
396/// in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that
397///                                   is co-prime with k
398/// in Z/2^kZ: largest odd divisor of n (taken in Z)
399/// other cases: not implemented
400static inline number n_GetUnit(number n, const coeffs r)
401{ assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
402#endif
403
404/// a number representing i in the given coeff field/ring r
405static inline number n_Init(long i,       const coeffs r)
406{ assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
407
408/// conversion of a GMP integer to number
409static inline number n_InitMPZ(mpz_t n,     const coeffs r)
410{ assume(r != NULL); assume(r->cfInitMPZ != NULL); return r->cfInitMPZ(n,r); }
411
412/// conversion of n to an int; 0 if not possible
413/// in Z/pZ: the representing int lying in (-p/2 .. p/2]
414static inline int n_Int(number &n,       const coeffs r)
415{ assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
416
417/// conversion of n to a GMP integer; 0 if not possible
418static inline void n_MPZ(mpz_t result, number &n,       const coeffs r)
419{ assume(r != NULL); assume(r->cfMPZ!=NULL); r->cfMPZ(result, n, r); }
420
421
422/// in-place negation of n
423/// MUST BE USED: n = n_Neg(n) (no copy is returned)
424static inline number n_Neg(number n,     const coeffs r)
425{ assume(r != NULL); assume(r->cfNeg!=NULL); return r->cfNeg(n,r); }
426
427/// return the multiplicative inverse of 'a';
428/// raise an error if 'a' is not invertible
429///
430/// !!! Recommendation: rename to 'n_Inverse'
431static inline number n_Invers(number a,  const coeffs r)
432{ assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
433
434/// return a non-negative measure for the complexity of n;
435/// return 0 only when n represents zero;
436/// (used for pivot strategies in matrix computations with entries from r)
437static inline int    n_Size(number n,    const coeffs r)
438{ assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
439
440/// inplace-normalization of n;
441/// produces some canonical representation of n;
442///
443/// !!! Recommendation: remove this method from the user-interface, i.e.,
444/// !!!                 this should be hidden
445static inline void   n_Normalize(number& n, const coeffs r)
446{ assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
447
448/// write to the output buffer of the currently used reporter
449static inline void   n_Write(number& n,  const coeffs r)
450{ assume(r != NULL); assume(r->cfWrite!=NULL); r->cfWrite(n,r); }
451
452/// @todo: Describe me!!! --> Hans
453///
454/// !!! Recommendation: This method is to cryptic to be part of the user-
455/// !!!                 interface. As defined here, it is merely a helper
456/// !!!                 method for parsing number input strings.
457static inline const char *n_Read(const char * s, number * a, const coeffs r)
458{ assume(r != NULL); assume(r->cfRead!=NULL); return r->cfRead(s, a, r); }
459
460/// return the denominator of n
461/// (if elements of r are by nature not fractional, result is 1)
462static inline number n_GetDenom(number& n, const coeffs r)
463{ assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
464
465/// return the numerator of n
466/// (if elements of r are by nature not fractional, result is n)
467static inline number n_GetNumerator(number& n, const coeffs r)
468{ assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
469
470/// fill res with the power a^b
471static inline void   n_Power(number a, int b, number *res, const coeffs r)
472{ assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
473
474/// return the product of 'a' and 'b', i.e., a*b
475static inline number n_Mult(number a, number b, const coeffs r)
476{ assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
477
478/// multiplication of 'a' and 'b';
479/// replacement of 'a' by the product a*b
480static inline void n_InpMult(number &a, number b, const coeffs r)
481{ assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
482
483/// return the difference of 'a' and 'b', i.e., a-b
484static inline number n_Sub(number a, number b, const coeffs r)
485{ assume(r != NULL); assume(r->cfSub!=NULL); return r->cfSub(a, b, r); }
486
487/// return the sum of 'a' and 'b', i.e., a+b
488static inline number n_Add(number a, number b, const coeffs r)
489{ assume(r != NULL); assume(r->cfAdd!=NULL); return r->cfAdd(a, b, r); }
490
491/// return the quotient of 'a' and 'b', i.e., a/b;
492/// raise an error if 'b' is not invertible in r
493static inline number n_Div(number a, number b, const coeffs r)
494{ assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
495
496/// in Z: largest c such that c*b <= a
497/// in Z/nZ, Z/2^kZ: computed as in the case Z (from integers representing
498///                  'a' and 'b')
499/// in Z/pZ: return a/b
500/// in K(a)/<p(a)>: return a/b
501/// in K(t_1, ..., t_n): return a/b
502/// other fields: not implemented
503static inline number n_IntDiv(number a, number b, const coeffs r)
504{ assume(r != NULL); assume(r->cfIntDiv!=NULL); return r->cfIntDiv(a,b,r); }
505
506static inline number n_IntMod(number a, number b, const coeffs r)
507{ assume(r != NULL); assume(r->cfIntMod!=NULL); return r->cfIntMod(a,b,r); }
508/// @todo: Describe me!!!
509///
510/// What is the purpose of this method, especially in comparison with
511/// n_Div?
512/// !!! Recommendation: remove this method from the user-interface.
513static inline number n_ExactDiv(number a, number b, const coeffs r)
514{ assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
515
516/// in Z: return the gcd of 'a' and 'b'
517/// in Z/nZ, Z/2^kZ: computed as in the case Z
518/// in Z/pZ, C, R: not implemented
519/// in Q: return the gcd of the numerators of 'a' and 'b'
520/// in K(a)/<p(a)>: not implemented
521/// in K(t_1, ..., t_n): not implemented
522static inline number n_Gcd(number a, number b, const coeffs r)
523{ assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
524
525/// in Z: return the lcm of 'a' and 'b'
526/// in Z/nZ, Z/2^kZ: computed as in the case Z
527/// in Z/pZ, C, R: not implemented
528/// in Q: return the lcm of the numerators of 'a' and the denominator of 'b'
529/// in K(a)/<p(a)>: not implemented
530/// in K(t_1, ..., t_n): not implemented
531static inline number n_Lcm(number a, number b, const coeffs r)
532{ assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
533
534/// set the mapping function pointers for translating numbers from src to dst
535static inline nMapFunc n_SetMap(const coeffs src, const coeffs dst)
536{ assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
537
538/// test whether n is a correct number;
539/// only used if LDEBUG is defined
540static inline BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
541{
542  assume(r != NULL); 
543#ifdef LDEBUG
544  assume(r->cfDBTest != NULL); 
545  return r->cfDBTest(n, filename, linenumber, r);
546#else
547  return TRUE;
548#endif
549}
550
551/// output the coeff description
552static inline void   n_CoeffWrite(const coeffs r, BOOLEAN details = TRUE)
553{ assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r, details); }
554
555// Tests:
556static inline BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
557{ assume(r != NULL); return (r->ringtype == 1); }
558
559static inline BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
560{ assume(r != NULL); return (r->ringtype == 2); }
561
562static inline BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
563{ assume(r != NULL); return (r->ringtype == 3); }
564
565static inline BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
566{ assume(r != NULL); return (r->ringtype == 4); }
567
568static inline BOOLEAN nCoeff_is_Ring(const coeffs r)
569{ assume(r != NULL); return (r->ringtype != 0); }
570
571/// returns TRUE, if r is not a field and r has no zero divisors (i.e is a domain)
572static inline BOOLEAN nCoeff_is_Domain(const coeffs r)
573{
574  assume(r != NULL); 
575#ifdef HAVE_RINGS
576  return (r->ringtype == 4 || r->ringtype == 0);
577#else
578  return TRUE;
579#endif
580}
581
582/// test whether 'a' is divisible 'b';
583/// for r encoding a field: TRUE iff 'b' does not represent zero
584/// in Z: TRUE iff 'b' divides 'a' (with remainder = zero)
585/// in Z/nZ: TRUE iff (a = 0 and b divides n in Z) or
586///                   (a != 0 and b/gcd(a, b) is co-prime with n, i.e.
587///                                              a unit in Z/nZ)
588/// in Z/2^kZ: TRUE iff ((a = 0 mod 2^k) and (b = 0 or b is a power of 2))
589///                  or ((a, b <> 0) and (b/gcd(a, b) is odd))
590static inline BOOLEAN n_DivBy(number a, number b, const coeffs r)
591{
592  assume(r != NULL);
593#ifdef HAVE_RINGS
594  if( nCoeff_is_Ring(r) )
595  {
596    assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r);
597  }
598#endif
599  return !n_IsZero(b, r);
600}
601
602static inline number n_ChineseRemainder(number *a, number *b, int rl, const coeffs r)
603{
604  assume(r != NULL);
605  return r->cfChineseRemainder(a,b,rl,r);
606}
607
608static inline number n_Farey(number a, number b, const coeffs r)
609{
610  assume(r != NULL);
611  return r->cfFarey(a,b,r);
612}
613
614static inline int n_ParDeg(number n, const coeffs r)
615{ 
616  assume(r != NULL);
617  return r->cfParDeg(n,r); 
618}
619
620static inline number  n_Init_bigint(number i, const coeffs dummy,
621                const coeffs dst)
622{
623  assume(dummy != NULL && dst != NULL); assume(dst->cfInit_bigint!=NULL); 
624  return dst->cfInit_bigint(i, dummy, dst);
625}
626
627static inline number  n_RePart(number i, const coeffs cf)
628{
629  assume(cf != NULL); assume(cf->cfRePart!=NULL); 
630  return cf->cfRePart(i,cf);
631}
632static inline number  n_ImPart(number i, const coeffs cf)
633{
634  assume(cf != NULL); assume(cf->cfImPart!=NULL); 
635  return cf->cfImPart(i,cf);
636}
637
638/// returns TRUE, if r is not a field and r has non-trivial units
639static inline BOOLEAN nCoeff_has_Units(const coeffs r)
640{ assume(r != NULL); return ((r->ringtype == 1) || (r->ringtype == 2) || (r->ringtype == 3)); }
641
642static inline BOOLEAN nCoeff_is_Zp(const coeffs r)
643{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
644
645static inline BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
646{ assume(r != NULL); return (getCoeffType(r)  && (r->ch == p)); }
647
648static inline BOOLEAN nCoeff_is_Q(const coeffs r)
649{ assume(r != NULL); return getCoeffType(r)==n_Q; }
650
651static inline BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
652{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
653// (r->ringtype == 0) && (r->ch ==  -1); ??
654
655static inline BOOLEAN nCoeff_is_R(const coeffs r)
656{ assume(r != NULL); return getCoeffType(r)==n_R; }
657
658static inline BOOLEAN nCoeff_is_GF(const coeffs r)
659{ assume(r != NULL); return getCoeffType(r)==n_GF; }
660
661static inline BOOLEAN nCoeff_is_GF(const coeffs r, int q)
662{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
663
664/* TRUE iff r represents an algebraic or transcendental extension field */
665static inline BOOLEAN nCoeff_is_Extension(const coeffs r)
666{
667  assume(r != NULL);
668  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
669}
670
671/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
672   svn trunk);
673   intension: should be TRUE iff the given r is an extension field above
674   some Z/pZ;
675   actually: TRUE iff the given r is an extension tower of arbitrary
676   height above some field of characteristic p (may be Z/pZ or some
677   Galois field of characteristic p) */
678static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r)
679{
680  assume(r != NULL);
681  return ((r->ringtype == 0) && (r->ch != 0) && nCoeff_is_Extension(r));
682}
683
684/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
685   svn trunk);
686   intension: should be TRUE iff the given r is an extension field above
687   Z/pZ (with p as provided);
688   actually: TRUE iff the given r is an extension tower of arbitrary
689   height above some field of characteristic p (may be Z/pZ or some
690   Galois field of characteristic p) */
691static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r, int p)
692{
693  assume(r != NULL);
694  return ((r->ringtype == 0) && (r->ch == p) && nCoeff_is_Extension(r));
695}
696
697/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
698   svn trunk);
699   intension: should be TRUE iff the given r is an extension field
700   above Q;
701   actually: TRUE iff the given r is an extension tower of arbitrary
702   height above some field of characteristic 0 (may be Q, R, or C) */
703static inline BOOLEAN nCoeff_is_Q_a(const coeffs r)
704{
705  assume(r != NULL);
706  return ((r->ringtype == 0) && (r->ch == 0) && nCoeff_is_Extension(r));
707}
708
709static inline BOOLEAN nCoeff_is_long_R(const coeffs r)
710{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
711
712static inline BOOLEAN nCoeff_is_long_C(const coeffs r)
713{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
714
715static inline BOOLEAN nCoeff_is_CF(const coeffs r)
716{ assume(r != NULL); return getCoeffType(r)==n_CF; }
717
718/// TRUE, if the computation of the inverse is fast,
719/// i.e. prefer leading coeff. 1 over content
720static inline BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
721{ assume(r != NULL); return r->has_simple_Inverse; }
722
723/// TRUE if n_Delete/n_New are empty operations
724static inline BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
725{ assume(r != NULL); return r->has_simple_Alloc; }
726
727/// TRUE iff r represents an algebraic extension field
728static inline BOOLEAN nCoeff_is_algExt(const coeffs r)
729{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
730
731/// TRUE iff r represents a transcendental extension field
732static inline BOOLEAN nCoeff_is_transExt(const coeffs r)
733{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
734
735/// BOOLEAN n_Test(number a, const coeffs r)
736#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
737
738// Missing wrappers for: (TODO: review this?)
739// cfIntMod, cfRead, cfName, cfInit_bigint
740// HAVE_RINGS: cfDivComp, cfExtGcd...
741
742/// Return the characteristic of the coeff. domain.
743static inline int n_GetChar(const coeffs r)
744{
745  assume(r != NULL);
746  return r->ch;
747}
748
749#endif
750
Note: See TracBrowser for help on using the repository browser.