source: git/libpolys/coeffs/coeffs.h @ 73a9ffb

spielwiese
Last change on this file since 73a9ffb was 73a9ffb, checked in by Frank Seelisch <seelisch@…>, 13 years ago
made sure that ch is properly set everywhere, and ch >= 0; more ASSUMEs
  • Property mode set to 100644
File size: 19.2 KB
Line 
1#ifndef COEFFS_H
2#define COEFFS_H
3/****************************************
4*  Computer Algebra System SINGULAR     *
5****************************************/
6/* $Id$ */
7/*
8* ABSTRACT
9*/
10
11#include <misc/auxiliary.h>
12/* for assume: */
13#include <reporter/reporter.h>
14
15#include <coeffs/si_gmp.h>
16
17#ifdef HAVE_FACTORY
18class CanonicalForm;
19#endif
20
21enum n_coeffType
22{
23  n_unknown=0,
24  n_Zp,
25  n_Q,
26  n_R,
27  n_GF,
28  n_long_R,
29  n_algExt,  /**< used for all algebraic extensions, i.e.,
30                the top-most extension in an extension tower
31                is algebraic */
32  n_transExt,  /**< used for all transcendental extensions, i.e.,
33                  the top-most extension in an extension tower
34                  is transcendental */
35  n_long_C,
36  // only used if HAVE_RINGS is defined:
37  n_Z,
38  n_Zn,
39  n_Zpn, // does no longer exist?
40  n_Z2m,
41  n_CF
42};
43
44struct snumber;
45typedef struct snumber *   number;
46
47struct snumber;
48typedef struct snumber *   number;
49
50/* standard types */
51#ifdef HAVE_RINGS
52typedef unsigned long NATNUMBER;
53typedef mpz_ptr int_number;
54#endif
55
56struct ip_sring;
57typedef struct ip_sring *         ring;
58
59struct n_Procs_s;
60typedef struct  n_Procs_s  n_Procs_s;
61typedef struct  n_Procs_s  *coeffs;
62
63typedef number (*numberfunc)(number a, number b, const coeffs r);
64
65/// maps "a", which lives in src, into dst
66typedef number (*nMapFunc)(number a, const coeffs src, const coeffs dst);
67
68struct n_Procs_s
69{
70   coeffs next;
71   unsigned int ringtype;  /* =0 => coefficient field,
72                             !=0 => coeffs from one of the rings:
73                              =1 => Z/2^mZ
74                              =2 => Z/nZ, n not a prime
75                              =3 => Z/p^mZ
76                              =4 => Z */
77
78   // general properties:
79   /// TRUE, if nNew/nDelete/nCopy are dummies
80   BOOLEAN has_simple_Alloc;
81   /// TRUE, if std should make polynomials monic (if nInvers is cheap)
82   /// if false, then a gcd routine is used for a content computation
83   BOOLEAN has_simple_Inverse;
84
85   // tests for numbers.cc:
86   BOOLEAN (*nCoeffIsEqual)(const coeffs r, n_coeffType n, void * parameter);
87
88   /// output of coeff description via Print
89   void (*cfCoeffWrite)(const coeffs r);
90
91   // the union stuff
92
93   // Zp:
94   int npPrimeM;
95   int npPminus1M;
96   #ifdef HAVE_DIV_MOD
97   unsigned short *npInvTable;
98   #endif
99   #if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
100   unsigned short *npExpTable;
101   unsigned short *npLogTable;
102   #endif
103
104   // ?
105   // initialisation:
106   //void (*cfInitChar)(coeffs r, int parameter); // do one-time initialisations
107   void (*cfKillChar)(coeffs r); //  undo all initialisations
108                                // or NULL
109   void (*cfSetChar)(const coeffs r); // initialisations after each ring change
110                                // or NULL
111   // general stuff
112   numberfunc cfMult, cfSub ,cfAdd ,cfDiv, cfIntDiv, cfIntMod, cfExactDiv;
113   /// init with an integer
114   number  (*cfInit)(int i,const coeffs r);
115   number  (*cfPar)(int i, const coeffs r);
116   int     (*cfParDeg)(number n, const coeffs r);
117   /// how complicated, (0) => 0, or positive
118   int     (*cfSize)(number n, const coeffs r);
119   /// convertion, 0 if impossible
120   int     (*cfInt)(number &n, const coeffs r);
121
122#ifdef HAVE_RINGS
123   int     (*cfDivComp)(number a,number b,const coeffs r);
124   BOOLEAN (*cfIsUnit)(number a,const coeffs r);
125   number  (*cfGetUnit)(number a,const coeffs r);
126   number  (*cfExtGcd)(number a, number b, number *s, number *t,const coeffs r);
127#endif
128
129   /// changes argument  inline: a:= -a
130   number  (*cfNeg)(number a, const coeffs r);
131   /// return 1/a
132   number  (*cfInvers)(number a, const coeffs r);
133   /// return a copy of a
134   number  (*cfCopy)(number a, const coeffs r);
135   number  (*cfRePart)(number a, const coeffs r);
136   number  (*cfImPart)(number a, const coeffs r);
137   void    (*cfWrite)(number &a, const coeffs r);
138   const char *  (*cfRead)(const char * s, number * a, const coeffs r);
139   void    (*cfNormalize)(number &a, const coeffs r);
140   BOOLEAN (*cfGreater)(number a,number b, const coeffs r),
141#ifdef HAVE_RINGS
142           (*cfDivBy)(number a, number b, const coeffs r),
143#endif
144            /// tests
145           (*cfEqual)(number a,number b, const coeffs r),
146           (*cfIsZero)(number a, const coeffs r),
147           (*cfIsOne)(number a, const coeffs r),
148           (*cfIsMOne)(number a, const coeffs r),
149           (*cfGreaterZero)(number a, const coeffs r);
150
151   void    (*cfPower)(number a, int i, number * result, const coeffs r);
152   number  (*cfGetDenom)(number &n, const coeffs r);
153   number  (*cfGetNumerator)(number &n, const coeffs r);
154   number  (*cfGcd)(number a, number b, const coeffs r);
155   number  (*cfLcm)(number a, number b, const coeffs r);
156   void    (*cfDelete)(number * a, const coeffs r);
157   nMapFunc (*cfSetMap)(const coeffs src, const coeffs dst);
158
159   /// For extensions (writes into global string buffer)
160   char *  (*cfName)(number n, const coeffs r);
161
162   /// Inplace: a *= b
163   void    (*cfInpMult)(number &a, number b, const coeffs r);
164   /// maps the bigint i (from dummy) into the coeffs dst
165   number  (*cfInit_bigint)(number i, const coeffs dummy, const coeffs dst);
166
167#ifdef HAVE_FACTORY
168   number (*convFactoryNSingN)( const CanonicalForm n, const coeffs r);
169   CanonicalForm (*convSingNFactoryN)( number n, BOOLEAN setChar, const coeffs r );
170#endif
171
172
173#ifdef LDEBUG
174   /// Test: is "a" a correct number?
175   BOOLEAN (*cfDBTest)(number a, const char *f, const int l, const coeffs r);
176#endif
177
178   number nNULL; /* the 0 as constant */
179   int     char_flag;
180   int     ref;
181   n_coeffType type;
182//-------------------------------------------
183
184  /// For Zp_a, Q_a we need polynomials (due to polys)
185  ring          algring; //< implementation of extensions needs polynomials...
186  // // for Q_a/Zp_a, rInit
187  //number     minpoly;  //< no longer needed: replaced by
188  //                     //<  algring->minideal->[0]
189
190
191//-------------------------------------------
192  char* complex_parameter; //< the name of sqrt(-1), i.e. 'i' or 'j' etc...?
193
194#ifdef HAVE_RINGS
195  /* The following members are for representing the ring Z/n,
196     where n is not a prime. We distinguish four cases:
197     1.) n has at least two distinct prime factors. Then
198         modBase stores n, modExponent stores 1, modNumber
199         stores n, and mod2mMask is not used;
200     2.) n = p^k for some odd prime p and k > 1. Then
201         modBase stores p, modExponent stores k, modNumber
202         stores n, and mod2mMask is not used;
203     3.) n = 2^k for some k > 1; moreover, 2^k - 1 fits in
204         an unsigned long. Then modBase stores 2, modExponent
205         stores k, modNumber is not used, and mod2mMask stores
206         2^k - 1, i.e., the bit mask '111..1' of length k.
207     4.) n = 2^k for some k > 1; but 2^k - 1 does not fit in
208         an unsigned long. Then modBase stores 2, modExponent
209         stores k, modNumber stores n, and mod2mMask is not
210         used;
211     Cases 1.), 2.), and 4.) are covered by the implementation
212     in the files rmodulon.h and rmodulon.cc, whereas case 3.)
213     is implemented in the files rmodulo2m.h and rmodulo2m.cc. */
214  int_number    modBase;
215  unsigned long modExponent;
216  int_number    modNumber;
217  unsigned long mod2mMask;
218#endif
219  int        ch;  /* characteristic, set by the local *InitChar methods;
220                     In field extensions or extensions towers, the
221                     characteristic can be accessed from any of the
222                     intermediate extension fields, i.e., in this case
223                     it is redundant along the chain of field extensions;
224                     CONTRARY to SINGULAR as it was, we do NOT LONGER use
225                     negative values for ch. */
226
227  short      float_len; /* additional char-flags, rInit */
228  short      float_len2; /* additional char-flags, rInit */
229
230  BOOLEAN   ShortOut; /// ffields need this.
231
232// ---------------------------------------------------
233  // for n_GF
234
235  int m_nfCharQ;  ///< the number of elemts: q
236  int m_nfM1;       ///< representation of -1
237  int m_nfCharP;  ///< the characteristic: p
238  int m_nfCharQ1; ///< q-1
239  unsigned short *m_nfPlus1Table;
240  int *m_nfMinPoly;
241  char * m_nfParameter;
242};
243//
244// test properties and type
245/// Returns the type of coeffs domain
246static inline n_coeffType getCoeffType(const coeffs r)
247{
248  assume(r != NULL);
249  return r->type;
250}
251
252static inline int nInternalChar(const coeffs r)
253{
254  assume(r != NULL);
255  return r->ch;
256}
257
258/// one-time initialisations for new coeffs
259/// in case of an error return NULL
260coeffs nInitChar(n_coeffType t, void * parameter);
261
262/// undo all initialisations
263void nKillChar(coeffs r);
264
265/// initialisations after each ring change
266static inline void nSetChar(const coeffs r)
267{
268  assume(r!=NULL); // r==NULL is an error
269  if (r->cfSetChar!=NULL) r->cfSetChar(r);
270}
271
272void           nNew(number * a);
273#define n_New(n, r)           nNew(n)
274
275
276// the access methods (part 2):
277
278/// return a copy of a
279static inline number n_Copy(number n,    const coeffs r)
280{   assume(r != NULL); assume(r->cfCopy!=NULL); return r->cfCopy(n, r); }
281
282static inline void   n_Delete(number* p, const coeffs r)
283{   assume(r != NULL); assume(r->cfDelete!= NULL); r->cfDelete(p, r); }
284
285static inline BOOLEAN n_Equal(number a, number b, const coeffs r)
286{ assume(r != NULL); assume(r->cfEqual!=NULL); return r->cfEqual(a, b, r); }
287
288static inline BOOLEAN n_IsZero(number n, const coeffs r)
289{ assume(r != NULL); assume(r->cfIsZero!=NULL); return r->cfIsZero(n,r); }
290
291static inline BOOLEAN n_IsOne(number n,  const coeffs r)
292{ assume(r != NULL); assume(r->cfIsOne!=NULL); return r->cfIsOne(n,r); }
293
294static inline BOOLEAN n_IsMOne(number n, const coeffs r)
295{ assume(r != NULL); assume(r->cfIsMOne!=NULL); return r->cfIsMOne(n,r); }
296
297static inline BOOLEAN n_GreaterZero(number n, const coeffs r)
298{ assume(r != NULL); assume(r->cfGreaterZero!=NULL); return r->cfGreaterZero(n,r); }
299static inline BOOLEAN n_Greater(number a, number b, const coeffs r)
300{ assume(r != NULL); assume(r->cfGreater!=NULL); return r->cfGreater(a,b,r); }
301
302#ifdef HAVE_RINGS
303static inline BOOLEAN n_IsUnit(number n, const coeffs r)
304{ assume(r != NULL); assume(r->cfIsUnit!=NULL); return r->cfIsUnit(n,r); }
305
306static inline number n_GetUnit(number n, const coeffs r)
307{ assume(r != NULL); assume(r->cfGetUnit!=NULL); return r->cfGetUnit(n,r); }
308
309static inline BOOLEAN n_DivBy(number a, number b, const coeffs r)
310{ assume(r != NULL); assume(r->cfDivBy!=NULL); return r->cfDivBy(a,b,r); }
311#endif
312
313/// init with an integer
314static inline number n_Init(int i,       const coeffs r)
315{ assume(r != NULL); assume(r->cfInit!=NULL); return r->cfInit(i,r); }
316
317/// conversion to int; 0 if not possible
318static inline int n_Int(number n,        const coeffs r)
319{ assume(r != NULL); assume(r->cfInt!=NULL); return r->cfInt(n,r); }
320
321/// changes argument  inline: a:= -a
322static inline number n_Neg(number n,     const coeffs r)
323{ assume(r != NULL); assume(r->cfNeg!=NULL); return r->cfNeg(n,r); }
324
325/// return 1/a
326static inline number n_Invers(number a,  const coeffs r)
327{ assume(r != NULL); assume(r->cfInvers!=NULL); return r->cfInvers(a,r); }
328
329/// use for pivot strategies, (0) => 0, otherwise positive
330static inline int    n_Size(number n,    const coeffs r)
331{ assume(r != NULL); assume(r->cfSize!=NULL); return r->cfSize(n,r); }
332
333/// normalize the number. i.e. go to some canonnical representation (inplace)
334static inline void   n_Normalize(number& n, const coeffs r)
335{ assume(r != NULL); assume(r->cfNormalize!=NULL); r->cfNormalize(n,r); }
336
337/// Normalize and Write to the output buffer of reporter
338static inline void   n_Write(number& n,  const coeffs r)
339{ assume(r != NULL); assume(r->cfWrite!=NULL); r->cfWrite(n,r); }
340
341/// Normalize and get denomerator
342static inline number n_GetDenom(number& n, const coeffs r)
343{ assume(r != NULL); assume(r->cfGetDenom!=NULL); return r->cfGetDenom(n, r); }
344
345/// Normalize and get numerator
346static inline number n_GetNumerator(number& n, const coeffs r)
347{ assume(r != NULL); assume(r->cfGetNumerator!=NULL); return r->cfGetNumerator(n, r); }
348
349static inline void   n_Power(number a, int b, number *res, const coeffs r)
350{ assume(r != NULL); assume(r->cfPower!=NULL); r->cfPower(a,b,res,r); }
351
352static inline number n_Mult(number a, number b, const coeffs r)
353{ assume(r != NULL); assume(r->cfMult!=NULL); return r->cfMult(a, b, r); }
354
355/// Inplace multiplication: a := a * b
356static inline void n_InpMult(number &a, number b, const coeffs r)
357{ assume(r != NULL); assume(r->cfInpMult!=NULL); r->cfInpMult(a,b,r); }
358
359static inline number n_Sub(number a, number b, const coeffs r)
360{ assume(r != NULL); assume(r->cfSub!=NULL); return r->cfSub(a, b, r); }
361
362static inline number n_Add(number a, number b, const coeffs r)
363{ assume(r != NULL); assume(r->cfAdd!=NULL); return r->cfAdd(a, b, r); }
364
365static inline number n_Div(number a, number b, const coeffs r)
366{ assume(r != NULL); assume(r->cfDiv!=NULL); return r->cfDiv(a,b,r); }
367
368static inline number n_IntDiv(number a, number b, const coeffs r)
369{ assume(r != NULL); assume(r->cfIntDiv!=NULL); return r->cfIntDiv(a,b,r); }
370
371static inline number n_ExactDiv(number a, number b, const coeffs r)
372{ assume(r != NULL); assume(r->cfExactDiv!=NULL); return r->cfExactDiv(a,b,r); }
373
374static inline number n_Gcd(number a, number b, const coeffs r)
375{ assume(r != NULL); assume(r->cfGcd!=NULL); return r->cfGcd(a,b,r); }
376
377static inline number n_Lcm(number a, number b, const coeffs r)
378{ assume(r != NULL); assume(r->cfLcm!=NULL); return r->cfLcm(a,b,r); }
379
380static inline nMapFunc n_SetMap(const coeffs src, const coeffs dst)
381{ assume(src != NULL && dst != NULL); assume(dst->cfSetMap!=NULL); return dst->cfSetMap(src,dst); }
382
383static inline number n_Par(int n, const coeffs r)
384{ assume(r != NULL); assume(r->cfPar!=NULL); return r->cfPar(n,r); }
385
386static inline int n_ParDeg(number n, const coeffs r)
387{ assume(r != NULL); assume(r->cfParDeg!=NULL); return r->cfParDeg(n,r); }
388
389/// Tests whether n is a correct number: only used if LDEBUG is defined
390static inline BOOLEAN n_DBTest(number n, const char *filename, const int linenumber, const coeffs r)
391{
392  assume(r != NULL); 
393#ifdef LDEBUG
394  assume(r->cfDBTest != NULL); 
395  return r->cfDBTest(n, filename, linenumber, r);
396#else
397  return TRUE;
398#endif
399}
400
401/// output the coeff description
402static inline void   n_CoeffWrite(const coeffs r)
403{ assume(r != NULL); assume(r->cfCoeffWrite != NULL); r->cfCoeffWrite(r); }
404
405// Tests:
406static inline BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
407{ assume(r != NULL); return (r->ringtype == 1); }
408
409static inline BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
410{ assume(r != NULL); return (r->ringtype == 2); }
411
412static inline BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
413{ assume(r != NULL); return (r->ringtype == 3); }
414
415static inline BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
416{ assume(r != NULL); return (r->ringtype == 4); }
417
418static inline BOOLEAN nCoeff_is_Ring(const coeffs r)
419{ assume(r != NULL); return (r->ringtype != 0); }
420
421/// returns TRUE, if r is not a field and r has no zero divisors (i.e is a domain)
422static inline BOOLEAN nCoeff_is_Domain(const coeffs r)
423{
424  assume(r != NULL); 
425#ifdef HAVE_RINGS
426  return (r->ringtype == 4 || r->ringtype == 0);
427#else
428  return TRUE;
429#endif
430}
431
432/// returns TRUE, if r is not a field and r has non-trivial units
433static inline BOOLEAN nCoeff_has_Units(const coeffs r)
434{ assume(r != NULL); return ((r->ringtype == 1) || (r->ringtype == 2) || (r->ringtype == 3)); }
435
436static inline BOOLEAN nCoeff_is_Zp(const coeffs r)
437{ assume(r != NULL); return getCoeffType(r)==n_Zp; }
438
439static inline BOOLEAN nCoeff_is_Zp(const coeffs r, int p)
440{ assume(r != NULL); return (getCoeffType(r)  && (r->ch == ABS(p))); }
441
442static inline BOOLEAN nCoeff_is_Q(const coeffs r)
443{ assume(r != NULL); return getCoeffType(r)==n_Q; }
444
445static inline BOOLEAN nCoeff_is_numeric(const coeffs r) /* R, long R, long C */
446{ assume(r != NULL);  return (getCoeffType(r)==n_R) || (getCoeffType(r)==n_long_R) || (getCoeffType(r)==n_long_C); }
447// (r->ringtype == 0) && (r->ch ==  -1); ??
448
449
450static inline BOOLEAN nCoeff_is_R(const coeffs r)
451{ assume(r != NULL); return getCoeffType(r)==n_R; }
452
453static inline BOOLEAN nCoeff_is_GF(const coeffs r)
454{ assume(r != NULL); return getCoeffType(r)==n_GF; }
455
456static inline BOOLEAN nCoeff_is_GF(const coeffs r, int q)
457{ assume(r != NULL); return (getCoeffType(r)==n_GF) && (r->ch == q); }
458
459/* TRUE iff an extension tower is build upon some Zp, i.e., the bottom
460   field in this tower is Zp */
461static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r)
462{
463  assume(r != NULL);
464  return (r->ringtype == 0) &&
465         ((getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt)) &&
466         (r->ch != 0);
467}
468
469/* TRUE iff an extension tower is build upon Zp (p as provided), i.e.,
470   the bottom field in this tower is Zp */
471static inline BOOLEAN nCoeff_is_Zp_a(const coeffs r, int p)
472{
473  assume(r != NULL);
474  return (r->ringtype == 0) &&
475         ((getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt)) &&
476         (r->ch != 0) && (r->ch == p);
477}
478
479/* TRUE iff an extension tower is build upon Q, i.e.,
480   the bottom field in this tower is Q */
481static inline BOOLEAN nCoeff_is_Q_a(const coeffs r)
482{
483  assume(r != NULL);
484  return (r->ringtype == 0) &&
485         ((getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt)) &&
486         (r->ch == 0);
487}
488
489static inline BOOLEAN nCoeff_is_long_R(const coeffs r)
490{ assume(r != NULL); return getCoeffType(r)==n_long_R; }
491
492static inline BOOLEAN nCoeff_is_long_C(const coeffs r)
493{ assume(r != NULL); return getCoeffType(r)==n_long_C; }
494
495static inline BOOLEAN nCoeff_is_CF(const coeffs r)
496{ assume(r != NULL); return getCoeffType(r)==n_CF; }
497
498/// TRUE, if the computation of the inverse is fast (i.e. prefer leading coeff. 1 over content)
499static inline BOOLEAN nCoeff_has_simple_inverse(const coeffs r)
500{ assume(r != NULL); return r->has_simple_Inverse; }
501/* Z/2^n, Z/p, GF(p,n), R, long_R, long_C*/
502// /* { return (r->ch>1) || (r->ch== -1); } *//* Z/p, GF(p,n), R, long_R, long_C*/
503// #ifdef HAVE_RINGS
504// { return (r->ringtype > 0) || (r->ch>1) || ((r->ch== -1) && (r->float_len < 10)); } /* Z/2^n, Z/p, GF(p,n), R, long_R, long_C*/
505// #else
506// { return (r->ch>1) || ((r->ch== -1) && (r->float_len < 10)); } /* Z/p, GF(p,n), R, long_R, long_C*/
507// #endif
508
509
510
511/// TRUE if n_Delete/n_New are empty operations
512static inline BOOLEAN nCoeff_has_simple_Alloc(const coeffs r)
513{ assume(r != NULL); return r->has_simple_Alloc; }
514/* Z/p, GF(p,n), R, Ring_2toM: nCopy, nNew, nDelete are dummies*/
515// return (rField_is_Zp(r)
516//         || rField_is_GF(r)
517// #ifdef HAVE_RINGS
518//             || rField_is_Ring_2toM(r)
519// #endif
520//             || rField_is_R(r)); }
521
522/* TRUE iff r represents an algebraic or transcendental extension field */
523static inline BOOLEAN nCoeff_is_Extension(const coeffs r)
524{
525  assume(r != NULL);
526  return (getCoeffType(r)==n_algExt) || (getCoeffType(r)==n_transExt);
527}
528
529/* TRUE iff r represents an algebraic extension field */
530static inline BOOLEAN nCoeff_is_algExt(const coeffs r)
531{ assume(r != NULL); return (getCoeffType(r)==n_algExt); }
532
533/* TRUE iff r represents a transcendental extension field */
534static inline BOOLEAN nCoeff_is_transExt(const coeffs r)
535{ assume(r != NULL); return (getCoeffType(r)==n_transExt); }
536
537/// BOOLEAN n_Test(number a, const coeffs r)
538#define n_Test(a,r)  n_DBTest(a, __FILE__, __LINE__, r)
539
540// Missing wrappers for:
541// cfIntMod, cfRePart, cfImPart, cfRead, cfName, cfInit_bigint
542// HAVE_RINGS: cfDivComp, cfExtGcd... cfDivBy
543
544
545// Deprecated:
546static inline int n_GetChar(const coeffs r)
547{ assume(r != NULL); return nInternalChar(r); }
548
549#endif
550
Note: See TracBrowser for help on using the repository browser.