source: git/libpolys/coeffs/coeffs.h @ 644f81

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