source: git/libpolys/coeffs/coeffs.h @ 61b2e16

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