source: git/Singular/p_Procs_Impl.h @ 0d7217

fieker-DuValspielwiese
Last change on this file since 0d7217 was 7e5a38, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* dynamic loading of p_Procs git-svn-id: file:///usr/local/Singular/svn/trunk@4833 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    p_Procs_Impl.h
6 *  Purpose: implementation of primitive procs for polys
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: p_Procs_Impl.h,v 1.1 2000-12-07 15:04:00 obachman Exp $
10 *******************************************************************/
11#ifndef P_PROCS_IMPL_H
12#define P_PROCS_IMPL_H
13
14/***************************************************************
15 * 
16 * Configurations
17 *
18 *******************************************************************/
19
20/***************************************************************
21 Here is how it works:
22 At run-time, SetProcs is used to choose the appropriate PolyProcs
23              based on the ring properies.
24 At generate-time, SetProcs is used to generate all
25              possible PolyProcs.
26 Which PolyProcs are generated/used can be controled by values of
27 HAVE_FAST_P_PROCS, HAVE_FAST_LENGTH, HAVE_FAST_ORD, and FAST_FIELD
28 
29 At generate-time, the file p_Procs.inc is generated,
30 which provides implementations of the p_Procs, based on
31 the p_*_Templates.cc and header files which provide the respective
32 macros.
33
34 At run-time, a fast proc is set/choosen if found/generated, else
35 a general proc is set/choosen.
36 *******************************************************************/
37
38// Define HAVE_FAST_P_PROCS to:
39//   0 -- only FieldGeneral_LengthGeneral_OrdGeneral
40//   1 -- plus FieldZp_Length*_OrdGeneral procs
41//   2 -- plus FieldZp_Length*_Ord* procs
42//   3 -- plus FieldQ_Length*_Ord*
43//   4 -- plus FieldGeneral_Length*_OrdGeneral procs
44//   5 -- all Field*_Length*_Ord* procs
45#ifndef HAVE_FAST_P_PROCS
46#define HAVE_FAST_P_PROCS 0
47#endif
48
49// Define HAVE_FAST_FIELD to:
50//   0 -- only FieldGeneral
51//   1 -- special cases for FieldZp
52//   2 -- plus special cases for FieldQ
53//   nothing else is implemented, yet
54#ifndef HAVE_FAST_FIELD
55#define HAVE_FAST_FIELD 0
56#endif
57
58// Define HAVE_FAST_LENGTH to:
59//   0 -- only LengthGeneral
60//   1 -- special cases for length <= 1
61//   2 -- special cases for length <= 2
62//   3 -- special cases for length <= 4
63//   4 -- special cases for length <= 8
64#ifndef HAVE_FAST_LENGTH
65#define HAVE_FAST_LENGTH 0
66#endif
67
68// Define HAVE_FAST_ORD to:
69//  0  -- only OrdGeneral
70//  1  -- special for ords with n_min <= 1
71//  2  -- special for ords with n_min <= 2
72//  3  -- special ords for with n_min <= 3
73//  4  -- special for all ords
74#ifndef HAVE_FAST_ORD
75#define HAVE_FAST_ORD 0
76#endif
77
78// Define HAVE_FAST_ZERO_ORD to:
79//  0 -- no zero ords are considered
80//  1 -- only ZeroOrds for OrdPosNomogPosZero, OrdNomogPosZero, OrdPomogNegZero
81//  2 -- ZeroOrds for all
82#ifndef HAVE_FAST_ZERO_ORD
83#define HAVE_FAST_ZERO_ORD 0
84#endif
85
86// undefine this, if ExpL_Size always equals CompLSize
87#define HAVE_LENGTH_DIFF
88
89
90// Predicate which returns true if alloc/copy/free of numbers is
91// like that of Zp
92#define ZP_COPY_FIELD(field) \
93  (field == FieldZp || field == FieldGF || field == FieldR)
94
95/***************************************************************
96 * 
97 * Definitions of our fields, lengths, ords, procs we work with
98 *
99 *******************************************************************/
100
101// Here are the different parameters for setting the PolyProcs:
102
103// If you add/remove things from here, also remeber to adjust the
104// respective *_2_String
105typedef enum p_Field
106{
107  FieldGeneral = 0,
108  FieldZp,         
109  FieldR,
110  FieldGF,
111  FieldQ,
112#if HAVE_MORE_FIELDS_IMPLEMENTED
113  FieldLong_R,
114  FieldLong_C,
115  FieldZp_a,
116  FieldQ_a,
117#endif
118  FieldUnknown
119};
120typedef enum p_Length // Length of exponent vector in words
121{
122  LengthGeneral = 0, // n >= 1
123  LengthEight,       // n == 8   
124  LengthSeven,
125  LengthSix,
126  LengthFive,
127  LengthFour,
128  LengthThree,
129  LengthTwo,
130  LengthOne,
131  LengthUnknown
132};
133typedef enum p_Ord 
134{                   
135  OrdGeneral = 0,   
136                    //     ordsgn   
137                    //  0   1   i   n-1 n   n_min   Example
138  OrdPomog,         //  +   +   +   +   +   1       (lp,C)
139  OrdNomog,         //  -   -   -   -   -   1       (ls, c), (ds, c)
140#define ORD_MAX_N_1 OrdNomog
141
142#ifdef HAVE_LENGTH_DIFF
143  OrdPomogZero,     //  +   +   +   +   0   2       (Dp, C), Even vars
144  OrdNomogZero,     //  -   -   -   -   0   2       (ds, c), Even vars
145#endif
146
147  OrdNegPomog,      //  -   +   +   +   +   2       (c, lp), (Ds, c)
148  OrdPomogNeg,      //  +   +   +   +   -   2       (lp, c)
149#define ORD_MAX_N_2 OrdPomogNeg
150
151  OrdPosNomog,      //  +   -   -   -   +   3       (dp, c) (for n == 2, use PomogNeg)
152  OrdNomogPos,      //  -   -   -   -   +   3       (ls, C) (for n == 2, use NegPomog)
153
154#ifdef HAVE_LENGTH_DIFF
155  OrdNegPomogZero,  //  -   +   +   +   0   3       (c, lp), (Ds, c)
156  OrdPomogNegZero,  //  +   +   +   -   0   3       (lp, c)
157#endif
158
159  OrdPosPosNomog,   //  +   +   -   -   -   3       (C, dp)
160  OrdPosNomogPos,   //  +   -   -   -   +   3       (dp, C)
161  OrdNegPosNomog,   //  -   +   -   -   -   3       (c, dp)
162#define ORD_MAX_N_3 OrdNegPosNomog
163
164#ifdef HAVE_LENGTH_DIFF
165  OrdNomogPosZero,  //  -   -   -   +   0   4       (ls, C) (for n == 3, use NegPomogZero)
166  OrdPosNomogZero,  //  +   -   -   -   0   4       (dp, c) (for n == 3, use PomogNegZero)
167
168  OrdPosPosNomogZero,// +   +   -   -   0   4       (C, dp)
169  OrdPosNomogPosZero,// +   -   -   +   0   4       (dp, C)
170  OrdNegPosNomogZero,// -   +   -   -   0   4       (c, dp)
171#endif
172
173  OrdUnknown
174};
175
176typedef enum p_Proc
177{
178  p_Copy_Proc = 0,
179  p_Delete_Proc,
180  p_ShallowCopyDelete_Proc,
181  p_Mult_nn_Proc,
182  pp_Mult_nn_Proc,
183  pp_Mult_mm_Proc,
184  pp_Mult_mm_Noether_Proc,
185  p_Mult_mm_Proc,
186  p_Add_q_Proc,
187  p_Minus_mm_Mult_qq_Proc,
188  p_Neg_Proc,
189  pp_Mult_Coeff_mm_DivSelect_Proc,
190  p_Merge_q_Proc,
191  p_kBucketSetLm_Proc,
192  p_Unknown_Proc
193};
194
195static inline char* p_FieldEnum_2_String(p_Field field)
196{
197  switch(field)
198  {
199      case FieldGeneral: return "FieldGeneral";
200      case FieldZp: return "FieldZp";         
201      case FieldR: return "FieldR";
202      case FieldGF: return "FieldGF";
203      case FieldQ: return "FieldQ";
204#if HAVE_MORE_FIELDS_IMPLEMENTED
205      case FieldLong_R: return "FieldLong_R";
206      case FieldLong_C: return "FieldLong_C";
207      case FieldZp_a: return "FieldZp_a";
208      case FieldQ_a: return "FieldQ_a";
209#endif
210      case FieldUnknown: return "FieldUnknown";
211  }
212  return "NoField_2_String";
213}
214
215static inline char* p_LengthEnum_2_String(p_Length length)
216{
217  switch(length)
218  {
219      case LengthGeneral: return "LengthGeneral"; 
220      case LengthEight: return "LengthEight";       
221      case LengthSeven: return "LengthSeven";
222      case LengthSix: return "LengthSix";
223      case LengthFive: return "LengthFive";
224      case LengthFour: return "LengthFour";
225      case LengthThree: return "LengthThree";
226      case LengthTwo: return "LengthTwo";
227      case LengthOne: return "LengthOne";
228      case LengthUnknown: return "LengthUnknown";
229  }
230  return "NoLength_2_String";
231}
232
233static inline char* p_OrdEnum_2_String(p_Ord ord)
234{
235  switch(ord)
236  {
237      case OrdGeneral: return "OrdGeneral";   
238      case OrdPomog: return "OrdPomog";         
239      case OrdNomog: return "OrdNomog";         
240      case OrdNegPomog: return "OrdNegPomog";     
241      case OrdPomogNeg: return "OrdPomogNeg";     
242      case OrdPosNomog: return "OrdPosNomog";     
243      case OrdNomogPos: return "OrdNomogPos";     
244      case OrdPosPosNomog: return "OrdPosPosNomog";   
245      case OrdPosNomogPos: return "OrdPosNomogPos";   
246      case OrdNegPosNomog: return "OrdNegPosNomog";   
247#ifdef HAVE_LENGTH_DIFF
248      case OrdNegPomogZero: return "OrdNegPomogZero"; 
249      case OrdPomogNegZero: return "OrdPomogNegZero"; 
250      case OrdPomogZero: return "OrdPomogZero";     
251      case OrdNomogZero: return "OrdNomogZero";     
252      case OrdNomogPosZero: return "OrdNomogPosZero"; 
253      case OrdPosNomogZero: return "OrdPosNomogZero"; 
254      case OrdPosPosNomogZero: return "OrdPosPosNomogZero";
255      case OrdPosNomogPosZero: return "OrdPosNomogPosZero";
256      case OrdNegPosNomogZero: return "OrdNegPosNomogZero";
257#endif
258      case OrdUnknown: return "OrdUnknown";
259  }
260  return "NoOrd_2_String";
261}
262
263static inline char* p_ProcEnum_2_String(p_Proc proc)
264{
265  switch(proc)
266  {
267      case p_Copy_Proc: return "p_Copy_Proc";
268      case p_Delete_Proc: return "p_Delete_Proc";
269      case p_ShallowCopyDelete_Proc: return "p_ShallowCopyDelete_Proc";
270      case p_Mult_nn_Proc: return "p_Mult_nn_Proc";
271      case pp_Mult_nn_Proc: return "pp_Mult_nn_Proc";
272      case pp_Mult_mm_Proc: return "pp_Mult_mm_Proc";
273      case pp_Mult_mm_Noether_Proc: return "pp_Mult_mm_Noether_Proc";
274      case p_Mult_mm_Proc: return "p_Mult_mm_Proc";
275      case p_Add_q_Proc: return "p_Add_q_Proc";
276      case p_Minus_mm_Mult_qq_Proc: return "p_Minus_mm_Mult_qq_Proc";
277      case p_Neg_Proc: return "p_Neg_Proc";
278      case pp_Mult_Coeff_mm_DivSelect_Proc: return "pp_Mult_Coeff_mm_DivSelect_Proc";
279      case p_Merge_q_Proc: return "p_Merge_q_Proc";
280      case p_kBucketSetLm_Proc: return "p_kBucketSetLm_Proc";
281      case p_Unknown_Proc: return "p_Unknown_Proc";
282  }
283  return "NoProc_2_String";
284}
285
286/***************************************************************
287 * 
288 *
289 * Deal with OrdZero
290 *
291 *******************************************************************/
292#ifdef HAVE_LENGTH_DIFF
293static inline int IsZeroOrd(p_Ord ord)
294{
295  return (ord == OrdPomogZero || ord == OrdNomogZero ||
296          ord == OrdNegPomogZero || ord == OrdPosNomogZero ||
297          ord == OrdPomogNegZero || ord == OrdNomogPosZero ||
298          ord == OrdPosNomogPosZero || ord == OrdPosPosNomogZero ||
299          ord == OrdNegPosNomogZero);
300}
301
302static inline p_Ord ZeroOrd_2_NonZeroOrd(p_Ord ord, int strict)
303{
304  if (IsZeroOrd(ord))
305  {
306    switch (ord)
307    {
308        case OrdPomogZero:      return OrdPomog;
309        case OrdNomogZero:      return OrdNomog;
310        case OrdNegPomogZero:   return OrdNegPomog;
311        case OrdPosNomogZero:   return OrdPosNomog;
312        case OrdPosPosNomogZero:    return OrdPosPosNomog;
313        case OrdNegPosNomogZero:    return OrdNegPosNomog;
314        default:   
315          if (strict) return OrdGeneral;
316          else if (ord == OrdPomogNegZero) return OrdPomogNeg;
317          else if (ord == OrdNomogPosZero) return OrdNomogPos;
318          else if (ord == OrdPosNomogPosZero) return OrdPosNomogPos;
319          else return OrdGeneral;
320    }
321  }
322  else
323  {
324    return ord;
325  }
326}
327#else
328#define IsZeroOrd(ord) 0
329#define ZeroOrd_2_NonZeroOrd(ord) (ord)
330#endif
331
332/***************************************************************
333 * 
334 * Filters which are applied to field/length/ord, before a proc is
335 * choosen
336 *
337 *******************************************************************/
338static inline void FastP_ProcsFilter(p_Field &field, p_Length &length, p_Ord &ord, const p_Proc proc)
339{
340  if (HAVE_FAST_P_PROCS >= 5) return;
341 
342  if (HAVE_FAST_P_PROCS < 3 && field == FieldQ)
343    field = FieldGeneral;
344 
345  if ((HAVE_FAST_P_PROCS == 0) ||
346      (HAVE_FAST_P_PROCS <= 4 && field != FieldZp && field != FieldQ &&
347       proc != p_Merge_q_Proc))
348  {
349    field = FieldGeneral;
350    length = LengthGeneral;
351    ord = OrdGeneral;
352    return;
353  }
354  if (HAVE_FAST_P_PROCS == 1 || 
355      (HAVE_FAST_P_PROCS == 4 && field != FieldZp && proc != p_Merge_q_Proc))
356    ord = OrdGeneral;
357}
358
359static inline void FastFieldFilter(p_Field &field)
360{
361  if (HAVE_FAST_FIELD <= 0 || 
362      (HAVE_FAST_FIELD == 1 && field != FieldZp) ||
363      (field != FieldZp && field != FieldQ))
364    field = FieldGeneral;
365}
366     
367static inline void FastLengthFilter(p_Length &length)
368{
369  if ((HAVE_FAST_LENGTH == 3 && length <= LengthFive) ||
370      (HAVE_FAST_LENGTH == 2 && length <= LengthFour) ||
371      (HAVE_FAST_LENGTH == 1 && length <= LengthTwo) ||
372      (HAVE_FAST_LENGTH <= 0))
373  {
374    length = LengthGeneral;
375  }
376}
377
378static inline void FastOrdFilter(p_Ord &ord)
379{
380  if ((HAVE_FAST_ORD == 3 && ord >= OrdNomogPosZero) ||
381      (HAVE_FAST_ORD == 2 && ord >= OrdPosNomog) ||
382      (HAVE_FAST_ORD == 1 && ord >= OrdPomogZero) ||
383      (HAVE_FAST_ORD <= 0))
384    ord = OrdGeneral;
385}
386
387static inline void FastOrdZeroFilter(p_Ord &ord)
388{
389  if (IsZeroOrd(ord))
390  {
391    if ((HAVE_FAST_ZERO_ORD == 1 && (ord != OrdPosNomogPosZero && 
392                                     ord != OrdNomogPosZero && 
393                                     ord != OrdPomogNegZero)) ||
394        (HAVE_FAST_ZERO_ORD <= 0))
395      ord = ZeroOrd_2_NonZeroOrd(ord, 1);
396  }
397}
398
399static inline void NCopy__Filter(p_Field &field)
400{
401  if (ZP_COPY_FIELD(field)) field = FieldZp;
402}
403
404// in p_Add_q, p_MemCmp works with CompLSize,
405// hence, we do not need to consider ZeroOrds
406static inline void p_Add_q__Filter(p_Length &length, p_Ord &ord)
407{
408  if (IsZeroOrd(ord))
409  {
410    ord = ZeroOrd_2_NonZeroOrd(ord, 0);
411    if (length > LengthGeneral)
412    {
413      length = (p_Length) ((int)length + 1);
414    }
415  }
416}
417
418static inline void pp_Mult_mm_Noether_Filter(p_Field &field, 
419                                             p_Length &length, p_Ord &ord)
420{
421  if (ord == OrdPomog
422      || ord == OrdPomogZero
423      || (ord == OrdPomogNeg && length > LengthTwo) 
424#ifdef HAVE_LENGTH_DIFF
425      || (ord == OrdPomogZero)
426      || (ord == OrdPomogNegZero && length > LengthThree)
427#endif
428      )
429  {
430    // all the other orderings might occur (remeber Mixed Orderings!)
431    field = FieldGeneral;
432    ord = OrdGeneral;
433    length = LengthGeneral;
434  }
435}
436     
437static inline void FastProcFilter(p_Proc proc, p_Field &field, 
438                                  p_Length &length, p_Ord &ord)
439{
440  switch(proc)
441  {
442      case p_Add_q_Proc:
443      case p_Merge_q_Proc:
444        p_Add_q__Filter(length, ord);
445        break;
446       
447      case p_Copy_Proc:
448      case p_Delete_Proc:
449        NCopy__Filter(field);
450        break;
451       
452      case pp_Mult_mm_Noether_Proc:
453        pp_Mult_mm_Noether_Filter(field, length, ord);
454        break;
455       
456      case p_kBucketSetLm_Proc:
457      {
458        if (field != FieldZp)
459        {
460          field = FieldGeneral;
461          length = LengthGeneral;
462          ord = OrdGeneral;
463          return;
464        }
465      }
466
467      default: break;
468  }
469
470  FastOrdFilter(ord);
471  FastOrdZeroFilter(ord);
472  FastLengthFilter(length);
473  FastFieldFilter(field);
474  FastP_ProcsFilter(field, length, ord, proc);
475}
476
477// returns 1 if combination of field/length/ord is invalid
478static inline int IsValidSpec(p_Field field, p_Length length, p_Ord ord)
479{
480  if (field == FieldUnknown || length == LengthUnknown || ord == OrdUnknown)
481    return 0;
482
483  if (length >= LengthThree && // i.e. 1, 2, or 3
484      ord > ORD_MAX_N_3)       //  i.e. OrdNomogPosZero and below
485    return 0;
486 
487  if (length >= LengthTwo &&    // i.e. 1 or 2
488      ord > ORD_MAX_N_2)        // i.e. PosNomog and below
489    return 0;
490
491  if (length == LengthOne && 
492      ord > ORD_MAX_N_1)           // i.e. PosPomogZero and below
493    return 0;
494
495  // we cover everything for length <= two
496  if (ord == OrdGeneral && length >= LengthTwo)
497    return 0;
498  return 1;
499}
500
501 
502static inline int index(p_Length length, p_Ord ord)
503{
504  return length*OrdUnknown + ord;
505}
506
507static inline int index(p_Field field, p_Length length)
508{
509  return field*LengthUnknown + length;
510}
511
512static inline int index(p_Field field, p_Length length, p_Ord ord)
513{
514  return field*LengthUnknown*OrdUnknown + length*OrdUnknown + ord;
515}
516
517static inline int index(p_Proc proc, p_Field field, p_Length length, p_Ord ord)
518{
519  switch(proc)
520  {
521      case p_Delete_Proc:
522      case p_Mult_nn_Proc:
523      case p_Neg_Proc:
524        return field;
525       
526      case p_ShallowCopyDelete_Proc:
527        return length;
528       
529      case p_Copy_Proc:
530      case pp_Mult_mm_Proc:
531      case p_Mult_mm_Proc:
532      case pp_Mult_nn_Proc:
533      case pp_Mult_Coeff_mm_DivSelect_Proc:
534        return index(field, length);
535
536      case p_Add_q_Proc:
537      case p_Minus_mm_Mult_qq_Proc:
538      case pp_Mult_mm_Noether_Proc:
539      case p_kBucketSetLm_Proc:
540        return index(field, length, ord);
541       
542      case p_Merge_q_Proc:
543        return index(length, ord);
544       
545      default:
546        assume(0);
547        return -1;
548  }
549}
550
551
552
553/***************************************************************
554 *
555 * Macros for setting procs -- these are used for
556 * generation and setting
557 *
558 ***************************************************************/
559
560#define SetProc(what, field, length, ord)                   \
561do                                                          \
562{                                                           \
563  p_Field t_field = field;                                  \
564  p_Ord t_ord = ord;                                        \
565  p_Length t_length = length;                               \
566  FastProcFilter(what##_Proc, t_field, t_length, t_ord);    \
567  DoSetProc(what, t_field, t_length, t_ord);                \
568}                                                           \
569while (0)                                                   \
570 
571#define SetProcs(field, length, ord)                                \
572do                                                                  \
573{                                                                   \
574  SetProc(p_Delete, field, LengthGeneral, OrdGeneral);              \
575  SetProc(p_Mult_nn, field, LengthGeneral, OrdGeneral);             \
576  SetProc(pp_Mult_nn, field, length, OrdGeneral);                   \
577  SetProc(p_ShallowCopyDelete, FieldGeneral, length, OrdGeneral);   \
578  SetProc(p_Copy, field, length, OrdGeneral);                       \
579  SetProc(pp_Mult_mm, field, length, OrdGeneral);                   \
580  SetProc(pp_Mult_mm_Noether, field, length, ord);                  \
581  SetProc(p_Mult_mm, field, length, OrdGeneral);                    \
582  SetProc(p_Add_q, field, length, ord);                             \
583  SetProc(p_Minus_mm_Mult_qq, field, length, ord);                  \
584  SetProc(p_kBucketSetLm, field, length, ord);                      \
585  SetProc(p_Neg, field, LengthGeneral, OrdGeneral);                 \
586  SetProc(pp_Mult_Coeff_mm_DivSelect, field, length, OrdGeneral);   \
587  SetProc(p_Merge_q, FieldGeneral, length, ord);                    \
588}                                                                   \
589while (0)
590
591#endif // P_PROCS_IMPL_H
592
Note: See TracBrowser for help on using the repository browser.