source: git/libpolys/coeffs/coeffs.h @ 03f7b5

fieker-DuValspielwiese
Last change on this file since 03f7b5 was 03f7b5, checked in by Oleksandr Motsak <motsak@…>, 13 years ago
ADD: detailed printing vs typing for coeff. domains (mostly - minpoly related)
  • Property mode set to 100644
File size: 26.7 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   // 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   CanShortOut; //< if the elements can be printed in short format
260                       // this is set to FALSE if a parameter name has >2 chars
261  BOOLEAN   ShortOut; //< if the elements should print in short format
262
263// ---------------------------------------------------
264  // for n_GF
265
266  int m_nfCharQ;  ///< the number of elements: q
267  int m_nfM1;       ///< representation of -1
268  int m_nfCharP;  ///< the characteristic: p
269  int m_nfCharQ1; ///< q-1
270  unsigned short *m_nfPlus1Table;
271  int *m_nfMinPoly;
272  char * m_nfParameter;
273};
274//
275// test properties and type
276/// Returns the type of coeffs domain
277static inline n_coeffType getCoeffType(const coeffs r)
278{
279  assume(r != NULL);
280  return r->type;
281}
282
283static inline int nInternalChar(const coeffs r)
284{
285  assume(r != NULL);
286  return r->ch;
287}
288
289/// one-time initialisations for new coeffs
290/// in case of an error return NULL
291coeffs nInitChar(n_coeffType t, void * parameter);
292
293/// undo all initialisations
294void nKillChar(coeffs r);
295
296/// initialisations after each ring change
297static inline void nSetChar(const coeffs r)
298{
299  assume(r!=NULL); // r==NULL is an error
300  assume(r->cfSetChar != NULL);
301  r->cfSetChar(r);
302}
303
304void           nNew(number * a);
305#define n_New(n, r)           nNew(n)
306
307
308// the access methods (part 2):
309
310/// return a copy of 'n'
311static inline number n_Copy(number n,    const coeffs r)
312{   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
313
314/// delete 'p'
315static inline void   n_Delete(number* p, const coeffs r)
316{   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
317
318/// TRUE iff 'a' and 'b' represent the same number;
319/// they may have different representations
320static inline BOOLEAN n_Equal(number a, number b, const coeffs r)
321{ assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
322
323/// TRUE iff 'n' represents the zero element
324static inline BOOLEAN n_IsZero(number n, const coeffs r)
325{ assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
326
327/// TRUE iff 'n' represents the one element
328static inline BOOLEAN n_IsOne(number n,  const coeffs r)
329{ assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
330
331/// TRUE iff 'n' represents the additive inverse of the one element, i.e. -1
332static inline BOOLEAN n_IsMOne(number n, const coeffs r)
333{ assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
334
335/// ordered fields: TRUE iff 'n' is positive;
336/// in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2), where m is the long
337///          representing n
338/// in C:    TRUE iff (Im(n) != 0 and Im(n) >= 0) or
339///                   (Im(n) == 0 and Re(n) >= 0)
340/// in K(a)/<p(a)>: TRUE iff (n != 0 and (LC(n) > 0 or deg(n) > 0))
341/// in K(t_1, ..., t_n): TRUE iff (LC(numerator(n) is a constant and > 0)
342///                            or (LC(numerator(n) is not a constant)
343/// in Z/2^kZ: TRUE iff 0 < n <= 2^(k-1)
344/// in Z/mZ: TRUE iff the internal mpz is greater than zero
345/// in Z: TRUE iff n > 0
346///
347/// !!! Recommendation: remove implementations for unordered fields
348/// !!!                 and raise errors instead, in these cases
349/// !!! Do not follow this recommendation: while writing polys,
350/// !!! between 2 monomials will be an additional + iff !n_GreaterZero(next coeff)
351///
352static inline BOOLEAN n_GreaterZero(number n, const coeffs r)
353{
354  assume(r != NULL); assume(r->cfGreaterZero!=NULL);
355  return r->cfGreaterZero(n,r);
356}
357
358/// ordered fields: TRUE iff 'a' is larger than 'b';
359/// in Z/pZ: TRUE iff la > lb, where la and lb are the long's representing
360//                             a and b, respectively
361/// in C:    TRUE iff (Im(a) > Im(b))
362/// in K(a)/<p(a)>: TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b))
363/// in K(t_1, ..., t_n): TRUE only if one or both numerator polynomials are
364///                      zero or if their degrees are equal. In this case,
365///                      TRUE if LC(numerator(a)) > LC(numerator(b))
366/// in Z/2^kZ: TRUE if n_DivBy(a, b)
367/// in Z/mZ: TRUE iff the internal mpz's fulfill the relation '>'
368/// in Z: TRUE iff a > b
369///
370/// !!! Recommendation: remove implementations for unordered fields
371/// !!!                 and raise errors instead, in these cases
372static inline BOOLEAN n_Greater(number a, number b, const coeffs r)
373{ assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
374
375#ifdef HAVE_RINGS
376/// TRUE iff n has a multiplicative inverse in the given coeff field/ring r
377static inline BOOLEAN n_IsUnit(number n, const coeffs r)
378{ assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
379
380static inline number n_ExtGcd(number a, number b, number *s, number *t, const coeffs r)
381{ assume(r != NULL); assume(r->cfExtGcd!=NULL); return r->cfExtGcd (a,b,s,t,r); }
382
383static inline int n_DivComp(number a, number b, const coeffs r)
384{ assume(r != NULL); assume(r->cfDivComp!=NULL); return r->cfDivComp (a,b,r); }
385
386/// in Z: 1
387/// in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that
388///                                   is co-prime with k
389/// in Z/2^kZ: largest odd divisor of n (taken in Z)
390/// other cases: not implemented
391static inline number n_GetUnit(number n, const coeffs r)
392{ assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
393#endif
394
395/// a number representing i in the given coeff field/ring r
396static inline number n_Init(int i,       const coeffs r)
397{ assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
398
399/// conversion of a GMP integer to number
400static inline number n_Init(mpz_t n,     const coeffs r)
401{ assume(r != NULL); assume(r->cfInitMPZ != NULL); return r->cfInitMPZ(n,r); }
402
403/// conversion of n to an int; 0 if not possible
404/// in Z/pZ: the representing int lying in (-p/2 .. p/2]
405static inline int n_Int(number &n,       const coeffs r)
406{ assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
407
408/// conversion of n to a GMP integer; 0 if not possible
409static inline void n_MPZ(mpz_t result, number &n,       const coeffs r)
410{ assume(r != NULL); assume(r->cfMPZ!=NULL); r->cfMPZ(result, n, r); }
411
412
413/// in-place negation of n
414/// MUST BE USED: n = n_Neg(n) (no copy is returned)
415static inline number n_Neg(number n,     const coeffs r)
416{ assume(r != NULL); assume(r->cfNeg!=NULL); return r->cfNeg(n,r); }
417
418/// return the multiplicative inverse of 'a';
419/// raise an error if 'a' is not invertible
420///
421/// !!! Recommendation: rename to 'n_Inverse'
422static inline number n_Invers(number a,  const coeffs r)
423{ assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
424
425/// return a non-negative measure for the complexity of n;
426/// return 0 only when n represents zero;
427/// (used for pivot strategies in matrix computations with entries from r)
428static inline int    n_Size(number n,    const coeffs r)
429{ assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
430
431/// inplace-normalization of n;
432/// produces some canonical representation of n;
433///
434/// !!! Recommendation: remove this method from the user-interface, i.e.,
435/// !!!                 this should be hidden
436static inline void   n_Normalize(number& n, const coeffs r)
437{ assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
438
439/// write to the output buffer of the currently used reporter
440static inline void   n_Write(number& n,  const coeffs r)
441{ assume(r != NULL); assume(r->cfWrite!=NULL); r->cfWrite(n,r); }
442
443/// @todo: Describe me!!! --> Hans
444///
445/// !!! Recommendation: This method is to cryptic to be part of the user-
446/// !!!                 interface. As defined here, it is merely a helper
447/// !!!                 method for parsing number input strings.
448static inline const char *n_Read(const char * s, number * a, const coeffs r)
449{ assume(r != NULL); assume(r->cfRead!=NULL); return r->cfRead(s, a, r); }
450
451/// return the denominator of n
452/// (if elements of r are by nature not fractional, result is 1)
453static inline number n_GetDenom(number& n, const coeffs r)
454{ assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
455
456/// return the numerator of n
457/// (if elements of r are by nature not fractional, result is n)
458static inline number n_GetNumerator(number& n, const coeffs r)
459{ assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
460
461/// fill res with the power a^b
462static inline void   n_Power(number a, int b, number *res, const coeffs r)
463{ assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
464
465/// return the product of 'a' and 'b', i.e., a*b
466static inline number n_Mult(number a, number b, const coeffs r)
467{ assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
468
469/// multiplication of 'a' and 'b';
470/// replacement of 'a' by the product a*b
471static inline void n_InpMult(number &a, number b, const coeffs r)
472{ assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
473
474/// return the difference of 'a' and 'b', i.e., a-b
475static inline number n_Sub(number a, number b, const coeffs r)
476{ assume(r != NULL); assume(r->cfSub!=NULL); return r->cfSub(a, b, r); }
477
478/// return the sum of 'a' and 'b', i.e., a+b
479static inline number n_Add(number a, number b, const coeffs r)
480{ assume(r != NULL); assume(r->cfAdd!=NULL); return r->cfAdd(a, b, r); }
481
482/// return the quotient of 'a' and 'b', i.e., a/b;
483/// raise an error if 'b' is not invertible in r
484static inline number n_Div(number a, number b, const coeffs r)
485{ assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
486
487/// in Z: largest c such that c*b <= a
488/// in Z/nZ, Z/2^kZ: computed as in the case Z (from integers representing
489///                  'a' and 'b')
490/// in Z/pZ: return a/b
491/// in K(a)/<p(a)>: return a/b
492/// in K(t_1, ..., t_n): return a/b
493/// other fields: not implemented
494static inline number n_IntDiv(number a, number b, const coeffs r)
495{ assume(r != NULL); assume(r->cfIntDiv!=NULL); return r->cfIntDiv(a,b,r); }
496
497static inline number n_IntMod(number a, number b, const coeffs r)
498{ assume(r != NULL); assume(r->cfIntMod!=NULL); return r->cfIntMod(a,b,r); }
499/// @todo: Describe me!!!
500///
501/// What is the purpose of this method, especially in comparison with
502/// n_Div?
503/// !!! Recommendation: remove this method from the user-interface.
504static inline number n_ExactDiv(number a, number b, const coeffs r)
505{ assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
506
507/// in Z: return the gcd of 'a' and 'b'
508/// in Z/nZ, Z/2^kZ: computed as in the case Z
509/// in Z/pZ, C, R: not implemented
510/// in Q: return the gcd of the numerators of 'a' and 'b'
511/// in K(a)/<p(a)>: not implemented
512/// in K(t_1, ..., t_n): not implemented
513static inline number n_Gcd(number a, number b, const coeffs r)
514{ assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
515
516/// in Z: return the lcm 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 lcm of the numerators of 'a' and the denominator of 'b'
520/// in K(a)/<p(a)>: not implemented
521/// in K(t_1, ..., t_n): not implemented
522static inline number n_Lcm(number a, number b, const coeffs r)
523{ assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
524
525/// set the mapping function pointers for translating numbers from src to dst
526static inline nMapFunc n_SetMap(const coeffs src, const coeffs dst)
527{ assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
528
529/// test whether n is a correct number;
530/// only used if LDEBUG is defined
531static inline BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
532{
533  assume(r != NULL); 
534#ifdef LDEBUG
535  assume(r->cfDBTest != NULL); 
536  return r->cfDBTest(n, filename, linenumber, r);
537#else
538  return TRUE;
539#endif
540}
541
542/// output the coeff description
543static inline void   n_CoeffWrite(const coeffs r, BOOLEAN details = TRUE)
544{ assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r, details); }
545
546// Tests:
547static inline BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
548{ assume(r != NULL); return (r->ringtype == 1); }
549
550static inline BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
551{ assume(r != NULL); return (r->ringtype == 2); }
552
553static inline BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
554{ assume(r != NULL); return (r->ringtype == 3); }
555
556static inline BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
557{ assume(r != NULL); return (r->ringtype == 4); }
558
559static inline BOOLEAN nCoeff_is_Ring(const coeffs r)
560{ assume(r != NULL); return (r->ringtype != 0); }
561
562/// returns TRUE, if r is not a field and r has no zero divisors (i.e is a domain)
563static inline BOOLEAN nCoeff_is_Domain(const coeffs r)
564{
565  assume(r != NULL); 
566#ifdef HAVE_RINGS
567  return (r->ringtype == 4 || r->ringtype == 0);
568#else
569  return TRUE;
570#endif
571}
572
573/// test whether 'a' is divisible 'b';
574/// for r encoding a field: TRUE iff 'b' does not represent zero
575/// in Z: TRUE iff 'b' divides 'a' (with remainder = zero)
576/// in Z/nZ: TRUE iff (a = 0 and b divides n in Z) or
577///                   (a != 0 and b/gcd(a, b) is co-prime with n, i.e.
578///                                              a unit in Z/nZ)
579/// in Z/2^kZ: TRUE iff ((a = 0 mod 2^k) and (b = 0 or b is a power of 2))
580///                  or ((a, b <> 0) and (b/gcd(a, b) is odd))
581static inline BOOLEAN n_DivBy(number a, number b, const coeffs r)
582{
583  assume(r != NULL);
584#ifdef HAVE_RINGS
585  if( nCoeff_is_Ring(r) )
586  {
587    assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r);
588  }
589#endif
590  return !n_IsZero(b, r);
591}
592
593static inline number n_ChineseRemainder(number *a, number *b, int rl, const coeffs r)
594{
595  assume(r != NULL);
596  assume(getCoeffType(r)==n_Q);
597  return r->cfChineseRemainder(a,b,rl,r);
598}
599
600static inline number n_Farey(number a, number b, const coeffs r)
601{
602  assume(r != NULL);
603  assume(getCoeffType(r)==n_Q);
604  return r->cfFarey(a,b,r);
605}
606
607static inline number  n_Init_bigint(number i, const coeffs dummy,
608                const coeffs dst)
609{
610  assume(dummy != NULL && dst != NULL); assume(dst->cfInit_bigint!=NULL); 
611  return dst->cfInit_bigint(i, dummy, dst);
612}
613
614static inline number  n_RePart(number i, const coeffs cf)
615{
616  assume(cf != NULL); assume(cf->cfRePart!=NULL); 
617  return cf->cfRePart(i,cf);
618}
619static inline number  n_ImPart(number i, const coeffs cf)
620{
621  assume(cf != NULL); assume(cf->cfImPart!=NULL); 
622  return cf->cfImPart(i,cf);
623}
624
625/// returns TRUE, if r is not a field and r has non-trivial units
626static inline BOOLEAN nCoeff_has_Units(const coeffs r)
627{ assume(r != NULL); return ((r->ringtype == 1) || (r->ringtype == 2) || (r->ringtype == 3)); }
628
629static inline BOOLEAN nCoeff_is_Zp(const coeffs r)
630{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
631
632static inline BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
633{ assume(r != NULL); return (getCoeffType(r)  && (r->ch == p)); }
634
635static inline BOOLEAN nCoeff_is_Q(const coeffs r)
636{ assume(r != NULL); return getCoeffType(r)==n_Q; }
637
638static inline BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
639{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
640// (r->ringtype == 0) && (r->ch ==  -1); ??
641
642static inline BOOLEAN nCoeff_is_R(const coeffs r)
643{ assume(r != NULL); return getCoeffType(r)==n_R; }
644
645static inline BOOLEAN nCoeff_is_GF(const coeffs r)
646{ assume(r != NULL); return getCoeffType(r)==n_GF; }
647
648static inline BOOLEAN nCoeff_is_GF(const coeffs r, int q)
649{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
650
651/* TRUE iff r represents an algebraic or transcendental extension field */
652static inline BOOLEAN nCoeff_is_Extension(const coeffs r)
653{
654  assume(r != NULL);
655  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
656}
657
658/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
659   svn trunk);
660   intension: should be TRUE iff the given r is an extension field above
661   some Z/pZ;
662   actually: TRUE iff the given r is an extension tower of arbitrary
663   height above some field of characteristic p (may be Z/pZ or some
664   Galois field of characteristic p) */
665static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r)
666{
667  assume(r != NULL);
668  return ((r->ringtype == 0) && (r->ch != 0) && nCoeff_is_Extension(r));
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   Z/pZ (with p as provided);
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, int p)
679{
680  assume(r != NULL);
681  return ((r->ringtype == 0) && (r->ch == p) && 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
687   above Q;
688   actually: TRUE iff the given r is an extension tower of arbitrary
689   height above some field of characteristic 0 (may be Q, R, or C) */
690static inline BOOLEAN nCoeff_is_Q_a(const coeffs r)
691{
692  assume(r != NULL);
693  return ((r->ringtype == 0) && (r->ch == 0) && nCoeff_is_Extension(r));
694}
695
696static inline BOOLEAN nCoeff_is_long_R(const coeffs r)
697{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
698
699static inline BOOLEAN nCoeff_is_long_C(const coeffs r)
700{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
701
702static inline BOOLEAN nCoeff_is_CF(const coeffs r)
703{ assume(r != NULL); return getCoeffType(r)==n_CF; }
704
705/// TRUE, if the computation of the inverse is fast,
706/// i.e. prefer leading coeff. 1 over content
707static inline BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
708{ assume(r != NULL); return r->has_simple_Inverse; }
709
710/// TRUE if n_Delete/n_New are empty operations
711static inline BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
712{ assume(r != NULL); return r->has_simple_Alloc; }
713
714/// TRUE iff r represents an algebraic extension field
715static inline BOOLEAN nCoeff_is_algExt(const coeffs r)
716{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
717
718/// TRUE iff r represents a transcendental extension field
719static inline BOOLEAN nCoeff_is_transExt(const coeffs r)
720{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
721
722/// BOOLEAN n_Test(number a, const coeffs r)
723#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
724
725// Missing wrappers for: (TODO: review this?)
726// cfIntMod, cfRead, cfName, cfInit_bigint
727// HAVE_RINGS: cfDivComp, cfExtGcd...
728
729// Deprecated:
730static inline int n_GetChar(const coeffs r)
731{ assume(r != NULL); return nInternalChar(r); }
732
733#endif
734
Note: See TracBrowser for help on using the repository browser.