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

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