source: git/libpolys/coeffs/coeffs.h @ 32cc7e

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