source: git/Singular/prProcs.cc @ d04e5c6

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