source: git/Singular/pInline2.h @ fa1f52

spielwiese
Last change on this file since fa1f52 was 2f436b, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* version 1-3-13: sparsemat improivements git-svn-id: file:///usr/local/Singular/svn/trunk@5003 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    pInline2.h
6 *  Purpose: implementation of poly procs which are of constant time
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: pInline2.h,v 1.23 2000-12-31 15:14:37 obachman Exp $
10 *******************************************************************/
11#ifndef PINLINE2_H
12#define PINLINE2_H
13
14/***************************************************************
15 *
16 * Primitives for accessing and setting fields of a poly
17 *
18 ***************************************************************/
19#if !defined(NO_PINLINE2) || defined(PINLINE2_CC)
20
21#include "tok.h"
22#include "omalloc.h"
23#include "numbers.h"
24#include "p_Procs.h"
25#include "sbuckets.h"
26
27PINLINE2 number p_SetCoeff(poly p, number n, ring r)
28{
29  p_LmCheckPolyRing2(p, r);
30  n_Delete(&(p->coef), r);
31  (p)->coef=n;
32  return n;
33}
34
35// order
36PINLINE2 Order_t p_GetOrder(poly p, ring r)
37{
38  p_LmCheckPolyRing2(p, r);
39  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]);
40  int i=0;
41  loop
42  {
43    switch(r->typ[i].ord_typ)
44    {
45      case ro_wp_neg:
46        return (((long)((p)->exp[r->pOrdIndex]))-((long) POLY_NEGWEIGHT_OFFSET));
47      case ro_syzcomp:
48      case ro_syz:
49      case ro_cp:
50        i++;
51        break;
52      //case ro_dp:
53      //case ro_wp:
54      default:
55        return ((p)->exp[r->pOrdIndex]);
56    }
57  }
58}
59
60PINLINE2 Order_t p_SetOrder(poly p, long o, ring r)
61{
62  p_LmCheckPolyRing2(p, r);
63  pAssume2(o >= 0);
64  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]=o);
65  int i=0;
66  loop
67  {
68    switch(r->typ[i].ord_typ)
69    {
70      case ro_wp_neg:
71        return (p)->exp[r->pOrdIndex]=o+POLY_NEGWEIGHT_OFFSET;
72      case ro_syzcomp:
73      case ro_syz:
74      case ro_cp:
75        i++;
76        break;
77      //case ro_dp:
78      //case ro_wp:
79      default:
80        return (p)->exp[r->pOrdIndex] = o;
81    }
82  }
83  return (p)->exp[r->pOrdIndex] = o;
84}
85
86// Setm
87PINLINE2 void p_Setm(poly p, ring r)
88{
89  p_CheckRing2(r);
90  r->p_Setm(p, r);
91}
92
93// component
94PINLINE2  unsigned long p_SetComp(poly p, unsigned long c, ring r)
95{
96  p_LmCheckPolyRing2(p, r);
97  pAssume2(rRing_has_Comp(r));
98  __p_GetComp(p,r) = c;
99  return c;
100}
101PINLINE2 unsigned long p_IncrComp(poly p, ring r)
102{
103  p_LmCheckPolyRing2(p, r);
104  pAssume2(rRing_has_Comp(r));
105  return ++(__p_GetComp(p,r));
106}
107PINLINE2 unsigned long p_DecrComp(poly p, ring r)
108{
109  p_LmCheckPolyRing2(p, r);
110  pAssume2(rRing_has_Comp(r));
111  pPolyAssume2(__p_GetComp(p,r) > 0);
112  return --(__p_GetComp(p,r));
113}
114PINLINE2 unsigned long p_AddComp(poly p, unsigned long v, ring r)
115{
116  p_LmCheckPolyRing2(p, r);
117  pAssume2(rRing_has_Comp(r));
118  return __p_GetComp(p,r) += v;
119}
120PINLINE2 unsigned long p_SubComp(poly p, unsigned long v, ring r)
121{
122  p_LmCheckPolyRing2(p, r);
123  pAssume2(rRing_has_Comp(r));
124  pPolyAssume2(__p_GetComp(p,r) >= v);
125  return __p_GetComp(p,r) -= v;
126}
127
128// exponent
129// r->VarOffset encodes the position in p->exp (lower 24 bits)
130// and number of bits to shift to the right in the upper 8 bits
131PINLINE2 Exponent_t p_GetExp(poly p, int v, ring r)
132{
133  p_LmCheckPolyRing2(p, r);
134  pAssume2(v > 0 && v <= r->N);
135  return (p->exp[(r->VarOffset[v] & 0xffffff)] >> (r->VarOffset[v] >> 24))
136          & r->bitmask;
137}
138PINLINE2 Exponent_t p_SetExp(poly p, int v, int e, ring r)
139{
140  p_LmCheckPolyRing2(p, r);
141  pAssume2(v>0 && v <= r->N);
142  pAssume2(e>=0);
143  pAssume2((unsigned int) e<=r->bitmask);
144
145  // shift e to the left:
146  register int shift = r->VarOffset[v] >> 24;
147  unsigned long ee = ((unsigned long)e) << shift /*(r->VarOffset[v] >> 24)*/;
148  // clear the bits in the exponent vector:
149  register int offset = (r->VarOffset[v] & 0xffffff);
150  p->exp[offset]  &=
151    ~( r->bitmask << shift );
152  // insert e with |
153  p->exp[ offset ] |= ee;
154  return e;
155}
156
157// the following should be implemented more efficiently
158PINLINE2  Exponent_t p_IncrExp(poly p, int v, ring r)
159{
160  p_LmCheckPolyRing2(p, r);
161  Exponent_t e = p_GetExp(p,v,r);
162  e++;
163  return p_SetExp(p,v,e,r);
164}
165PINLINE2  Exponent_t p_DecrExp(poly p, int v, ring r)
166{
167  p_LmCheckPolyRing2(p, r);
168  Exponent_t e = p_GetExp(p,v,r);
169  pAssume2(e > 0);
170  e--;
171  return p_SetExp(p,v,e,r);
172}
173PINLINE2  Exponent_t p_AddExp(poly p, int v, Exponent_t ee, ring r)
174{
175  p_LmCheckPolyRing2(p, r);
176  Exponent_t e = p_GetExp(p,v,r);
177  e += ee;
178  return p_SetExp(p,v,e,r);
179}
180PINLINE2  Exponent_t p_SubExp(poly p, int v, Exponent_t ee, ring r)
181{
182  p_LmCheckPolyRing2(p, r);
183  Exponent_t e = p_GetExp(p,v,r);
184  pAssume2(e >= ee);
185  e -= ee;
186  return p_SetExp(p,v,e,r);
187}
188PINLINE2  Exponent_t p_MultExp(poly p, int v, Exponent_t ee, ring r)
189{
190  p_LmCheckPolyRing2(p, r);
191  Exponent_t e = p_GetExp(p,v,r);
192  e *= ee;
193  return p_SetExp(p,v,e,r);
194}
195
196PINLINE2 Exponent_t p_GetExpSum(poly p1, poly p2, int i, ring r)
197{
198  p_LmCheckPolyRing2(p1, r);
199  p_LmCheckPolyRing2(p2, r);
200  return p_GetExp(p1,i,r) + p_GetExp(p2,i,r);
201}
202PINLINE2 Exponent_t p_GetExpDiff(poly p1, poly p2, int i, ring r)
203{
204  return p_GetExp(p1,i,r) - p_GetExp(p2,i,r);
205}
206
207
208/***************************************************************
209 *
210 * Allocation/Initalization/Deletion
211 *
212 ***************************************************************/
213PINLINE2 poly p_New(ring r, omBin bin)
214{
215  p_CheckRing2(r);
216  pAssume2(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
217  poly p;
218  omTypeAllocBin(poly, p, bin);
219  p_SetRingOfLm(p, r);
220  return p;
221}
222
223PINLINE2 poly p_New(ring r)
224{
225  return p_New(r, r->PolyBin);
226}
227
228PINLINE2 void p_DeleteLm(poly *p, ring r)
229{
230  pIfThen2(*p != NULL, p_LmCheckPolyRing2(*p, r));
231  poly h = *p;
232  if (h != NULL)
233  {
234    n_Delete(&_pGetCoeff(h), r);
235    *p = _pNext(h);
236    omFreeBinAddr(h);
237  }
238}
239PINLINE2 void p_DeleteLm(poly p, ring r)
240{
241  pIfThen2(p != NULL, p_LmCheckPolyRing2(p, r));
242  if (p != NULL)
243  {
244    n_Delete(&_pGetCoeff(p), r);
245    omFreeBinAddr(p);
246  }
247}
248PINLINE2 void p_LmFree(poly p, ring r)
249{
250  p_LmCheckPolyRing2(p, r);
251  omFreeBinAddr(p);
252}
253PINLINE2 void p_LmFree(poly *p, ring r)
254{
255  p_LmCheckPolyRing2(*p, r);
256  poly h = *p;
257  *p = pNext(h);
258  omFreeBinAddr(h);
259}
260PINLINE2 poly p_LmFreeAndNext(poly p, ring r)
261{
262  p_LmCheckPolyRing2(p, r);
263  poly pnext = pNext(p);
264  omFreeBinAddr(p);
265  return pnext;
266}
267PINLINE2 void p_LmDelete(poly p, ring r)
268{
269  p_LmCheckPolyRing2(p, r);
270  n_Delete(&_pGetCoeff(p), r);
271  omFreeBinAddr(p);
272}
273PINLINE2 void p_LmDelete(poly *p, ring r)
274{
275  p_LmCheckPolyRing2(*p, r);
276  poly h = *p;
277  *p = pNext(h);
278  n_Delete(&pGetCoeff(h), r);
279  omFreeBinAddr(h);
280}
281PINLINE2 poly p_LmDeleteAndNext(poly p, ring r)
282{
283  p_LmCheckPolyRing2(p, r);
284  poly pnext = _pNext(p);
285  n_Delete(&_pGetCoeff(p), r);
286  omFreeBinAddr(p);
287  return pnext;
288}
289
290/***************************************************************
291 *
292 * Misc routines
293 *
294 ***************************************************************/
295PINLINE2 int p_Cmp(poly p1, poly p2, ring r)
296{
297  if (p2==NULL)
298    return 1;
299  if (p1==NULL)
300    return -1;
301  return p_LmCmp(p1,p2,r);
302}
303
304PINLINE2 Exponent_t p_GetMaxExp(poly p, ring r)
305{
306  return p_GetMaxExp(p_GetMaxExpL(p, r), r);
307}
308
309PINLINE2 Exponent_t
310p_GetMaxExp(const unsigned long l, const ring r, const int number_of_exps)
311{
312  unsigned long bitmask = r->bitmask;
313  unsigned long max = (l & bitmask);
314  unsigned long j = number_of_exps - 1;
315 
316  if (j > 0)
317  {
318    unsigned long i = r->BitsPerExp;
319    Exponent_t e;
320    while(1)
321    {
322      e = ((l >> i) & bitmask);
323      if ((unsigned long) e > max) 
324        max = e;
325      j--;
326      if (j==0) break;
327      i += r->BitsPerExp;
328    }
329  }
330  return max;
331}
332
333PINLINE2 Exponent_t p_GetMaxExp(const unsigned long l, const ring r)
334{
335  return p_GetMaxExp(l, r, r->ExpPerLong);
336}
337
338PINLINE2 unsigned long 
339p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps)
340{
341  const unsigned long bitmask = r->bitmask;
342  unsigned long sum = (l & bitmask);
343  unsigned long j = number_of_exps - 1;
344 
345  if (j > 0)
346  {
347    unsigned long i = r->BitsPerExp;
348    while(1)
349    {
350      sum += ((l >> i) & bitmask);
351      j--;
352      if (j==0) break;
353      i += r->BitsPerExp;
354    }
355  }
356  return sum;
357}
358
359PINLINE2 unsigned long 
360p_GetTotalDegree(const unsigned long l, const ring r)
361{
362  return p_GetTotalDegree(l, r, r->ExpPerLong);
363}
364
365/***************************************************************
366 *
367 * Dispatcher to r->p_Procs, they do the tests/checks
368 *
369 ***************************************************************/
370// returns a copy of p
371PINLINE2 poly p_Copy(poly p, const ring r)
372{
373  return r->p_Procs->p_Copy(p, r);
374}
375
376PINLINE2 poly p_Copy(poly p, const ring lmRing, const ring tailRing)
377{
378#ifndef PDEBUG
379  if (tailRing == lmRing)
380    return tailRing->p_Procs->p_Copy(p, tailRing);
381#endif
382  if (p != NULL)
383  {
384    poly pres = p_Head(p, lmRing);
385    pNext(pres) = tailRing->p_Procs->p_Copy(pNext(p), tailRing);
386    return pres;
387  }
388  else
389    return NULL;
390}
391
392// deletes *p, and sets *p to NULL
393PINLINE2 void p_Delete(poly *p, const ring r)
394{
395  r->p_Procs->p_Delete(p, r);
396}
397
398PINLINE2 void p_Delete(poly *p,  const ring lmRing, const ring tailRing)
399{
400#ifndef PDEBUG
401  if (tailRing == lmRing)
402  {
403    tailRing->p_Procs->p_Delete(p, tailRing);
404    return;
405  }
406#endif
407  if (*p != NULL)
408  {
409    if (pNext(*p) != NULL)
410      tailRing->p_Procs->p_Delete(&pNext(*p), tailRing);
411    p_LmDelete(p, lmRing);
412  }
413}
414
415PINLINE2 poly p_ShallowCopyDelete(poly p, const ring r, omBin bin)
416{
417  p_LmCheckPolyRing2(p, r);
418  pAssume2(r->PolyBin->sizeW == bin->sizeW);
419  return r->p_Procs->p_ShallowCopyDelete(p, r, bin);
420}
421
422// returns p+q, destroys p and q
423PINLINE2 poly p_Add_q(poly p, poly q, const ring r)
424{
425  int shorter;
426  return r->p_Procs->p_Add_q(p, q, shorter, r);
427}
428
429PINLINE2 poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r)
430{
431  int shorter;
432  poly res = r->p_Procs->p_Add_q(p, q, shorter, r);
433  lp = (lp + lq) - shorter;
434  return res;
435}
436
437// returns p*n, destroys p
438PINLINE2 poly p_Mult_nn(poly p, number n, const ring r)
439{
440  if (n_IsOne(n, r))
441    return p;
442  else
443    return r->p_Procs->p_Mult_nn(p, n, r);
444}
445
446PINLINE2 poly p_Mult_nn(poly p, number n, const ring lmRing,
447                        const ring tailRing)
448{
449#ifndef PDEBUG
450  if (lmRing == tailRing)
451  {
452    return p_Mult_nn(p, n, tailRing);
453  }
454#endif
455  poly pnext = pNext(p);
456  pNext(p) = NULL;
457  p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing);
458  pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing);
459  return p;
460}
461
462// returns p*n, does not destroy p
463PINLINE2 poly pp_Mult_nn(poly p, number n, const ring r)
464{
465  if (n_IsOne(n, r))
466    return p_Copy(p, r);
467  else
468    return r->p_Procs->pp_Mult_nn(p, n, r);
469}
470
471// returns Copy(p)*m, does neither destroy p nor m
472PINLINE2 poly pp_Mult_mm(poly p, poly m, const ring r)
473{
474  if (p_LmIsConstant(m, r))
475    return pp_Mult_nn(p, pGetCoeff(m), r);
476  else
477  {
478    poly last;
479    return r->p_Procs->pp_Mult_mm(p, m, r, last);
480  }
481}
482
483// returns p*m, destroys p, const: m
484PINLINE2 poly p_Mult_mm(poly p, poly m, const ring r)
485{
486  if (p_LmIsConstant(m, r))
487    return p_Mult_nn(p, pGetCoeff(m), r);
488  else
489    return r->p_Procs->p_Mult_mm(p, m, r);
490}
491
492// return p - m*Copy(q), destroys p; const: p,m
493PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
494{
495  int shorter;
496  poly last;
497  return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
498}
499PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
500                                 poly spNoether, const ring r)
501{
502  int shorter;
503  poly last;
504  poly res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r, last);
505  lp = (lp + lq) - shorter;
506  return res;
507}
508
509PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r)
510{
511  int shorter;
512  return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
513}
514
515PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r)
516{
517  int shorter;
518  poly pp = r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
519  lp -= shorter;
520  return pp;
521}
522
523// returns -p, destroys p
524PINLINE2 poly p_Neg(poly p, const ring r)
525{
526  return r->p_Procs->p_Neg(p, r);
527}
528
529extern poly  _p_Mult_q(poly p, poly q, const int copy, const ring r);
530// returns p*q, destroys p and q
531PINLINE2 poly p_Mult_q(poly p, poly q, const ring r)
532{
533  if (p == NULL)
534  {
535    r->p_Procs->p_Delete(&q, r);
536    return NULL;
537  }
538  if (q == NULL)
539  {
540    r->p_Procs->p_Delete(&p, r);
541    return NULL;
542  }
543
544  if (pNext(p) == NULL)
545  {
546#ifdef HAVE_PLURAL
547    if (rIsPluralRing(r))
548      q = r->p_Procs->nc_mm_Mult_p(p, q, r);
549    else
550#endif HAVE_PLURAL
551      q = r->p_Procs->p_Mult_mm(q, p, r);
552
553    r->p_Procs->p_Delete(&p, r);
554    return q;
555  }
556
557  if (pNext(q) == NULL)
558  {
559    p = r->p_Procs->p_Mult_mm(p, q, r);
560    r->p_Procs->p_Delete(&q, r);
561    return p;
562  }
563
564  return _p_Mult_q(p, q, 0, r);
565}
566
567// returns p*q, does neither destroy p nor q
568PINLINE2 poly pp_Mult_qq(poly p, poly q, const ring r)
569{
570  poly last;
571  if (p == NULL || q == NULL) return NULL;
572
573  if (pNext(p) == NULL)
574    return r->p_Procs->pp_Mult_mm(q, p, r, last);
575
576  if (pNext(q) == NULL)
577    return r->p_Procs->pp_Mult_mm(p, q, r, last);
578
579  poly qq = q;
580  if (p == q)
581    qq = p_Copy(q, r);
582
583  poly res = _p_Mult_q(p, qq, 1, r);
584  if (qq != q)
585    p_Delete(&qq, r);
586  return res;
587}
588
589// returns p + m*q destroys p, const: q, m
590// this should be implemented more efficiently
591PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq, 
592                                const ring r)
593{
594  poly res, last;
595  int shorter;
596  number n_old = pGetCoeff(m);
597  number n_neg = n_Copy(n_old, r);
598  n_neg = n_Neg(n_neg, r);
599  pSetCoeff0(m, n_neg);
600
601  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
602  lp = (lp + lq) - shorter;
603  pSetCoeff0(m, n_old);
604  n_Delete(&n_neg, r);
605  return res;
606}
607
608PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
609{
610  int lp = 0, lq = 0;
611  return p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
612}
613
614PINLINE2 poly p_Merge_q(poly p, poly q, const ring r)
615{
616  return r->p_Procs->p_Merge_q(p, q, r);
617}
618
619PINLINE2 poly p_SortAdd(poly p, const ring r, BOOLEAN revert)
620{
621  if (revert) p = pReverse(p);
622  return sBucketSortAdd(p, r);
623}
624
625PINLINE2 poly p_SortMerge(poly p, const ring r, BOOLEAN revert)
626{
627  if (revert) p = pReverse(p);
628  return sBucketSortMerge(p, r);
629}
630
631/***************************************************************
632 *
633 * I/O
634 *
635 ***************************************************************/
636PINLINE2 char*     p_String(poly p, ring p_ring)
637{
638  return p_String(p, p_ring, p_ring);
639}
640PINLINE2 char*     p_String0(poly p, ring p_ring)
641{
642  return p_String0(p, p_ring, p_ring);
643}
644PINLINE2 void      p_Write(poly p, ring p_ring)
645{
646  p_Write(p, p_ring, p_ring);
647}
648PINLINE2 void      p_Write0(poly p, ring p_ring)
649{
650  p_Write0(p, p_ring, p_ring);
651}
652PINLINE2 void      p_wrp(poly p, ring p_ring)
653{
654  p_wrp(p, p_ring, p_ring);
655}
656#endif // !defined(NO_PINLINE2) || defined(POLYS_IMPL_CC)
657#endif // PINLINE2_H
658
Note: See TracBrowser for help on using the repository browser.