source: git/libpolys/coeffs/coeffs.h @ 8a5c49

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