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

spielwiese
Last change on this file since a44bcf was b56249, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Misc fixes due to building on Mac OS X 10.6 fix: no pyobject-building if configured without dynamic loading chg: minor include reordering + forward declarations + cosmetics fix: AM_COND_IF may be undefined in older automake/autoconf fix: distribute ALL tested tests fix: no double definition of NATNUMBER/int_number in structs.h fix: n_ExtGcd is not always related to HAVE_RINGS
  • Property mode set to 100644
File size: 32.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#include <coeffs/Enumerator.h>
17
18#ifdef HAVE_FACTORY
19class CanonicalForm;
20#endif
21
22enum n_coeffType
23{
24  n_unknown=0,
25  n_Zp, /**< \F{p < ?} */
26  n_Q,  /**< rational (GMP) numbers */
27  n_R,  /**< single prescision (6,6) real numbers */
28  n_GF, /**< \GF{p^n < 32001?} */
29  n_long_R, /**< real (GMP) numbers */
30  n_algExt,  /**< used for all algebraic extensions, i.e.,
31                the top-most extension in an extension tower
32                is algebraic */
33  n_transExt,  /**< used for all transcendental extensions, i.e.,
34                  the top-most extension in an extension tower
35                  is transcendental */
36  n_long_C, /**< complex (GMP) numbers */
37  n_Z, /**< only used if HAVE_RINGS is defined: ? */
38  n_Zn, /**< only used if HAVE_RINGS is defined: ? */
39  n_Znm, /**< only used if HAVE_RINGS is defined: ? */
40  n_Z2m, /**< only used if HAVE_RINGS is defined: ? */
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;
57typedef struct ip_sring const *   const_ring;
58
59struct n_Procs_s;
60typedef struct  n_Procs_s  *coeffs;
61typedef struct  n_Procs_s  const * const_coeffs;
62
63typedef number (*numberfunc)(number a, number b, const coeffs r);
64
65/// maps "a", which lives in src, into dst
66typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
67
68
69/// Abstract interface for an enumerator of number coefficients for an
70/// object, e.g. a polynomial
71typedef IEnumerator<number> ICoeffsEnumerator;
72
73/// goes over coeffs given by the ICoeffsEnumerator and changes them.
74/// Additionally returns a number;
75typedef void (*nCoeffsEnumeratorFunc)(ICoeffsEnumerator& numberCollectionEnumerator, number& output, const coeffs r);
76
77
78/// Creation data needed for finite fields
79typedef struct 
80{
81  int GFChar;
82  int GFDegree;
83  const char* GFPar_name;
84} GFInfo;
85
86typedef struct
87{
88  short      float_len; /**< additional char-flags, rInit */
89  short      float_len2; /**< additional char-flags, rInit */
90  const char* par_name; /**< parameter name */
91} LongComplexInfo;
92
93struct n_Procs_s
94{
95   coeffs next;
96   /*unsigned int ringtype;   =0 => coefficient field,
97                             !=0 => coeffs from one of the rings:
98                              =1 => Z/2^mZ
99                              =2 => Z/nZ, n not a prime
100                              =3 => Z/p^mZ
101                              =4 => Z */
102
103   // general properties:
104   /// TRUE, if nNew/nDelete/nCopy are dummies
105   BOOLEAN has_simple_Alloc;
106   /// TRUE, if std should make polynomials monic (if nInvers is cheap)
107   /// if false, then a gcd routine is used for a content computation
108   BOOLEAN has_simple_Inverse;
109
110   // tests for numbers.cc:
111   BOOLEAN (*nCoeffIsEqual)(const coeffs r, n_coeffType n, void * parameter);
112
113   /// output of coeff description via Print
114   void (*cfCoeffWrite)(const coeffs r, BOOLEAN details);
115
116   // ?
117   // initialisation:
118   //void (*cfInitChar)(coeffs r, int parameter); // do one-time initialisations
119   void (*cfKillChar)(coeffs r); //  undo all initialisations
120                                // or NULL
121   void (*cfSetChar)(const coeffs r); // initialisations after each ring change
122                                // or NULL
123   // general stuff
124   numberfunc cfMult, cfSub ,cfAdd ,cfDiv, cfIntDiv, cfIntMod, cfExactDiv;
125   
126   /// init with an integer
127   number  (*cfInit)(long i,const coeffs r);
128
129   /// init with a GMP integer
130   number  (*cfInitMPZ)(mpz_t i, const coeffs r);
131   
132   /// how complicated, (0) => 0, or positive
133   int     (*cfSize)(number n, const coeffs r);
134   
135   /// convertion to int, 0 if impossible
136   int     (*cfInt)(number &n, const coeffs r);
137
138   /// Converts a non-negative number n into a GMP number, 0 if impossible
139   void     (*cfMPZ)(mpz_t result, number &n, const coeffs r);
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
152   /// print a given number (long format)
153   void    (*cfWriteLong)(number &a, const coeffs r);
154   
155   /// print a given number in a shorter way, if possible
156   /// e.g. in K(a): a2 instead of a^2
157   void    (*cfWriteShort)(number &a, const coeffs r);
158   
159   const char *  (*cfRead)(const char * s, number * a, const coeffs r);
160   void    (*cfNormalize)(number &a, const coeffs r);
161   
162#ifdef HAVE_RINGS
163   int     (*cfDivComp)(number a,number b,const coeffs r);
164   BOOLEAN (*cfIsUnit)(number a,const coeffs r);
165   number  (*cfGetUnit)(number a,const coeffs r);
166   BOOLEAN (*cfDivBy)(number a, number b, const coeffs r);
167#endif
168
169   
170   BOOLEAN (*cfGreater)(number a,number b, const coeffs r),
171            /// tests
172           (*cfEqual)(number a,number b, const coeffs r),
173           (*cfIsZero)(number a, const coeffs r),
174           (*cfIsOne)(number a, const coeffs r),
175           (*cfIsMOne)(number a, const coeffs r),
176           (*cfGreaterZero)(number a, const coeffs r);
177
178   void    (*cfPower)(number a, int i, number * result, const coeffs r);
179   number  (*cfGetDenom)(number &n, const coeffs r);
180   number  (*cfGetNumerator)(number &n, const coeffs r);
181   number  (*cfGcd)(number a, number b, const coeffs r);
182   number  (*cfExtGcd)(number a, number b, number *s, number *t,const coeffs r);
183   number  (*cfLcm)(number a, number b, const coeffs r);
184   void    (*cfDelete)(number * a, const coeffs r);
185   nMapFunc (*cfSetMap)(const coeffs src, const coeffs dst);
186
187   /// For extensions (writes into global string buffer)
188   char *  (*cfName)(number n, const coeffs r);
189
190   /// Inplace: a *= b
191   void    (*cfInpMult)(number &a, number b, const coeffs r);
192
193   /// maps the bigint i (from dummy == coeffs_BIGINT!!!) into the
194   /// coeffs dst
195   /// TODO: to be exchanged with a map!!!
196   number  (*cfInit_bigint)(number i, const coeffs dummy, const coeffs dst);
197
198   /// rational reconstruction: best rational with mod p=n
199   number  (*cfFarey)(number p, number n, const coeffs);
200
201   /// chinese remainder
202   /// returns X with X mod q[i]=x[i], i=0..rl-1
203   number  (*cfChineseRemainder)(number *x, number *q,int rl, BOOLEAN sym,const coeffs);
204
205   /// degree for coeffcients: -1 for 0, 0 for "constants", ...
206   int (*cfParDeg)(number x,const coeffs r);
207
208   /// create i^th parameter or NULL if not possible
209   number  (*cfParameter)(const int i, const coeffs r);
210       
211   /// function pointer behind n_ClearContent
212   nCoeffsEnumeratorFunc cfClearContent;
213
214   /// function pointer behind n_ClearDenominators
215   nCoeffsEnumeratorFunc cfClearDenominators;
216
217#ifdef HAVE_FACTORY
218   number (*convFactoryNSingN)( const CanonicalForm n, const coeffs r);
219   CanonicalForm (*convSingNFactoryN)( number n, BOOLEAN setChar, const coeffs r );
220#endif
221
222
223#ifdef LDEBUG
224   /// Test: is "a" a correct number?
225   BOOLEAN (*cfDBTest)(number a, const char *f, const int l, const coeffs r);
226#endif
227
228   /// the 0 as constant, NULL by default
229   number nNULL; 
230   int     char_flag;
231   int     ref;
232   /// how many variables of factort are already used by this coeff
233   int     factoryVarOffset;
234   n_coeffType type;
235
236
237   /// Number of Parameters in the coeffs (default 0)
238   int iNumberOfParameters;
239
240   /// array containing the names of Parameters (default NULL)
241   char const * const * pParameterNames;
242   // NOTE that it replaces the following:
243// char* complex_parameter; //< the name of sqrt(-1) in n_long_C , i.e. 'i' or 'j' etc...?
244// char * m_nfParameter; //< the name of parameter in n_GF
245
246   /////////////////////////////////////////////
247   // the union stuff
248
249   //-------------------------------------------
250
251  /* for extension fields we need to be able to represent polynomials,
252     so here is the polynomial ring: */
253  ring          extRing;
254
255  //number     minpoly;  //< no longer needed: replaced by
256  //                     //< extRing->qideal->[0]
257
258
259//-------------------------------------------
260#ifdef HAVE_RINGS
261  /* The following members are for representing the ring Z/n,
262     where n is not a prime. We distinguish four cases:
263     1.) n has at least two distinct prime factors. Then
264         modBase stores n, modExponent stores 1, modNumber
265         stores n, and mod2mMask is not used;
266     2.) n = p^k for some odd prime p and k > 1. Then
267         modBase stores p, modExponent stores k, modNumber
268         stores n, and mod2mMask is not used;
269     3.) n = 2^k for some k > 1; moreover, 2^k - 1 fits in
270         an unsigned long. Then modBase stores 2, modExponent
271         stores k, modNumber is not used, and mod2mMask stores
272         2^k - 1, i.e., the bit mask '111..1' of length k.
273     4.) n = 2^k for some k > 1; but 2^k - 1 does not fit in
274         an unsigned long. Then modBase stores 2, modExponent
275         stores k, modNumber stores n, and mod2mMask is not
276         used;
277     Cases 1.), 2.), and 4.) are covered by the implementation
278     in the files rmodulon.h and rmodulon.cc, whereas case 3.)
279     is implemented in the files rmodulo2m.h and rmodulo2m.cc. */
280  int_number    modBase;
281  unsigned long modExponent;
282  int_number    modNumber;
283  unsigned long mod2mMask;
284#endif
285  int        ch;  /* characteristic, set by the local *InitChar methods;
286                     In field extensions or extensions towers, the
287                     characteristic can be accessed from any of the
288                     intermediate extension fields, i.e., in this case
289                     it is redundant along the chain of field extensions;
290                     CONTRARY to SINGULAR as it was, we do NO LONGER use
291                     negative values for ch;
292                     for rings, ch will also be set and is - per def -
293                     the smallest number of 1's that sum up to zero;
294                     however, in this case ch may not fit in an int,
295                     thus ch may contain a faulty value */
296
297  short      float_len; /* additional char-flags, rInit */
298  short      float_len2; /* additional char-flags, rInit */
299
300//  BOOLEAN   CanShortOut; //< if the elements can be printed in short format
301//                     // this is set to FALSE if a parameter name has >2 chars
302//  BOOLEAN   ShortOut; //< if the elements should print in short format
303
304// ---------------------------------------------------
305  // for n_GF
306
307  int m_nfCharQ;  ///< the number of elements: q
308  int m_nfM1;       ///< representation of -1
309  int m_nfCharP;  ///< the characteristic: p
310  int m_nfCharQ1; ///< q-1
311  unsigned short *m_nfPlus1Table;
312  int *m_nfMinPoly;
313 
314// ---------------------------------------------------
315// for Zp:
316#ifdef HAVE_DIV_MOD
317  unsigned short *npInvTable;
318#endif
319#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
320  unsigned short *npExpTable;
321  unsigned short *npLogTable;
322#endif
323   //   int npPrimeM; // NOTE: npPrimeM is deprecated, please use ch instead!
324  int npPminus1M; ///< characteristic - 1
325};
326//
327// test properties and type
328/// Returns the type of coeffs domain
329static inline n_coeffType getCoeffType(const coeffs r)
330{
331  assume(r != NULL);
332  return r->type;
333}
334
335/// one-time initialisations for new coeffs
336/// in case of an error return NULL
337coeffs nInitChar(n_coeffType t, void * parameter);
338
339/// undo all initialisations
340void nKillChar(coeffs r);
341
342/// initialisations after each ring change
343static inline void nSetChar(const coeffs r)
344{
345  assume(r!=NULL); // r==NULL is an error
346  assume(r->cfSetChar != NULL);
347  r->cfSetChar(r);
348}
349
350void           nNew(number * a);
351#define n_New(n, r)           nNew(n)
352
353
354/// Return the characteristic of the coeff. domain.
355static inline int n_GetChar(const coeffs r)
356{
357  assume(r != NULL);
358  return r->ch;
359}
360
361
362// the access methods (part 2):
363
364/// return a copy of 'n'
365static inline number n_Copy(number n,    const coeffs r)
366{   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
367
368/// delete 'p'
369static inline void   n_Delete(number* p, const coeffs r)
370{   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
371
372/// TRUE iff 'a' and 'b' represent the same number;
373/// they may have different representations
374static inline BOOLEAN n_Equal(number a, number b, const coeffs r)
375{ assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
376
377/// TRUE iff 'n' represents the zero element
378static inline BOOLEAN n_IsZero(number n, const coeffs r)
379{ assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
380
381/// TRUE iff 'n' represents the one element
382static inline BOOLEAN n_IsOne(number n,  const coeffs r)
383{ assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
384
385/// TRUE iff 'n' represents the additive inverse of the one element, i.e. -1
386static inline BOOLEAN n_IsMOne(number n, const coeffs r)
387{ assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
388
389/// ordered fields: TRUE iff 'n' is positive;
390/// in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2), where m is the long
391///          representing n
392/// in C:    TRUE iff (Im(n) != 0 and Im(n) >= 0) or
393///                   (Im(n) == 0 and Re(n) >= 0)
394/// in K(a)/<p(a)>: TRUE iff (n != 0 and (LC(n) > 0 or deg(n) > 0))
395/// in K(t_1, ..., t_n): TRUE iff (LC(numerator(n) is a constant and > 0)
396///                            or (LC(numerator(n) is not a constant)
397/// in Z/2^kZ: TRUE iff 0 < n <= 2^(k-1)
398/// in Z/mZ: TRUE iff the internal mpz is greater than zero
399/// in Z: TRUE iff n > 0
400///
401/// !!! Recommendation: remove implementations for unordered fields
402/// !!!                 and raise errors instead, in these cases
403/// !!! Do not follow this recommendation: while writing polys,
404/// !!! between 2 monomials will be an additional + iff !n_GreaterZero(next coeff)
405///
406static inline BOOLEAN n_GreaterZero(number n, const coeffs r)
407{
408  assume(r != NULL); assume(r->cfGreaterZero!=NULL);
409  return r->cfGreaterZero(n,r);
410}
411
412/// ordered fields: TRUE iff 'a' is larger than 'b';
413/// in Z/pZ: TRUE iff la > lb, where la and lb are the long's representing
414//                             a and b, respectively
415/// in C:    TRUE iff (Im(a) > Im(b))
416/// in K(a)/<p(a)>: TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b))
417/// in K(t_1, ..., t_n): TRUE only if one or both numerator polynomials are
418///                      zero or if their degrees are equal. In this case,
419///                      TRUE if LC(numerator(a)) > LC(numerator(b))
420/// in Z/2^kZ: TRUE if n_DivBy(a, b)
421/// in Z/mZ: TRUE iff the internal mpz's fulfill the relation '>'
422/// in Z: TRUE iff a > b
423///
424/// !!! Recommendation: remove implementations for unordered fields
425/// !!!                 and raise errors instead, in these cases
426static inline BOOLEAN n_Greater(number a, number b, const coeffs r)
427{ assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
428
429#ifdef HAVE_RINGS
430static inline int n_DivComp(number a, number b, const coeffs r)
431{ assume(r != NULL); assume(r->cfDivComp!=NULL); return r->cfDivComp (a,b,r); }
432
433/// TRUE iff n has a multiplicative inverse in the given coeff field/ring r
434static inline BOOLEAN n_IsUnit(number n, const coeffs r)
435{ assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
436
437/// in Z: 1
438/// in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that
439///                                   is co-prime with k
440/// in Z/2^kZ: largest odd divisor of n (taken in Z)
441/// other cases: not implemented
442static inline number n_GetUnit(number n, const coeffs r)
443{ assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
444#endif
445
446/// a number representing i in the given coeff field/ring r
447static inline number n_Init(long i,       const coeffs r)
448{ assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
449
450/// conversion of a GMP integer to number
451static inline number n_InitMPZ(mpz_t n,     const coeffs r)
452{ assume(r != NULL); assume(r->cfInitMPZ != NULL); return r->cfInitMPZ(n,r); }
453
454/// conversion of n to an int; 0 if not possible
455/// in Z/pZ: the representing int lying in (-p/2 .. p/2]
456static inline int n_Int(number &n,       const coeffs r)
457{ assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
458
459/// conversion of n to a GMP integer; 0 if not possible
460static inline void n_MPZ(mpz_t result, number &n,       const coeffs r)
461{ assume(r != NULL); assume(r->cfMPZ!=NULL); r->cfMPZ(result, n, r); }
462
463
464/// in-place negation of n
465/// MUST BE USED: n = n_Neg(n) (no copy is returned)
466static inline number n_Neg(number n,     const coeffs r)
467{ assume(r != NULL); assume(r->cfNeg!=NULL); return r->cfNeg(n,r); }
468
469/// return the multiplicative inverse of 'a';
470/// raise an error if 'a' is not invertible
471///
472/// !!! Recommendation: rename to 'n_Inverse'
473static inline number n_Invers(number a,  const coeffs r)
474{ assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
475
476/// return a non-negative measure for the complexity of n;
477/// return 0 only when n represents zero;
478/// (used for pivot strategies in matrix computations with entries from r)
479static inline int    n_Size(number n,    const coeffs r)
480{ assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
481
482/// inplace-normalization of n;
483/// produces some canonical representation of n;
484///
485/// !!! Recommendation: remove this method from the user-interface, i.e.,
486/// !!!                 this should be hidden
487static inline void   n_Normalize(number& n, const coeffs r)
488{ assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
489
490/// write to the output buffer of the currently used reporter
491static inline void   n_WriteLong(number& n,  const coeffs r)
492{ assume(r != NULL); assume(r->cfWriteLong!=NULL); r->cfWriteLong(n,r); }
493
494/// write to the output buffer of the currently used reporter
495/// in a shortest possible way, e.g. in K(a): a2 instead of a^2
496static inline void   n_WriteShort(number& n,  const coeffs r)
497{ assume(r != NULL); assume(r->cfWriteShort!=NULL); r->cfWriteShort(n,r); }
498
499static inline void   n_Write(number& n,  const coeffs r, const BOOLEAN bShortOut = TRUE)
500{ if (bShortOut) n_WriteShort(n, r); else n_WriteLong(n, r); }
501
502
503/// @todo: Describe me!!! --> Hans
504///
505/// !!! Recommendation: This method is to cryptic to be part of the user-
506/// !!!                 interface. As defined here, it is merely a helper
507/// !!!                 method for parsing number input strings.
508static inline const char *n_Read(const char * s, number * a, const coeffs r)
509{ assume(r != NULL); assume(r->cfRead!=NULL); return r->cfRead(s, a, r); }
510
511/// return the denominator of n
512/// (if elements of r are by nature not fractional, result is 1)
513static inline number n_GetDenom(number& n, const coeffs r)
514{ assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
515
516/// return the numerator of n
517/// (if elements of r are by nature not fractional, result is n)
518static inline number n_GetNumerator(number& n, const coeffs r)
519{ assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
520
521/// fill res with the power a^b
522static inline void   n_Power(number a, int b, number *res, const coeffs r)
523{ assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
524
525/// return the product of 'a' and 'b', i.e., a*b
526static inline number n_Mult(number a, number b, const coeffs r)
527{ assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
528
529/// multiplication of 'a' and 'b';
530/// replacement of 'a' by the product a*b
531static inline void n_InpMult(number &a, number b, const coeffs r)
532{ assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
533
534/// return the difference of 'a' and 'b', i.e., a-b
535static inline number n_Sub(number a, number b, const coeffs r)
536{ assume(r != NULL); assume(r->cfSub!=NULL); return r->cfSub(a, b, r); }
537
538/// return the sum of 'a' and 'b', i.e., a+b
539static inline number n_Add(number a, number b, const coeffs r)
540{ assume(r != NULL); assume(r->cfAdd!=NULL); return r->cfAdd(a, b, r); }
541
542/// return the quotient of 'a' and 'b', i.e., a/b;
543/// raise an error if 'b' is not invertible in r
544static inline number n_Div(number a, number b, const coeffs r)
545{ assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
546
547/// in Z: largest c such that c*b <= a
548/// in Z/nZ, Z/2^kZ: computed as in the case Z (from integers representing
549///                  'a' and 'b')
550/// in Z/pZ: return a/b
551/// in K(a)/<p(a)>: return a/b
552/// in K(t_1, ..., t_n): return a/b
553/// other fields: not implemented
554static inline number n_IntDiv(number a, number b, const coeffs r)
555{ assume(r != NULL); assume(r->cfIntDiv!=NULL); return r->cfIntDiv(a,b,r); }
556
557static inline number n_IntMod(number a, number b, const coeffs r)
558{ assume(r != NULL); assume(r->cfIntMod!=NULL); return r->cfIntMod(a,b,r); }
559/// @todo: Describe me!!!
560///
561/// What is the purpose of this method, especially in comparison with
562/// n_Div?
563/// !!! Recommendation: remove this method from the user-interface.
564static inline number n_ExactDiv(number a, number b, const coeffs r)
565{ assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
566
567/// in Z: return the gcd of 'a' and 'b'
568/// in Z/nZ, Z/2^kZ: computed as in the case Z
569/// in Z/pZ, C, R: not implemented
570/// in Q: return the gcd of the numerators of 'a' and 'b'
571/// in K(a)/<p(a)>: not implemented
572/// in K(t_1, ..., t_n): not implemented
573static inline number n_Gcd(number a, number b, const coeffs r)
574{ assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
575
576/// beware that ExtGCD is only relevant for a few chosen coeff. domains
577/// and may perform something unexpected in some cases...
578static inline number n_ExtGcd(number a, number b, number *s, number *t, const coeffs r)
579{ assume(r != NULL); assume(r->cfExtGcd!=NULL); return r->cfExtGcd (a,b,s,t,r); }
580
581/// in Z: return the lcm of 'a' and 'b'
582/// in Z/nZ, Z/2^kZ: computed as in the case Z
583/// in Z/pZ, C, R: not implemented
584/// in Q: return the lcm of the numerators of 'a' and the denominator of 'b'
585/// in K(a)/<p(a)>: not implemented
586/// in K(t_1, ..., t_n): not implemented
587static inline number n_Lcm(number a, number b, const coeffs r)
588{ assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
589
590/// set the mapping function pointers for translating numbers from src to dst
591static inline nMapFunc n_SetMap(const coeffs src, const coeffs dst)
592{ assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
593
594/// test whether n is a correct number;
595/// only used if LDEBUG is defined
596#ifdef LDEBUG
597static inline BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
598#else
599static inline BOOLEAN n_DBTest(number, const char*, const int, const coeffs)
600#endif
601{
602  assume(r != NULL); 
603#ifdef LDEBUG
604  assume(r->cfDBTest != NULL); 
605  return r->cfDBTest(n, filename, linenumber, r);
606#else
607  return TRUE;
608#endif
609}
610
611/// output the coeff description
612static inline void   n_CoeffWrite(const coeffs r, BOOLEAN details = TRUE)
613{ assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r, details); }
614
615// Tests:
616static inline BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
617{ assume(r != NULL); return (getCoeffType(r)==n_Z2m); }
618
619static inline BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
620{ assume(r != NULL); return (getCoeffType(r)==n_Zn); }
621
622static inline BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
623{ assume(r != NULL); return (getCoeffType(r)==n_Znm); }
624
625static inline BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
626{ assume(r != NULL); return (getCoeffType(r)==n_Z); }
627
628static inline BOOLEAN nCoeff_is_Ring(const coeffs r)
629{ assume(r != NULL); return ((getCoeffType(r)==n_Z) || (getCoeffType(r)==n_Z2m) || (getCoeffType(r)==n_Zn) || (getCoeffType(r)==n_Znm)); }
630
631/// returns TRUE, if r is not a field and r has no zero divisors (i.e is a domain)
632static inline BOOLEAN nCoeff_is_Domain(const coeffs r)
633{
634  assume(r != NULL); 
635#ifdef HAVE_RINGS
636  return (getCoeffType(r)==n_Z || ((getCoeffType(r)!=n_Z2m) && (getCoeffType(r)!=n_Zn) && (getCoeffType(r)!=n_Znm)));
637#else
638  return TRUE;
639#endif
640}
641
642/// test whether 'a' is divisible 'b';
643/// for r encoding a field: TRUE iff 'b' does not represent zero
644/// in Z: TRUE iff 'b' divides 'a' (with remainder = zero)
645/// in Z/nZ: TRUE iff (a = 0 and b divides n in Z) or
646///                   (a != 0 and b/gcd(a, b) is co-prime with n, i.e.
647///                                              a unit in Z/nZ)
648/// in Z/2^kZ: TRUE iff ((a = 0 mod 2^k) and (b = 0 or b is a power of 2))
649///                  or ((a, b <> 0) and (b/gcd(a, b) is odd))
650static inline BOOLEAN n_DivBy(number a, number b, const coeffs r)
651{
652  assume(r != NULL);
653#ifdef HAVE_RINGS
654  if( nCoeff_is_Ring(r) )
655  {
656    assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r);
657  }
658#endif
659  return !n_IsZero(b, r);
660}
661
662static inline number n_ChineseRemainderSym(number *a, number *b, int rl, BOOLEAN sym,const coeffs r)
663{
664  assume(r != NULL); assume(r->cfChineseRemainder != NULL); return r->cfChineseRemainder(a,b,rl,sym,r);
665}
666
667static inline number n_Farey(number a, number b, const coeffs r)
668{
669  assume(r != NULL); assume(r->cfFarey != NULL); return r->cfFarey(a,b,r);
670}
671
672static inline int n_ParDeg(number n, const coeffs r)
673{ 
674  assume(r != NULL); assume(r->cfParDeg != NULL); return r->cfParDeg(n,r); 
675}
676
677/// Returns the number of parameters
678static inline int n_NumberOfParameters(const coeffs r){ return r->iNumberOfParameters; }
679
680/// Returns a (const!) pointer to (const char*) names of parameters
681static inline char const * const * n_ParameterNames(const coeffs r){ return r->pParameterNames; }
682
683
684/// return the (iParameter^th) parameter as a NEW number
685/// NOTE: parameter numbering: 1..n_NumberOfParameters(...)
686static inline number n_Param(const int iParameter, const coeffs r)
687{
688  assume(r != NULL);
689  assume((iParameter >= 1) || (iParameter <= n_NumberOfParameters(r)));
690  assume(r->cfParameter != NULL);
691  return r->cfParameter(iParameter, r); 
692}
693
694
695static inline number  n_Init_bigint(number i, const coeffs dummy,
696                const coeffs dst)
697{
698  assume(dummy != NULL && dst != NULL); assume(dst->cfInit_bigint!=NULL); 
699  return dst->cfInit_bigint(i, dummy, dst);
700}
701
702static inline number  n_RePart(number i, const coeffs cf)
703{
704  assume(cf != NULL); assume(cf->cfRePart!=NULL); 
705  return cf->cfRePart(i,cf);
706}
707static inline number  n_ImPart(number i, const coeffs cf)
708{
709  assume(cf != NULL); assume(cf->cfImPart!=NULL); 
710  return cf->cfImPart(i,cf);
711}
712
713/// returns TRUE, if r is not a field and r has non-trivial units
714static inline BOOLEAN nCoeff_has_Units(const coeffs r)
715{ assume(r != NULL); return ((getCoeffType(r)==n_Zn) || (getCoeffType(r)==n_Z2m) || (getCoeffType(r)==n_Znm)); }
716
717static inline BOOLEAN nCoeff_is_Zp(const coeffs r)
718{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
719
720static inline BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
721{ assume(r != NULL); return ((getCoeffType(r)==n_Zp) && (r->ch == p)); }
722
723static inline BOOLEAN nCoeff_is_Q(const coeffs r)
724{ assume(r != NULL); return getCoeffType(r)==n_Q; }
725
726static inline BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
727{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
728// (r->ringtype == 0) && (r->ch ==  -1); ??
729
730static inline BOOLEAN nCoeff_is_R(const coeffs r)
731{ assume(r != NULL); return getCoeffType(r)==n_R; }
732
733static inline BOOLEAN nCoeff_is_GF(const coeffs r)
734{ assume(r != NULL); return getCoeffType(r)==n_GF; }
735
736static inline BOOLEAN nCoeff_is_GF(const coeffs r, int q)
737{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
738
739/* TRUE iff r represents an algebraic or transcendental extension field */
740static inline BOOLEAN nCoeff_is_Extension(const coeffs r)
741{
742  assume(r != NULL);
743  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
744}
745
746/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
747   svn trunk);
748   intension: should be TRUE iff the given r is an extension field above
749   some Z/pZ;
750   actually: TRUE iff the given r is an extension tower of arbitrary
751   height above some field of characteristic p (may be Z/pZ or some
752   Galois field of characteristic p) */
753static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r)
754{
755  assume(r != NULL);
756  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) != 0) && nCoeff_is_Extension(r));
757}
758
759/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
760   svn trunk);
761   intension: should be TRUE iff the given r is an extension field above
762   Z/pZ (with p as provided);
763   actually: TRUE iff the given r is an extension tower of arbitrary
764   height above some field of characteristic p (may be Z/pZ or some
765   Galois field of characteristic p) */
766static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r, int p)
767{
768  assume(r != NULL);
769  assume(p != 0);
770  return ((!nCoeff_is_Ring(r)) && (n_GetChar(r) == p) && nCoeff_is_Extension(r));
771}
772
773/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
774   svn trunk);
775   intension: should be TRUE iff the given r is an extension field
776   above Q;
777   actually: TRUE iff the given r is an extension tower of arbitrary
778   height above some field of characteristic 0 (may be Q, R, or C) */
779static inline BOOLEAN nCoeff_is_Q_a(const coeffs r)
780{
781  assume(r != NULL);
782  return ((n_GetChar(r) == 0) && nCoeff_is_Extension(r));
783}
784
785
786
787
788static inline BOOLEAN nCoeff_is_long_R(const coeffs r)
789{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
790
791static inline BOOLEAN nCoeff_is_long_C(const coeffs r)
792{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
793
794static inline BOOLEAN nCoeff_is_CF(const coeffs r)
795{ assume(r != NULL); return getCoeffType(r)==n_CF; }
796
797/// TRUE, if the computation of the inverse is fast,
798/// i.e. prefer leading coeff. 1 over content
799static inline BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
800{ assume(r != NULL); return r->has_simple_Inverse; }
801
802/// TRUE if n_Delete/n_New are empty operations
803static inline BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
804{ assume(r != NULL); return r->has_simple_Alloc; }
805
806/// TRUE iff r represents an algebraic extension field
807static inline BOOLEAN nCoeff_is_algExt(const coeffs r)
808{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
809
810/// is it an alg. ext. of Q?
811static inline BOOLEAN nCoeff_is_Q_algext(const coeffs r)
812{ assume(r != NULL); return ((n_GetChar(r) == 0) && nCoeff_is_algExt(r)); }
813
814/// TRUE iff r represents a transcendental extension field
815static inline BOOLEAN nCoeff_is_transExt(const coeffs r)
816{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
817
818/// BOOLEAN n_Test(number a, const coeffs r)
819#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
820
821// Missing wrappers for: (TODO: review this?)
822// cfIntMod, cfRead, cfName, cfInit_bigint
823
824// HAVE_RINGS: cfDivComp, cfIsUnit, cfGetUnit, cfDivBy
825// BUT NOT cfExtGcd...!
826
827
828/// Computes the content and (inplace) divides it out on a collection
829/// of numbers
830/// number @em c is the content (i.e. the GCD of all the coeffs, which
831/// we divide out inplace)
832/// NOTE: it assumes all coefficient numbers to be integer!!!
833/// NOTE/TODO: see also the description by Hans
834/// TODO: rename into n_ClearIntegerContent
835static inline void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs r)
836{
837  assume(r != NULL);
838  r->cfClearContent(numberCollectionEnumerator, c, r);
839}
840
841/// (inplace) Clears denominators on a collection of numbers
842/// number @em d is the LCM of all the coefficient denominators (i.e. the number
843/// with which all the number coeffs. were multiplied)
844/// NOTE/TODO: see also the description by Hans
845static inline void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& d, const coeffs r)
846{
847  assume(r != NULL);
848  r->cfClearDenominators(numberCollectionEnumerator, d, r);
849}
850
851// convenience helpers (no number returned - but the input enumeration
852// is to be changed
853// TODO: do we need separate hooks for these as our existing code does
854// *different things* there: compare p_Cleardenom (which calls
855// *p_Content) and p_Cleardenom_n (which doesn't)!!!
856
857static inline void n_ClearContent(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
858{
859  number c;
860  n_ClearContent(numberCollectionEnumerator, c, r);
861  n_Delete(&c, r);
862}
863
864static inline void n_ClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, const coeffs r)
865{
866  assume(r != NULL);
867  number d;
868  n_ClearDenominators(numberCollectionEnumerator, d, r);
869  n_Delete(&d, r);
870}
871
872/// print a number (BEWARE of string buffers!)
873/// mostly for debugging
874void   n_Print(number& a,  const coeffs r);
875
876#endif
877
Note: See TracBrowser for help on using the repository browser.