source: git/kernel/p_Mult_q.cc @ 35aab3

spielwiese
Last change on this file since 35aab3 was 35aab3, checked in by Hans Schönemann <hannes@…>, 21 years ago
This commit was generated by cvs2svn to compensate for changes in r6879, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@6880 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    p_Mult_q.cc
6 *  Purpose: multiplication of polynomials
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id: p_Mult_q.cc,v 1.1.1.1 2003-10-06 12:16:00 Singular Exp $
10 *******************************************************************/
11#include "mod2.h"
12
13/***************************************************************
14 *
15 * Returns:  p * q,
16 * Destroys: if !copy then p, q
17 * Assumes: pLength(p) >= 2 pLength(q) >=2
18 ***************************************************************/
19#include "p_polys.h"
20#include "p_Procs.h"
21#include "p_Numbers.h"
22#include "kbuckets.h"
23
24#include "p_Mult_q.h"
25
26BOOLEAN pqLength(poly p, poly q, int &lp, int &lq, const int min)
27{
28  int l = 0;
29
30  do
31  {
32    if (p == NULL)
33    {
34      lp = l;
35      if (l < min)
36      {
37        if (q != NULL)
38          lq = l+1;
39        else
40          lq = l;
41        return FALSE;
42      }
43      lq = l + pLength(q);
44      return TRUE;
45    }
46    pIter(p);
47    if (q == NULL)
48    {
49      lq = l;
50      if (l < min)
51      {
52        lp = l+1;
53        return FALSE;
54      }
55      lp = l + 1 + pLength(p);
56      return TRUE;
57    }
58    pIter(q);
59    l++;
60  }
61  while (1);
62}
63
64
65static poly _p_Mult_q_Bucket(poly p, const int lp,
66                             poly q, const int lq,
67                             const int copy, const ring r)
68{
69  assume(p != NULL && pNext(p) != NULL && q != NULL && pNext(q) != NULL);
70  pAssume1(! pHaveCommonMonoms(p, q));
71  assume(lp >= 1 && lq >= 1);
72  p_Test(p, r);
73  p_Test(q, r);
74
75  poly res = pp_Mult_mm(p,q,r);     // holds initially q1*p
76  poly qq = pNext(q);               // we iter of this
77  poly qn = pp_Mult_mm(qq, p,r);    // holds p1*qi
78  poly pp = pNext(p);               // used for Lm(qq)*pp
79  poly rr = res;                    // last monom which is surely not NULL
80  poly rn = pNext(res);             // pNext(rr)
81  number n, n1;
82
83  kBucket_pt bucket = kBucketCreate(r);
84
85  // initialize bucket
86  kBucketInit(bucket, pNext(rn), lp - 2);
87  pNext(rn) = NULL;
88
89  // now the main loop
90  Top:
91  if (rn == NULL) goto Smaller;
92  p_LmCmpAction(rn, qn, r, goto Equal, goto Greater, goto Smaller);
93
94  Greater:
95  // rn > qn, so iter
96  rr = rn;
97  pNext(rn) = kBucketExtractLm(bucket);
98  pIter(rn);
99  goto Top;
100
101  // rn < qn, append qn to rr, and compute next Lm(qq)*pp
102  Smaller:
103  pNext(rr) = qn;
104  rr = qn;
105  pIter(qn);
106  Work: // compute res + Lm(qq)*pp
107  if (rn == NULL)
108  {
109    pNext(rr) = pp_Mult_mm(pp, qq, r);
110    kBucketInit(bucket, pNext(pNext(rr)), lp - 2);
111    pNext(pNext(rr)) = NULL;
112  }
113  else
114  {
115    kBucketSetLm(bucket, rn);
116    kBucket_Plus_mm_Mult_pp(bucket, qq, pp, lp - 1);
117    pNext(rr) = kBucketExtractLm(bucket);
118  }
119
120  pIter(qq);
121  if (qq == NULL) goto Finish;
122  rn = pNext(rr);
123  goto Top;
124
125  Equal:
126  n1 = pGetCoeff(rn);
127  n = n_Add(n1, pGetCoeff(qn), r);
128  n_Delete(&n1, r);
129  if (n_IsZero(n, r))
130  {
131    n_Delete(&n, r);
132    p_LmFree(rn, r);
133  }
134  else
135  {
136    pSetCoeff0(rn, n);
137    rr = rn;
138  }
139  rn = kBucketExtractLm(bucket);
140  n_Delete(&pGetCoeff(qn),r);
141  qn = p_LmFreeAndNext(qn, r);
142  goto Work;
143
144  Finish:
145  assume(rr != NULL && pNext(rr) != NULL);
146  pNext(pNext(rr)) = kBucketClear(bucket);
147  kBucketDestroy(&bucket);
148
149  if (!copy)
150  {
151    p_Delete(&p, r);
152    p_Delete(&q, r);
153  }
154  p_Test(res, r);
155  return res;
156}
157
158
159static poly _p_Mult_q_Normal(poly p, poly q, const int copy, const ring r)
160{
161  assume(p != NULL && pNext(p) != NULL && q != NULL && pNext(q) != NULL);
162  pAssume1(! pHaveCommonMonoms(p, q));
163  p_Test(p, r);
164  p_Test(q, r);
165
166  poly res = pp_Mult_mm(p,q,r);     // holds initially q1*p
167  poly qq = pNext(q);               // we iter of this
168  poly qn = pp_Mult_mm(qq, p,r);    // holds p1*qi
169  poly pp = pNext(p);               // used for Lm(qq)*pp
170  poly rr = res;                    // last monom which is surely not NULL
171  poly rn = pNext(res);             // pNext(rr)
172  number n, n1;
173
174  // now the main loop
175  Top:
176  if (rn == NULL) goto Smaller;
177  p_LmCmpAction(rn, qn, r, goto Equal, goto Greater, goto Smaller);
178
179  Greater:
180  // rn > qn, so iter
181  rr = rn;
182  pIter(rn);
183  goto Top;
184
185  // rn < qn, append qn to rr, and compute next Lm(qq)*pp
186  Smaller:
187  pNext(rr) = qn;
188  rr = qn;
189  pIter(qn);
190  Work: // compute res + Lm(qq)*pp
191  if (rn == NULL)
192    pNext(rr) = pp_Mult_mm(pp, qq, r);
193  else
194  {
195    pNext(rr) = p_Plus_mm_Mult_qq(rn, qq, pp, r);
196  }
197
198  pIter(qq);
199  if (qq == NULL) goto Finish;
200  rn = pNext(rr);
201  goto Top;
202
203  Equal:
204  n1 = pGetCoeff(rn);
205  n = n_Add(n1, pGetCoeff(qn), r);
206  n_Delete(&n1, r);
207  if (n_IsZero(n, r))
208  {
209    n_Delete(&n, r);
210    rn = p_LmFreeAndNext(rn, r);
211  }
212  else
213  {
214    pSetCoeff0(rn, n);
215    rr = rn;
216    pIter(rn);
217  }
218  n_Delete(&pGetCoeff(qn),r);
219  qn = p_LmFreeAndNext(qn, r);
220  goto Work;
221
222  Finish:
223  if (!copy)
224  {
225    p_Delete(&p, r);
226    p_Delete(&q, r);
227  }
228  p_Test(res, r);
229  return res;
230}
231
232
233poly _p_Mult_q(poly p, poly q, const int copy, const ring r)
234{
235  int lp, lq, l;
236  poly pt;
237
238  pqLength(p, q, lp, lq, MIN_LENGTH_BUCKET);
239
240  if (lp < lq)
241  {
242    pt = p;
243    p =  q;
244    q = pt;
245    l = lp;
246    lp = lq;
247    lq = l;
248  }
249  if (lq < MIN_LENGTH_BUCKET || TEST_OPT_NOT_BUCKETS)
250    return _p_Mult_q_Normal(p, q, copy, r);
251  else
252  {
253    assume(lp == pLength(p));
254    assume(lq == pLength(q));
255    return _p_Mult_q_Bucket(p, lp, q, lq, copy, r);
256  }
257}
Note: See TracBrowser for help on using the repository browser.