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

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