source: git/Singular/prProcs.cc @ a70441f

spielwiese
Last change on this file since a70441f was a70441f, checked in by Olaf Bachmann <obachman@…>, 24 years ago
Windows and gcc 2.95 porting git-svn-id: file:///usr/local/Singular/svn/trunk@4273 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: prProcs.cc,v 1.2 2000-04-27 10:07:10 obachman Exp $ */
5/*
6*  ABSTRACT -  Routines for primitive poly arithmetic
7*/
8#include "mod2.h"
9#include "mmemory.h"
10#include "polys.h"
11#include "polys-comp.h"
12#include "prProcs.h"
13#include "numbers.h"
14
15// #define HAVE_CHAR_P
16
17#ifdef HAVE_CHAR_P
18#include "modulop.h"
19
20#undef nDelete
21#define nDelete(n)
22#define nMult(n1, n2)   npMultM(n1, n2)
23#define nAdd(n1, n2)    npAddM(n1, n2)
24#define nSub(n1, n2)    npSubM(n1, n2)
25#define nEqual(n1, n2)  npEqualM(n1, n2)
26#define nIsZero(n)      npIsZeroM(n)
27#endif
28
29// Define to enable tests in this file
30// #define DEBUG_THIS
31
32#if ! (defined(DEBUG_THIS) || (defined(PDEBUG) && PDEBUG > 0))
33#undef assume
34#define assume(x)
35#endif
36
37#define prFree1AndAdvance(p, r)                  \
38do                                              \
39{                                               \
40  poly __p = p;                                 \
41  p = pNext(__p);                               \
42  FreeHeap(__p, r->mm_specHeap);                \
43}                                               \
44while(0)
45/***************************************************************
46 *
47 * General:  pr_Mult_n which always works
48 * Returns:  p*n
49 * Destroys: p
50 * Const:    n
51 *
52 ***************************************************************/
53
54poly pr_Mult_n_General(poly p, number n)
55{
56  poly q = p;
57  while (p != NULL)
58  {
59    number nc = pGetCoeff(p);
60    pSetCoeff0(p, nMult(n, nc));
61    nDelete(&nc);
62    pIter(p);
63  }
64  return q;
65}
66
67
68/***************************************************************
69 *
70 * General:  pr_Add_q which always works
71 * Returns:  p + q, *lp == pLength(p+q), p+q are from heap
72 * Destroys: p, q
73 * Assume:   *lp == NULL || pLength(p) == *lp && pLength(q) == q
74 *           p, q are from heap
75 *
76 ***************************************************************/
77
78poly pr_Add_q_General(poly p, poly q, int *lp, int lq,
79                     const ring r)
80{
81  assume(prTest(p, r));
82  assume(prTest(q, r));
83  assume(lp == NULL || pLength(p) == *lp);
84  assume(lp == NULL || pLength(q) == lq);
85
86  // test for trivial cases
87  if (q == NULL) return p;
88  if (p == NULL)
89  {
90    if (lp != NULL) *lp = lq;
91    return q;
92  }
93 
94  number t, n1, n2;
95  int l;
96  spolyrec rp;
97  poly a = &rp;
98
99  if (lp != NULL) l = *lp + lq;
100
101  Top:     // compare p and q w.r.t. monomial ordering
102  _prMonCmp(p, q, r, goto Equal, goto Greater , goto Smaller);
103
104  Equal:
105  assume(prComp0(p, q, r) == 0);
106
107  n1 = pGetCoeff(p);
108  n2 = pGetCoeff(q);
109  t = nAdd(n1,n2);
110  nDelete(&n1);
111  nDelete(&n2);
112  prFree1AndAdvance(q, r);
113 
114  if (nIsZero(t))
115  {
116    l -= 2;
117    nDelete(&t);
118    prFree1AndAdvance(p, r);
119  }
120  else
121  {
122    l--;
123    pSetCoeff0(p,t);
124    a = pNext(a) = p;
125    pIter(p);
126  }
127  if (p==NULL) { pNext(a) = q; goto Finish;}
128  if (q==NULL) { pNext(a) = p; goto Finish;}
129  goto Top;
130     
131  Greater:
132  assume(prComp0(p, q, r) == 1);
133  a = pNext(a) = p;
134  pIter(p);
135  if (p==NULL) { pNext(a) = q; goto Finish;}
136  goto Top;
137   
138  Smaller:
139  assume(prComp0(p, q, r) == -1);
140  a = pNext(a) = q;
141  pIter(q);
142  if (q==NULL) { pNext(a) = p; goto Finish;}
143  goto Top;
144 
145
146  Finish:
147  if (lp != NULL) *lp = l;
148
149  assume(prTest(pNext(&rp), r));
150  assume(lp == NULL || pLength(pNext(&rp)) == *lp);
151  return pNext(&rp);
152}
153
154
155/***************************************************************
156 *
157 * General: pr_Mult_m which always works
158 * Returns: m*a1, newly allocated from r
159 *          if spNoether != NULL, then monoms whioch are smaller
160 *          then spNoether are cut
161 * Assume:  m is Monom
162 * Const: p, m
163 *
164 ***************************************************************/
165poly  pr_Mult_m_General(poly p,
166                       poly m, 
167                       poly spNoether,
168                       const ring ri)
169{
170  assume(ri != NULL);
171  assume(prTest(p, ri));
172 
173  if (p == NULL) return NULL;
174  spolyrec rp;
175  poly q = &rp, r;
176  number ln = pGetCoeff(m);
177
178  if (spNoether == NULL)
179  {
180    while (p != NULL)
181    {
182      pNext(q) = AllocHeapType(ri->mm_specHeap, poly);
183      q = pNext(q);
184      pSetCoeff0(q, nMult(ln, pGetCoeff(p)));
185      prMonAdd(q, p, m, ri);
186      p = pNext(p);
187    }
188  }
189  else
190  {
191    poly r;
192    while (p != NULL)
193    {
194      r = AllocHeapType(ri->mm_specHeap, poly);
195      prMonAdd(r, p, m, ri);
196
197      if (prComp0(r, spNoether, ri) == -1)
198      {
199        FreeHeap(r, ri->mm_specHeap);
200        break;
201      }
202      q = pNext(q) = r;
203      pSetCoeff0(q, nMult(ln, pGetCoeff(p)));
204      pIter(p);
205    }
206  }
207  pNext(q) = NULL;
208
209  assume(prTest(pNext(&rp), ri));
210
211  return pNext(&rp);
212}
213
214// #define TRACK_MEMORY
215
216/***************************************************************
217 *
218 * General:  pr_Minus_m_Mult_q which always works
219 * Return :  p - m*q, allocated from heap
220 * Assume:   p is from heap, m is Monom
221 *           *lp == NULL || pLength(p) == *lp && pLenth(q) == lq
222 * Destroy:  p
223 * Const:    m, q
224 *
225 ***************************************************************/
226poly pr_Minus_m_Mult_q_General (poly p, 
227                               poly m,
228                               poly q, 
229                               poly spNoether,
230                               int *lp,  int lq,
231                               const ring r)
232{
233#ifdef TRACK_MEMORY
234  mmMarkCurrentUsageState();
235  mmMarkCurrentUsageStop();
236  poly ptemp = pCopy(p);
237  pDelete(&p);
238  p = ptemp;
239#endif 
240  assume(prTest(p, r));
241  assume(prTest(q, r));
242  assume(lp == NULL || (pLength(p) == *lp && pLength(q) == lq));
243
244  // we are done if q == NULL || m == NULL
245  if (q == NULL || m == NULL) return p;
246 
247  spolyrec rp;
248  poly a = &rp,                       // collects the result
249       qm = NULL,                     // stores q*m
250       c;                             // used for temporary storage
251
252
253  number tm   = pGetCoeff(m),       // coefficient of m
254         tneg = nNeg(nCopy(tm)),    // - (coefficient of m)
255         tb,                        // used for tm*coeff(a1)
256         tc;                        // used as intermediate number
257
258
259  int l;
260  if (lp != NULL) l = *lp + lq;
261
262  if (p == NULL) goto Finish;       // we are done if p is 0
263 
264  qm = AllocHeapType(r->mm_specHeap,poly);
265  assume(pGetComp(q) == 0 || pGetComp(m) == 0);
266  prMonAdd(qm, q, m, r);
267 
268  // MAIN LOOP:
269  Top:     // compare qm = m*q and p w.r.t. monomial ordering
270  _prMonCmp(qm, p, r, goto Equal, goto Greater, goto Smaller);
271 
272  Equal:   // qm equals p
273  assume(prComp0(qm, p,r) == 0);
274    tb = nMult(pGetCoeff(q), tm);
275    tc = pGetCoeff(p);
276    if (!nEqual(tc, tb))
277    {
278      l--;
279      tc = nSub(tc, tb);
280      nDelete(&(pGetCoeff(p)));
281      pSetCoeff0(p,tc); // adjust coeff of p
282      a = pNext(a) = p; // append p to result and advance p
283      pIter(p);
284    }
285    else
286    { // coeffs are equal, so their difference is 0:
287      l -= 2;
288      nDelete(&tc);
289      prFree1AndAdvance(p, r);
290    }
291    nDelete(&tb);
292    pIter(q);
293    if (q == NULL || p == NULL) goto Finish; // are we done ?
294    // no, so update qm
295    assume(pGetComp(q) == 0 || pGetComp(m) == 0);
296    prMonAdd(qm, q, m, r);
297    goto Top;
298
299
300  Greater:
301    assume(prComp0(qm, p,r) == 1);
302      pSetCoeff0(qm,nMult(pGetCoeff(q), tneg));
303      a = pNext(a) = qm;       // append qm to result and advance q
304      pIter(q);
305      if (q == NULL) // are we done?
306      {
307        qm = NULL;
308        goto Finish; 
309      }
310      // construct new qm
311      qm = AllocHeapType(r->mm_specHeap,poly);
312      assume(pGetComp(q) == 0 || pGetComp(m) == 0);
313      prMonAdd(qm, q, m, r);
314      goto Top;
315   
316  Smaller:     
317      assume(prComp0(qm, p,r) == -1);
318      a = pNext(a) = p;// append p to result and advance p
319      pIter(p);
320      if (p == NULL) goto Finish;;
321      goto Top;
322 
323
324  Finish: // q or p is NULL: Clean-up time
325
326   if (q == NULL) // append rest of p to result
327     pNext(a) = p;
328   else  // append (- m*q) to result
329   {
330     pSetCoeff0(m, tneg);
331     pNext(a) = pr_Mult_m(q, m, spNoether, r);
332     pSetCoeff0(m, tm);
333   }
334   
335   nDelete(&tneg);
336   if (qm != NULL) FreeHeap(qm, r->mm_specHeap);
337   if (lp != NULL) *lp = l;
338   
339   assume(prTest(pNext(&rp), r));
340   assume(lp == NULL || pLength(pNext(&rp)) == l);
341   
342#ifdef TRACK_MEMORY
343   mmMarkCurrentUsageStart();
344   assume(prTest((pNext(&rp), heap));
345   mmPrintUnMarkedBlocks();
346   mmMarkCurrentUsageStop();
347#endif
348   
349  return pNext(&rp);
350} 
351
Note: See TracBrowser for help on using the repository browser.