source: git/libpolys/coeffs/coeffs.h @ 2f3764

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