source: git/libpolys/coeffs/coeffs.h @ 7fee876

spielwiese
Last change on this file since 7fee876 was 7fee876, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
moved prarameter-handling to coeffs from rings.* and related fixes chg: removed complex_parameter, m_nfParameter add: n_NumberOfParameters, n_ParameterNames, n_Param(coeffs) fix: par(1) (n_Param) for n_GF & n_long_C fix/chg: n_long_C is an Extension as well (rIsExtension) fix: n_long_C ngcCoeffWrite: additional space needed for compatibility with legacy Singular fix: complexToStr over non-C coeffs! fix: rRenameVars renames _new_ VARIABLES instead of _old_ parameters! fix: coeff construction was broken in walk.cc add/fix: nfKillChar, ngcKillChar chg: cleanup of headers & tests chg: parameter output during "make check"
  • Property mode set to 100644
File size: 29.0 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,
24  n_Q,
25  n_R,
26  n_GF,
27  n_long_R,
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,
35  // only used if HAVE_RINGS is defined:
36  n_Z,
37  n_Zn,
38  n_Zpn, // does no longer exist?
39  n_Z2m,
40  n_CF
41};
42
43extern unsigned short fftable[];
44
45struct snumber;
46typedef struct snumber *   number;
47
48/* standard types */
49#ifdef HAVE_RINGS
50typedef unsigned long NATNUMBER;
51typedef mpz_ptr int_number;
52#endif
53
54struct ip_sring;
55typedef struct ip_sring *         ring;
56typedef struct ip_sring const *   const_ring;
57
58struct n_Procs_s;
59typedef struct  n_Procs_s  *coeffs;
60typedef struct  n_Procs_s  const * const_coeffs;
61
62typedef number (*numberfunc)(number a, number b, const coeffs r);
63
64/// maps "a", which lives in src, into dst
65typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
66
67/// Creation data needed for finite fields
68typedef struct 
69{
70  int GFChar;
71  int GFDegree;
72  const char* GFPar_name;
73} GFInfo;
74
75typedef struct
76{
77  short      float_len; /**< additional char-flags, rInit */
78  short      float_len2; /**< additional char-flags, rInit */
79  const char* par_name; /**< parameter name */
80} LongComplexInfo;
81
82struct n_Procs_s
83{
84   coeffs next;
85   unsigned int ringtype;  /* =0 => coefficient field,
86                             !=0 => coeffs from one of the rings:
87                              =1 => Z/2^mZ
88                              =2 => Z/nZ, n not a prime
89                              =3 => Z/p^mZ
90                              =4 => Z */
91
92   // general properties:
93   /// TRUE, if nNew/nDelete/nCopy are dummies
94   BOOLEAN has_simple_Alloc;
95   /// TRUE, if std should make polynomials monic (if nInvers is cheap)
96   /// if false, then a gcd routine is used for a content computation
97   BOOLEAN has_simple_Inverse;
98
99   // tests for numbers.cc:
100   BOOLEAN (*nCoeffIsEqual)(const coeffs r, n_coeffType n, void * parameter);
101
102   /// output of coeff description via Print
103   void (*cfCoeffWrite)(const coeffs r, BOOLEAN details);
104
105   // ?
106   // initialisation:
107   //void (*cfInitChar)(coeffs r, int parameter); // do one-time initialisations
108   void (*cfKillChar)(coeffs r); //  undo all initialisations
109                                // or NULL
110   void (*cfSetChar)(const coeffs r); // initialisations after each ring change
111                                // or NULL
112   // general stuff
113   numberfunc cfMult, cfSub ,cfAdd ,cfDiv, cfIntDiv, cfIntMod, cfExactDiv;
114   
115   /// init with an integer
116   number  (*cfInit)(long i,const coeffs r);
117
118   /// init with a GMP integer
119   number  (*cfInitMPZ)(mpz_t i, const coeffs r);
120   
121   /// how complicated, (0) => 0, or positive
122   int     (*cfSize)(number n, const coeffs r);
123   
124   /// convertion to int, 0 if impossible
125   int     (*cfInt)(number &n, const coeffs r);
126
127   /// Converts a non-negative number n into a GMP number, 0 if impossible
128   void     (*cfMPZ)(mpz_t result, number &n, const coeffs r);
129   
130#ifdef HAVE_RINGS
131   int     (*cfDivComp)(number a,number b,const coeffs r);
132   BOOLEAN (*cfIsUnit)(number a,const coeffs r);
133   number  (*cfGetUnit)(number a,const coeffs r);
134   number  (*cfExtGcd)(number a, number b, number *s, number *t,const coeffs r);
135#endif
136
137   /// changes argument  inline: a:= -a
138   /// return -a! (no copy is returned)
139   /// the result should be assigned to the original argument: e.g. a = n_Neg(a,r)
140   number  (*cfNeg)(number a, const coeffs r);
141   /// return 1/a
142   number  (*cfInvers)(number a, const coeffs r);
143   /// return a copy of a
144   number  (*cfCopy)(number a, const coeffs r);
145   number  (*cfRePart)(number a, const coeffs r);
146   number  (*cfImPart)(number a, const coeffs r);
147
148   /// print a given number (long format)
149   void    (*cfWriteLong)(number &a, const coeffs r);
150   
151   /// print a given number in a shorter way, if possible
152   /// e.g. in K(a): a2 instead of a^2
153   void    (*cfWriteShort)(number &a, const coeffs r);
154   
155   const char *  (*cfRead)(const char * s, number * a, const coeffs r);
156   void    (*cfNormalize)(number &a, const coeffs r);
157   BOOLEAN (*cfGreater)(number a,number b, const coeffs r),
158#ifdef HAVE_RINGS
159           (*cfDivBy)(number a, number b, const coeffs r),
160#endif
161            /// tests
162           (*cfEqual)(number a,number b, const coeffs r),
163           (*cfIsZero)(number a, const coeffs r),
164           (*cfIsOne)(number a, const coeffs r),
165           (*cfIsMOne)(number a, const coeffs r),
166           (*cfGreaterZero)(number a, const coeffs r);
167
168   void    (*cfPower)(number a, int i, number * result, const coeffs r);
169   number  (*cfGetDenom)(number &n, const coeffs r);
170   number  (*cfGetNumerator)(number &n, const coeffs r);
171   number  (*cfGcd)(number a, number b, const coeffs r);
172   number  (*cfLcm)(number a, number b, const coeffs r);
173   void    (*cfDelete)(number * a, const coeffs r);
174   nMapFunc (*cfSetMap)(const coeffs src, const coeffs dst);
175
176   /// For extensions (writes into global string buffer)
177   char *  (*cfName)(number n, const coeffs r);
178
179   /// Inplace: a *= b
180   void    (*cfInpMult)(number &a, number b, const coeffs r);
181
182   /// maps the bigint i (from dummy == coeffs_BIGINT!!!) into the
183   /// coeffs dst
184   /// TODO: to be exchanged with a map!!!
185   number  (*cfInit_bigint)(number i, const coeffs dummy, const coeffs dst);
186
187   /// rational reconstruction: best rational with mod p=n
188   number  (*cfFarey)(number p, number n, const coeffs);
189
190   /// chinese remainder
191   /// returns X with X mod q[i]=x[i], i=0..rl-1
192   number  (*cfChineseRemainder)(number *x, number *q,int rl, const coeffs);
193
194   /// degree for coeffcients: -1 for 0, 0 for "constants", ...
195   int (*cfParDeg)(number x,const coeffs r);
196
197   /// create i^th parameter or NULL if not possible
198   number  (*cfParameter)(const int i, const coeffs r);
199
200#ifdef HAVE_FACTORY
201   number (*convFactoryNSingN)( const CanonicalForm n, const coeffs r);
202   CanonicalForm (*convSingNFactoryN)( number n, BOOLEAN setChar, const coeffs r );
203#endif
204
205
206#ifdef LDEBUG
207   /// Test: is "a" a correct number?
208   BOOLEAN (*cfDBTest)(number a, const char *f, const int l, const coeffs r);
209#endif
210
211   number nNULL; /* the 0 as constant */
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->minideal->[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// the access methods (part 2):
337
338/// return a copy of 'n'
339static inline number n_Copy(number n,    const coeffs r)
340{   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
341
342/// delete 'p'
343static inline void   n_Delete(number* p, const coeffs r)
344{   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
345
346/// TRUE iff 'a' and 'b' represent the same number;
347/// they may have different representations
348static inline BOOLEAN n_Equal(number a, number b, const coeffs r)
349{ assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
350
351/// TRUE iff 'n' represents the zero element
352static inline BOOLEAN n_IsZero(number n, const coeffs r)
353{ assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
354
355/// TRUE iff 'n' represents the one element
356static inline BOOLEAN n_IsOne(number n,  const coeffs r)
357{ assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
358
359/// TRUE iff 'n' represents the additive inverse of the one element, i.e. -1
360static inline BOOLEAN n_IsMOne(number n, const coeffs r)
361{ assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
362
363/// ordered fields: TRUE iff 'n' is positive;
364/// in Z/pZ: TRUE iff 0 < m <= roundedBelow(p/2), where m is the long
365///          representing n
366/// in C:    TRUE iff (Im(n) != 0 and Im(n) >= 0) or
367///                   (Im(n) == 0 and Re(n) >= 0)
368/// in K(a)/<p(a)>: TRUE iff (n != 0 and (LC(n) > 0 or deg(n) > 0))
369/// in K(t_1, ..., t_n): TRUE iff (LC(numerator(n) is a constant and > 0)
370///                            or (LC(numerator(n) is not a constant)
371/// in Z/2^kZ: TRUE iff 0 < n <= 2^(k-1)
372/// in Z/mZ: TRUE iff the internal mpz is greater than zero
373/// in Z: TRUE iff n > 0
374///
375/// !!! Recommendation: remove implementations for unordered fields
376/// !!!                 and raise errors instead, in these cases
377/// !!! Do not follow this recommendation: while writing polys,
378/// !!! between 2 monomials will be an additional + iff !n_GreaterZero(next coeff)
379///
380static inline BOOLEAN n_GreaterZero(number n, const coeffs r)
381{
382  assume(r != NULL); assume(r->cfGreaterZero!=NULL);
383  return r->cfGreaterZero(n,r);
384}
385
386/// ordered fields: TRUE iff 'a' is larger than 'b';
387/// in Z/pZ: TRUE iff la > lb, where la and lb are the long's representing
388//                             a and b, respectively
389/// in C:    TRUE iff (Im(a) > Im(b))
390/// in K(a)/<p(a)>: TRUE iff (a != 0 and (b == 0 or deg(a) > deg(b))
391/// in K(t_1, ..., t_n): TRUE only if one or both numerator polynomials are
392///                      zero or if their degrees are equal. In this case,
393///                      TRUE if LC(numerator(a)) > LC(numerator(b))
394/// in Z/2^kZ: TRUE if n_DivBy(a, b)
395/// in Z/mZ: TRUE iff the internal mpz's fulfill the relation '>'
396/// in Z: TRUE iff a > b
397///
398/// !!! Recommendation: remove implementations for unordered fields
399/// !!!                 and raise errors instead, in these cases
400static inline BOOLEAN n_Greater(number a, number b, const coeffs r)
401{ assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
402
403#ifdef HAVE_RINGS
404/// TRUE iff n has a multiplicative inverse in the given coeff field/ring r
405static inline BOOLEAN n_IsUnit(number n, const coeffs r)
406{ assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
407
408static inline number n_ExtGcd(number a, number b, number *s, number *t, const coeffs r)
409{ assume(r != NULL); assume(r->cfExtGcd!=NULL); return r->cfExtGcd (a,b,s,t,r); }
410
411static inline int n_DivComp(number a, number b, const coeffs r)
412{ assume(r != NULL); assume(r->cfDivComp!=NULL); return r->cfDivComp (a,b,r); }
413
414/// in Z: 1
415/// in Z/kZ (where k is not a prime): largest divisor of n (taken in Z) that
416///                                   is co-prime with k
417/// in Z/2^kZ: largest odd divisor of n (taken in Z)
418/// other cases: not implemented
419static inline number n_GetUnit(number n, const coeffs r)
420{ assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
421#endif
422
423/// a number representing i in the given coeff field/ring r
424static inline number n_Init(long i,       const coeffs r)
425{ assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
426
427/// conversion of a GMP integer to number
428static inline number n_InitMPZ(mpz_t n,     const coeffs r)
429{ assume(r != NULL); assume(r->cfInitMPZ != NULL); return r->cfInitMPZ(n,r); }
430
431/// conversion of n to an int; 0 if not possible
432/// in Z/pZ: the representing int lying in (-p/2 .. p/2]
433static inline int n_Int(number &n,       const coeffs r)
434{ assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
435
436/// conversion of n to a GMP integer; 0 if not possible
437static inline void n_MPZ(mpz_t result, number &n,       const coeffs r)
438{ assume(r != NULL); assume(r->cfMPZ!=NULL); r->cfMPZ(result, n, r); }
439
440
441/// in-place negation of n
442/// MUST BE USED: n = n_Neg(n) (no copy is returned)
443static inline number n_Neg(number n,     const coeffs r)
444{ assume(r != NULL); assume(r->cfNeg!=NULL); return r->cfNeg(n,r); }
445
446/// return the multiplicative inverse of 'a';
447/// raise an error if 'a' is not invertible
448///
449/// !!! Recommendation: rename to 'n_Inverse'
450static inline number n_Invers(number a,  const coeffs r)
451{ assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
452
453/// return a non-negative measure for the complexity of n;
454/// return 0 only when n represents zero;
455/// (used for pivot strategies in matrix computations with entries from r)
456static inline int    n_Size(number n,    const coeffs r)
457{ assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
458
459/// inplace-normalization of n;
460/// produces some canonical representation of n;
461///
462/// !!! Recommendation: remove this method from the user-interface, i.e.,
463/// !!!                 this should be hidden
464static inline void   n_Normalize(number& n, const coeffs r)
465{ assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
466
467/// write to the output buffer of the currently used reporter
468static inline void   n_WriteLong(number& n,  const coeffs r)
469{ assume(r != NULL); assume(r->cfWriteLong!=NULL); r->cfWriteLong(n,r); }
470
471/// write to the output buffer of the currently used reporter
472/// in a shortest possible way, e.g. in K(a): a2 instead of a^2
473static inline void   n_WriteShort(number& n,  const coeffs r)
474{ assume(r != NULL); assume(r->cfWriteShort!=NULL); r->cfWriteShort(n,r); }
475
476static inline void   n_Write(number& n,  const coeffs r, const BOOLEAN bShortOut = TRUE)
477{ if (bShortOut) n_WriteShort(n, r); else n_WriteLong(n, r); }
478
479
480/// @todo: Describe me!!! --> Hans
481///
482/// !!! Recommendation: This method is to cryptic to be part of the user-
483/// !!!                 interface. As defined here, it is merely a helper
484/// !!!                 method for parsing number input strings.
485static inline const char *n_Read(const char * s, number * a, const coeffs r)
486{ assume(r != NULL); assume(r->cfRead!=NULL); return r->cfRead(s, a, r); }
487
488/// return the denominator of n
489/// (if elements of r are by nature not fractional, result is 1)
490static inline number n_GetDenom(number& n, const coeffs r)
491{ assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
492
493/// return the numerator of n
494/// (if elements of r are by nature not fractional, result is n)
495static inline number n_GetNumerator(number& n, const coeffs r)
496{ assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
497
498/// fill res with the power a^b
499static inline void   n_Power(number a, int b, number *res, const coeffs r)
500{ assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
501
502/// return the product of 'a' and 'b', i.e., a*b
503static inline number n_Mult(number a, number b, const coeffs r)
504{ assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
505
506/// multiplication of 'a' and 'b';
507/// replacement of 'a' by the product a*b
508static inline void n_InpMult(number &a, number b, const coeffs r)
509{ assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
510
511/// return the difference of 'a' and 'b', i.e., a-b
512static inline number n_Sub(number a, number b, const coeffs r)
513{ assume(r != NULL); assume(r->cfSub!=NULL); return r->cfSub(a, b, r); }
514
515/// return the sum of 'a' and 'b', i.e., a+b
516static inline number n_Add(number a, number b, const coeffs r)
517{ assume(r != NULL); assume(r->cfAdd!=NULL); return r->cfAdd(a, b, r); }
518
519/// return the quotient of 'a' and 'b', i.e., a/b;
520/// raise an error if 'b' is not invertible in r
521static inline number n_Div(number a, number b, const coeffs r)
522{ assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
523
524/// in Z: largest c such that c*b <= a
525/// in Z/nZ, Z/2^kZ: computed as in the case Z (from integers representing
526///                  'a' and 'b')
527/// in Z/pZ: return a/b
528/// in K(a)/<p(a)>: return a/b
529/// in K(t_1, ..., t_n): return a/b
530/// other fields: not implemented
531static inline number n_IntDiv(number a, number b, const coeffs r)
532{ assume(r != NULL); assume(r->cfIntDiv!=NULL); return r->cfIntDiv(a,b,r); }
533
534static inline number n_IntMod(number a, number b, const coeffs r)
535{ assume(r != NULL); assume(r->cfIntMod!=NULL); return r->cfIntMod(a,b,r); }
536/// @todo: Describe me!!!
537///
538/// What is the purpose of this method, especially in comparison with
539/// n_Div?
540/// !!! Recommendation: remove this method from the user-interface.
541static inline number n_ExactDiv(number a, number b, const coeffs r)
542{ assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
543
544/// in Z: return the gcd of 'a' and 'b'
545/// in Z/nZ, Z/2^kZ: computed as in the case Z
546/// in Z/pZ, C, R: not implemented
547/// in Q: return the gcd of the numerators of 'a' and 'b'
548/// in K(a)/<p(a)>: not implemented
549/// in K(t_1, ..., t_n): not implemented
550static inline number n_Gcd(number a, number b, const coeffs r)
551{ assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
552
553/// in Z: return the lcm of 'a' and 'b'
554/// in Z/nZ, Z/2^kZ: computed as in the case Z
555/// in Z/pZ, C, R: not implemented
556/// in Q: return the lcm of the numerators of 'a' and the denominator of 'b'
557/// in K(a)/<p(a)>: not implemented
558/// in K(t_1, ..., t_n): not implemented
559static inline number n_Lcm(number a, number b, const coeffs r)
560{ assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
561
562/// set the mapping function pointers for translating numbers from src to dst
563static inline nMapFunc n_SetMap(const coeffs src, const coeffs dst)
564{ assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
565
566/// test whether n is a correct number;
567/// only used if LDEBUG is defined
568static inline BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
569{
570  assume(r != NULL); 
571#ifdef LDEBUG
572  assume(r->cfDBTest != NULL); 
573  return r->cfDBTest(n, filename, linenumber, r);
574#else
575  return TRUE;
576#endif
577}
578
579/// output the coeff description
580static inline void   n_CoeffWrite(const coeffs r, BOOLEAN details = TRUE)
581{ assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r, details); }
582
583// Tests:
584static inline BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
585{ assume(r != NULL); return (r->ringtype == 1); }
586
587static inline BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
588{ assume(r != NULL); return (r->ringtype == 2); }
589
590static inline BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
591{ assume(r != NULL); return (r->ringtype == 3); }
592
593static inline BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
594{ assume(r != NULL); return (r->ringtype == 4); }
595
596static inline BOOLEAN nCoeff_is_Ring(const coeffs r)
597{ assume(r != NULL); return (r->ringtype != 0); }
598
599/// returns TRUE, if r is not a field and r has no zero divisors (i.e is a domain)
600static inline BOOLEAN nCoeff_is_Domain(const coeffs r)
601{
602  assume(r != NULL); 
603#ifdef HAVE_RINGS
604  return (r->ringtype == 4 || r->ringtype == 0);
605#else
606  return TRUE;
607#endif
608}
609
610/// test whether 'a' is divisible 'b';
611/// for r encoding a field: TRUE iff 'b' does not represent zero
612/// in Z: TRUE iff 'b' divides 'a' (with remainder = zero)
613/// in Z/nZ: TRUE iff (a = 0 and b divides n in Z) or
614///                   (a != 0 and b/gcd(a, b) is co-prime with n, i.e.
615///                                              a unit in Z/nZ)
616/// in Z/2^kZ: TRUE iff ((a = 0 mod 2^k) and (b = 0 or b is a power of 2))
617///                  or ((a, b <> 0) and (b/gcd(a, b) is odd))
618static inline BOOLEAN n_DivBy(number a, number b, const coeffs r)
619{
620  assume(r != NULL);
621#ifdef HAVE_RINGS
622  if( nCoeff_is_Ring(r) )
623  {
624    assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r);
625  }
626#endif
627  return !n_IsZero(b, r);
628}
629
630static inline number n_ChineseRemainder(number *a, number *b, int rl, const coeffs r)
631{
632  assume(r != NULL);
633  return r->cfChineseRemainder(a,b,rl,r);
634}
635
636static inline number n_Farey(number a, number b, const coeffs r)
637{
638  assume(r != NULL);
639  return r->cfFarey(a,b,r);
640}
641
642static inline int n_ParDeg(number n, const coeffs r)
643{ 
644  assume(r != NULL);
645  return r->cfParDeg(n,r); 
646}
647
648/// Returns the number of parameters
649static inline int n_NumberOfParameters(const coeffs r){ return r->iNumberOfParameters; }
650
651/// Returns a (const!) pointer to (const char*) names of parameters
652static inline char const * const * n_ParameterNames(const coeffs r){ return r->pParameterNames; }
653
654
655/// return the (iParameter^th) parameter as a NEW number
656/// NOTE: parameter numbering: 1..n_NumberOfParameters(...)
657static inline number n_Param(const int iParameter, const coeffs r)
658{
659  assume(r != NULL);
660  assume((iParameter >= 1) || (iParameter <= n_NumberOfParameters(r)));
661  assume(r->cfParameter != NULL);
662  return r->cfParameter(iParameter, r); 
663}
664
665
666static inline number  n_Init_bigint(number i, const coeffs dummy,
667                const coeffs dst)
668{
669  assume(dummy != NULL && dst != NULL); assume(dst->cfInit_bigint!=NULL); 
670  return dst->cfInit_bigint(i, dummy, dst);
671}
672
673static inline number  n_RePart(number i, const coeffs cf)
674{
675  assume(cf != NULL); assume(cf->cfRePart!=NULL); 
676  return cf->cfRePart(i,cf);
677}
678static inline number  n_ImPart(number i, const coeffs cf)
679{
680  assume(cf != NULL); assume(cf->cfImPart!=NULL); 
681  return cf->cfImPart(i,cf);
682}
683
684/// returns TRUE, if r is not a field and r has non-trivial units
685static inline BOOLEAN nCoeff_has_Units(const coeffs r)
686{ assume(r != NULL); return ((r->ringtype == 1) || (r->ringtype == 2) || (r->ringtype == 3)); }
687
688static inline BOOLEAN nCoeff_is_Zp(const coeffs r)
689{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
690
691static inline BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
692{ assume(r != NULL); return (getCoeffType(r)  && (r->ch == p)); }
693
694static inline BOOLEAN nCoeff_is_Q(const coeffs r)
695{ assume(r != NULL); return getCoeffType(r)==n_Q; }
696
697static inline BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
698{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
699// (r->ringtype == 0) && (r->ch ==  -1); ??
700
701static inline BOOLEAN nCoeff_is_R(const coeffs r)
702{ assume(r != NULL); return getCoeffType(r)==n_R; }
703
704static inline BOOLEAN nCoeff_is_GF(const coeffs r)
705{ assume(r != NULL); return getCoeffType(r)==n_GF; }
706
707static inline BOOLEAN nCoeff_is_GF(const coeffs r, int q)
708{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
709
710/* TRUE iff r represents an algebraic or transcendental extension field */
711static inline BOOLEAN nCoeff_is_Extension(const coeffs r)
712{
713  assume(r != NULL);
714  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
715}
716
717/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
718   svn trunk);
719   intension: should be TRUE iff the given r is an extension field above
720   some Z/pZ;
721   actually: TRUE iff the given r is an extension tower of arbitrary
722   height above some field of characteristic p (may be Z/pZ or some
723   Galois field of characteristic p) */
724static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r)
725{
726  assume(r != NULL);
727  return ((r->ringtype == 0) && (r->ch != 0) && nCoeff_is_Extension(r));
728}
729
730/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
731   svn trunk);
732   intension: should be TRUE iff the given r is an extension field above
733   Z/pZ (with p as provided);
734   actually: TRUE iff the given r is an extension tower of arbitrary
735   height above some field of characteristic p (may be Z/pZ or some
736   Galois field of characteristic p) */
737static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r, int p)
738{
739  assume(r != NULL);
740  return ((r->ringtype == 0) && (r->ch == p) && nCoeff_is_Extension(r));
741}
742
743/* DO NOT USE (only kept for compatibility reasons towards the SINGULAR
744   svn trunk);
745   intension: should be TRUE iff the given r is an extension field
746   above Q;
747   actually: TRUE iff the given r is an extension tower of arbitrary
748   height above some field of characteristic 0 (may be Q, R, or C) */
749static inline BOOLEAN nCoeff_is_Q_a(const coeffs r)
750{
751  assume(r != NULL);
752  return ((r->ringtype == 0) && (r->ch == 0) && nCoeff_is_Extension(r));
753}
754
755static inline BOOLEAN nCoeff_is_long_R(const coeffs r)
756{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
757
758static inline BOOLEAN nCoeff_is_long_C(const coeffs r)
759{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
760
761static inline BOOLEAN nCoeff_is_CF(const coeffs r)
762{ assume(r != NULL); return getCoeffType(r)==n_CF; }
763
764/// TRUE, if the computation of the inverse is fast,
765/// i.e. prefer leading coeff. 1 over content
766static inline BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
767{ assume(r != NULL); return r->has_simple_Inverse; }
768
769/// TRUE if n_Delete/n_New are empty operations
770static inline BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
771{ assume(r != NULL); return r->has_simple_Alloc; }
772
773/// TRUE iff r represents an algebraic extension field
774static inline BOOLEAN nCoeff_is_algExt(const coeffs r)
775{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
776
777/// TRUE iff r represents a transcendental extension field
778static inline BOOLEAN nCoeff_is_transExt(const coeffs r)
779{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
780
781/// BOOLEAN n_Test(number a, const coeffs r)
782#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
783
784// Missing wrappers for: (TODO: review this?)
785// cfIntMod, cfRead, cfName, cfInit_bigint
786// HAVE_RINGS: cfDivComp, cfExtGcd...
787
788/// Return the characteristic of the coeff. domain.
789static inline int n_GetChar(const coeffs r)
790{
791  assume(r != NULL);
792  return r->ch;
793}
794
795#endif
796
Note: See TracBrowser for help on using the repository browser.