source: git/libpolys/coeffs/coeffs.h @ 9b3700

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