source: git/libpolys/coeffs/coeffs.h @ 4b38e3

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