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