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

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