source: git/libpolys/coeffs/coeffs.h @ 95eb6d

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