source: git/libpolys/polys/templates/p_Minus_mm_Mult_qq__T.cc @ 014b65

spielwiese
Last change on this file since 014b65 was 014b65, checked in by Mohamed Barakat <mohamed.barakat@…>, 13 years ago
- moved misc,reporter,resources,coeffs,polys -> (new) libpolys (Hans agreed) - migrated to automake in coeffs, misc status: everything builds (except polys) todo: . migrate resources and reporter to automake . create autoconf macros for omalloc, factory, and libpolys
  • Property mode set to 100644
File size: 3.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    p_Minus_mm_Mult_qq__Template.cc
6 *  Purpose: template for p_Minus_m_Mult_q
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 8/00
9 *  Version: $Id$
10 *******************************************************************/
11
12/***************************************************************
13 *
14 * Returns:  p - m*q
15 *           Shorter, where Shorter == Length(p) + Length(q) - Length(p - m*q);
16 * Destroys: p
17 * Const:    m, q
18 *
19 ***************************************************************/
20LINKAGE poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int& Shorter, const poly spNoether, const ring r, poly &last)
21{
22  p_Test(p, r);
23  p_Test(q, r);
24  p_LmTest(m, r);
25
26#if PDEBUG > 0
27  int l_debug = pLength(p) + pLength(q);
28#endif
29
30  Shorter = 0;
31  // we are done if q == NULL || m == NULL
32  if (q == NULL || m == NULL) return p;
33
34  spolyrec rp;
35  poly a = &rp,                    // collects the result
36    qm = NULL;                     // stores q*m
37
38
39  number tm = pGetCoeff(m),           // coefficient of m
40    tneg = n_Neg(n_Copy(tm, r), r),    // - (coefficient of m)
41    tb,                            // used for tm*coeff(a1)
42    tc;                            // used as intermediate number
43
44
45  int shorter = 0;
46  DECLARE_LENGTH(const unsigned long length = r->ExpL_Size);
47  DECLARE_ORDSGN(const long* ordsgn = r->ordsgn);
48
49  const unsigned long* m_e = m->exp;
50  omBin bin = r->PolyBin;
51
52  if (p == NULL) goto Finish;           // return tneg*q if (p == NULL)
53
54  pAssume(p_GetComp(q, r) == 0 || p_GetComp(m, r) == 0);
55
56  AllocTop:
57  p_AllocBin(qm, bin, r);
58  SumTop:
59  p_MemSum(qm->exp, q->exp, m_e, length);
60  p_MemAddAdjust(qm, r);
61
62  CmpTop:
63  // compare qm = m*q and p w.r.t. monomial ordering
64  p_MemCmp(qm->exp, p->exp, length, ordsgn, goto Equal, goto Greater, goto Smaller );
65
66  Equal:   // qm equals p
67  tb = n_Mult(pGetCoeff(q), tm, r);
68#ifdef HAVE_ZERODIVISORS
69  if (!nIsZero(tb)) {
70#endif
71  tc = pGetCoeff(p);
72  if (!n_Equal(tc, tb, r))
73  {
74    shorter++;
75    tc = n_Sub(tc, tb, r);
76    n_Delete(&(pGetCoeff(p)), r);
77    pSetCoeff0(p,tc); // adjust coeff of p
78    a = pNext(a) = p; // append p to result and advance p
79    pIter(p);
80  }
81  else
82  { // coeffs are equal, so their difference is 0:
83    shorter += 2;
84    n_Delete(&tc, r);
85    p = p_LmFreeAndNext(p, r);
86  }
87#ifdef HAVE_ZERODIVISORS
88  }
89  else
90  { // coeff itself is zero
91    shorter += 1;
92  }
93#endif
94  n_Delete(&tb, r);
95  pIter(q);
96  if (q == NULL || p == NULL) goto Finish; // are we done ?
97  // no, so update qm
98  goto SumTop;
99
100
101  Greater:
102#ifdef HAVE_ZERODIVISORS
103  tb = n_Mult(pGetCoeff(q), tneg, r);
104  if (!nIsZero(tb))
105  {
106#endif
107    pSetCoeff0(qm, n_Mult(pGetCoeff(q), tneg, r));
108    a = pNext(a) = qm;       // append qm to result and advance q
109#ifdef HAVE_ZERODIVISORS
110  }
111  else
112  {
113    shorter++;
114  }
115  n_Delete(&tb, r);
116#endif
117  pIter(q);
118  if (q == NULL) // are we done?
119  {
120    qm = NULL;
121    goto Finish;
122  }
123  // construct new qm
124  goto AllocTop;
125
126  Smaller:
127  a = pNext(a) = p;// append p to result and advance p
128  pIter(p);
129  if (p == NULL) goto Finish;
130  goto CmpTop;
131
132
133  Finish: // q or p is NULL: Clean-up time
134  if (q == NULL) // append rest of p to result
135  {
136    pNext(a) = p;
137    if (p == NULL) last = a;
138  }
139  else  // append (- m*q) to result
140  {
141    pSetCoeff0(m, tneg);
142    last = a;
143    if (spNoether != NULL)
144    {
145      int ll = 0;
146      pNext(a) = r->p_Procs->pp_Mult_mm_Noether(q, m, spNoether, ll, r, last);
147      shorter += ll;
148    }
149    else
150    {
151      pNext(a) = r->p_Procs->pp_Mult_mm(q, m, r, last);
152#ifdef HAVE_RINGS
153      if (! rField_is_Domain(r))
154      {
155        shorter += pLength(q) - pLength(pNext(a));
156      }
157#endif
158    }
159    pSetCoeff0(m, tm);
160  }
161
162  n_Delete(&tneg, r);
163  if (qm != NULL) p_FreeBinAddr(qm, r);
164  Shorter = shorter;
165  p_Test(pNext(&rp), r);
166  return pNext(&rp);
167}
Note: See TracBrowser for help on using the repository browser.