source: git/libpolys/coeffs/coeffs.h @ 920581

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