source: git/libpolys/polys/shiftop.cc @ 220277f

fieker-DuValspielwiese
Last change on this file since 220277f was 220277f, checked in by Karim Abou Zeid <karim23697@…>, 6 years ago
Support components in letterplace kernel multiplication
  • Property mode set to 100644
File size: 11.7 KB
RevLine 
[e9691e2]1#include "shiftop.h"
[dbbc24]2#include "templates/p_MemCopy.h"
[e9691e2]3
[dc0f002]4/* #define SHIFT_MULT_DEBUG */
[dce59cc]5/* #define SHIFT_MULT_COMPAT_MODE */
[e9691e2]6
7#ifdef SHIFT_MULT_DEBUG
8#include "../kernel/polys.h"
9#endif
10
11poly shift_pp_Mult_mm(poly p, const poly m, const ring ri)
12{
13#ifdef SHIFT_MULT_DEBUG
[a718906]14  PrintLn(); PrintS("shift_pp_Mult_mm: ("); p_wrp(p, ri, ri); PrintS(") * "); p_wrp(m, ri, ri);
[e9691e2]15#endif
16
[dbbc24]17  p_Test(p, ri);
18  p_LmTest(m, ri);
19  if (p == NULL)
20  {
21    return NULL;
22  }
[f5850b]23
[dbbc24]24  int lV = ri->isLPring;
25  poly _m = m; // temp hack because m is const
26#ifdef SHIFT_MULT_COMPAT_MODE
27  _m = p_Copy(_m, ri);
28  p_mLPUnShift(_m, ri);
29  p = p_Copy(p, ri);
30  poly pCopyHead = p; // used to delete p later
31  p_LPUnShift(p, ri);
32#else
[b00f8a]33  assume(p_mFirstVblock(_m, ri) <= 1);
34  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
[dbbc24]35#endif
36  // at this point _m and p are shifted to 1
37
38  spolyrec rp;
39  poly q = &rp; // we use p for iterating and q for the result
40  number mCoeff = pGetCoeff(_m);
41  omBin bin = ri->PolyBin;
42  pAssume(!n_IsZero(mCoeff, ri->cf));
43  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
44
[b00f8a]45  int mLength = p_mLastVblock(_m, ri) * lV;
[dbbc24]46  int *mExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
47  p_GetExpV(_m,mExpV,ri);
48  do
49  {
50    p_AllocBin(pNext(q), bin, ri);
51    pIter(q);
52    pSetCoeff0(q, n_Mult(mCoeff, pGetCoeff(p), ri->cf));
53
54    int *pExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
55    p_GetExpV(p, pExpV, ri);
[b00f8a]56    p_LPExpVappend(pExpV, mExpV, p_mLastVblock(p, ri) * lV, mLength, ri);
[dbbc24]57    p_MemCopy_LengthGeneral(q->exp, p->exp, ri->ExpL_Size); // otherwise q is not initialized correctly
58    p_SetExpV(q, pExpV, ri);
59    omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
60
61    pIter(p);
[f5850b]62  }
[dbbc24]63  while (p != NULL);
64  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
65  pNext(q) = NULL;
66#ifdef SHIFT_MULT_COMPAT_MODE
67  p_Delete(&_m, ri); // in this case we copied _m before
68  p_Delete(&pCopyHead, ri); // in this case we copied p before
[f5850b]69#endif
70#ifdef SHIFT_MULT_DEBUG
[dbbc24]71  PrintLn(); PrintS("shift_pp_Mult_mm result: "); p_wrp(pNext(&rp), ri, ri); PrintLn();
[f5850b]72#endif
[dbbc24]73  p_Test(pNext(&rp), ri);
74  return pNext(&rp);
[e9691e2]75}
76
77// destroys p
78poly shift_p_Mult_mm(poly p, const poly m, const ring ri)
79{
80#ifdef SHIFT_MULT_DEBUG
[a718906]81  PrintLn(); PrintS("shift_p_Mult_mm: ("); p_wrp(p, ri, ri); PrintS(") * "); p_wrp(m, ri, ri);
[e9691e2]82#endif
83
[dbbc24]84  p_Test(p, ri);
85  p_LmTest(m, ri);
86  pAssume(m != NULL);
87  assume(p!=NULL);
[f5850b]88
[dbbc24]89  int lV = ri->isLPring;
90  poly _m = m; // temp hack because m is const
91#ifdef SHIFT_MULT_COMPAT_MODE
92  _m = p_Copy(_m, ri);
93  p_mLPUnShift(_m, ri);
94  p_LPUnShift(p, ri);
95#else
[3a961a]96  assume(p_mFirstVblock(_m, ri) <= 1);
97  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
[dbbc24]98#endif
99  // at this point _m and p are shifted to 1
100
101  poly q = p; // we use p for iterating and q for the result
102  number mCoeff = pGetCoeff(_m);
103  number pCoeff;
104  pAssume(!n_IsZero(mCoeff, ri->cf));
105
[b00f8a]106  int mLength = p_mLastVblock(_m, ri) * lV;
[dbbc24]107  int *mExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
108  p_GetExpV(_m,mExpV,ri);
109  while (p != NULL)
110  {
111    pCoeff = pGetCoeff(p);
112    pSetCoeff0(p, n_Mult(mCoeff, pCoeff, ri->cf));
113    n_Delete(&pCoeff, ri->cf); // delete the old coeff
114
115    int *pExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
116    p_GetExpV(p,pExpV,ri);
[b00f8a]117    p_LPExpVappend(pExpV, mExpV, p_mLastVblock(p, ri) * lV, mLength, ri);
[dbbc24]118    p_SetExpV(p, pExpV, ri);
119    omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
120
121    pIter(p);
[f5850b]122  }
[dbbc24]123  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
124#ifdef SHIFT_MULT_COMPAT_MODE
125  p_Delete(&_m, ri); // in this case we copied _m before
[f5850b]126#endif
127#ifdef SHIFT_MULT_DEBUG
128  PrintLn(); PrintS("shift_p_Mult_mm result: "); p_wrp(q, ri, ri); PrintLn();
129#endif
[dbbc24]130  p_Test(q, ri);
[e9691e2]131  return q;
132}
133
134poly shift_pp_mm_Mult(poly p, const poly m, const ring ri)
135{
136#ifdef SHIFT_MULT_DEBUG
[a718906]137  PrintLn(); PrintS("shift_pp_mm_Mult: "); p_wrp(m, ri, ri); PrintS(" * ("); p_wrp(p, ri, ri); PrintS(")");
[e9691e2]138#endif
139
[a718906]140  p_Test(p, ri);
141  p_LmTest(m, ri);
142  if (p == NULL)
143  {
144    return NULL;
[f5850b]145  }
[a718906]146
147  int lV = ri->isLPring;
148  poly _m = m; // temp hack because m is const
149#ifdef SHIFT_MULT_COMPAT_MODE
150  _m = p_Copy(_m, ri);
151  p_mLPUnShift(_m, ri);
152  p = p_Copy(p, ri);
153  poly pCopyHead = p; // used to delete p later
154  p_LPUnShift(p, ri);
155#else
[3a961a]156  assume(p_mFirstVblock(_m, ri) <= 1);
157  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
[f5850b]158#endif
[a718906]159  // at this point _m and p are shifted to 1
[e9691e2]160
[a718906]161  spolyrec rp;
162  poly q = &rp; // we use p for iterating and q for the result
163  number mCoeff = pGetCoeff(_m);
164  omBin bin = ri->PolyBin;
165  pAssume(!n_IsZero(mCoeff, ri->cf));
166  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
[f5850b]167
[b00f8a]168  int mLength = p_mLastVblock(_m, ri) * lV;
[a718906]169  int *mExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
170  p_GetExpV(_m,mExpV,ri);
171  do
172  {
173    p_AllocBin(pNext(q), bin, ri);
174    pIter(q);
175    pSetCoeff0(q, n_Mult(mCoeff, pGetCoeff(p), ri->cf));
176
177    int *pExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
178    p_GetExpV(p, pExpV, ri);
[b00f8a]179    p_LPExpVprepend(pExpV, mExpV, p_mLastVblock(p, ri) * lV, mLength, ri);
[a718906]180    p_MemCopy_LengthGeneral(q->exp, p->exp, ri->ExpL_Size); // otherwise q is not initialized correctly
181    p_SetExpV(q, pExpV, ri);
182    omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
183
184    pIter(p);
185  }
186  while (p != NULL);
187  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
188  pNext(q) = NULL;
189#ifdef SHIFT_MULT_COMPAT_MODE
190  p_Delete(&_m, ri); // in this case we copied _m before
191  p_Delete(&pCopyHead, ri); // in this case we copied p before
192#endif
[f5850b]193#ifdef SHIFT_MULT_DEBUG
[a718906]194  PrintLn(); PrintS("shift_pp_mm_Mult result: "); p_wrp(pNext(&rp), ri, ri); PrintLn();
[f5850b]195#endif
[a718906]196  p_Test(pNext(&rp), ri);
197  return pNext(&rp);
[e9691e2]198}
199
200// destroys p
201poly shift_p_mm_Mult(poly p, const poly m, const ring ri)
202{
203#ifdef SHIFT_MULT_DEBUG
[a718906]204  PrintLn(); PrintS("shift_p_mm_Mult: "); p_wrp(m, ri, ri); PrintS(" * ("); p_wrp(p, ri, ri); PrintS(")");
[e9691e2]205#endif
206
[a718906]207  p_Test(p, ri);
208  p_LmTest(m, ri);
209  pAssume(m != NULL);
210  assume(p!=NULL);
[f5850b]211
[a718906]212  int lV = ri->isLPring;
213  poly _m = m; // temp hack because m is const
214#ifdef SHIFT_MULT_COMPAT_MODE
215  _m = p_Copy(_m, ri);
216  p_mLPUnShift(_m, ri);
217  p_LPUnShift(p, ri);
218#else
[3a961a]219  assume(p_mFirstVblock(_m, ri) <= 1);
220  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
[f5850b]221#endif
[a718906]222  // at this point _m and p are shifted to 1
[e9691e2]223
[a718906]224  poly q = p; // we use p for iterating and q for the result
225  number mCoeff = pGetCoeff(_m);
226  number pCoeff;
227  pAssume(!n_IsZero(mCoeff, ri->cf));
228
[b00f8a]229  int mLength = p_mLastVblock(_m, ri) * lV;
[a718906]230  int *mExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
231  p_GetExpV(_m,mExpV,ri);
232  while (p != NULL)
233  {
234    pCoeff = pGetCoeff(p);
235    pSetCoeff0(p, n_Mult(mCoeff, pCoeff, ri->cf));
236    n_Delete(&pCoeff, ri->cf); // delete the old coeff
[e9691e2]237
[a718906]238    int *pExpV = (int *) omAlloc0((ri->N+1)*sizeof(int));
239    p_GetExpV(p,pExpV,ri);
[b00f8a]240    p_LPExpVprepend(pExpV, mExpV, p_mLastVblock(p, ri) * lV, mLength, ri);
[a718906]241    p_SetExpV(p, pExpV, ri);
242    omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
243
244    pIter(p);
245  }
246  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
247#ifdef SHIFT_MULT_COMPAT_MODE
248  p_Delete(&_m, ri); // in this case we copied _m before
249#endif
[f5850b]250#ifdef SHIFT_MULT_DEBUG
[d91af4]251  PrintLn(); PrintS("shift_p_mm_Mult result: "); p_wrp(q, ri, ri); PrintLn();
[f5850b]252#endif
[a718906]253  p_Test(q, ri);
[e9691e2]254  return q;
255}
256
257// p - m*q destroys p
258poly shift_p_Minus_mm_Mult_qq(poly p, poly m, poly q, int& Shorter, const poly spNoether, const ring ri) {
259#ifdef SHIFT_MULT_DEBUG
[a718906]260  PrintLn(); PrintS("shift_p_Minus_mm_Mult_qq: "); p_wrp(p, ri, ri); PrintS(" - "); p_wrp(m, ri, ri); PrintS(" * "); p_wrp(q, ri, ri);
[e9691e2]261#endif
262
[f5850b]263  Shorter = pLength(p) + pLength(q);
[e9691e2]264
[f5850b]265  poly qq = p_Add_q(p, shift_pp_mm_Mult(q, p_Neg(p_Copy(m, ri), ri), ri), ri);
[e9691e2]266
[f5850b]267#ifdef SHIFT_MULT_DEBUG
268  PrintLn(); PrintS("shift_p_Minus_mm_Mult_qq result: "); p_wrp(qq, ri, ri); PrintLn();
269#endif
270  Shorter -= pLength(qq);
[e9691e2]271  return qq;
272}
[b11ff2]273
274// Unsupported Operation STUBs
275poly shift_pp_Mult_mm_Noether_STUB(poly p, const poly m, const poly spNoether, int &ll, const ring ri) {
[a718906]276  PrintLn(); WarnS("pp_Mult_mm_Noether is not supported yet by Letterplace. Ignoring spNoether and using pp_Mult_mm. This might lead to unexpected behavior.");
[b11ff2]277
278  int pLen = 0;
279  if (ll >= 0) {
280    pLen = pLength(p);
281  }
282
283  p = shift_pp_Mult_mm(p, m, ri);
284
285  if (ll >= 0) {
286    ll = pLen - pLength(p);
287  } else {
288    ll = pLength(p);
289  }
290
291  return p;
292}
293
294
295poly shift_pp_Mult_Coeff_mm_DivSelectMult_STUB(poly p,const poly m, const poly a, const poly b, int &shorter,const ring r) {
[519191]296  PrintLn(); WarnS("pp_Mult_Coeff_mm_DivSelectMult is not supported yet by Letterplace. This might lead to unexpected behavior.");
[b11ff2]297  return NULL;
298}
299
300poly shift_pp_Mult_Coeff_mm_DivSelect_STUB(poly p, const poly m, int &shorter, const ring r) {
[519191]301  PrintLn(); WarnS("pp_Mult_Coeff_mm_DivSelect is not supported yet by Letterplace. This might lead to unexpected behavior.");
[b11ff2]302  return NULL;
303}
[dbbc24]304
305// auxiliary
306
307// unshifts the monomial m
308void p_mLPUnShift(poly m, const ring ri)
309{
[220277f]310  if (m == NULL || p_LmIsConstantComp(m,ri)) return;
[dbbc24]311
312  int lV = ri->isLPring;
313
[b00f8a]314  int shift = p_mFirstVblock(m, ri) - 1;
[dbbc24]315
316  if (shift == 0) return;
317
[b00f8a]318  int L = p_mLastVblock(m, ri);
[dbbc24]319
320  int *e=(int *)omAlloc0((ri->N+1)*sizeof(int));
321  int *s=(int *)omAlloc0((ri->N+1)*sizeof(int));
322  p_GetExpV(m, e, ri);
323
324  int expVoffset = shift*lV;
[a718906]325  for (int i = 1 + expVoffset; i <= L*lV; ++i)
[dbbc24]326  {
327    assume(e[i] <= 1);
328    s[i - expVoffset] = e[i];
329  }
330  p_SetExpV(m,s,ri);
331  omFreeSize((ADDRESS) e, (ri->N+1)*sizeof(int));
332  omFreeSize((ADDRESS) s, (ri->N+1)*sizeof(int));
333}
334
335// unshifts the polynomial p, note: the ordering can be destroyed if the shifts for the monomials are not equal
336void p_LPUnShift(poly p, const ring ri)
337{
338  while (p!=NULL)
339  {
340    p_mLPUnShift(p, ri);
341    pIter(p);
342  }
343  p_Test(p, ri); // check if ordering was destroyed
344}
345
[a718906]346// appends m2ExpV to m1ExpV where m1Last is the last Vblock of m1 and m2Last the last Vblock of m2
[220277f]347// also adds their components (one of them is always zero)
[a718906]348void p_LPExpVappend(int *m1ExpV, int *m2ExpV, int m1Length, int m2Length, const ring ri) {
[dbbc24]349#ifdef SHIFT_MULT_DEBUG
[a718906]350  PrintLn(); PrintS("Append");
351  PrintLn(); WriteLPExpV(m1ExpV, ri);
352  PrintLn(); WriteLPExpV(m2ExpV, ri);
[dbbc24]353#endif
[a718906]354  assume(m1Length + m2Length <= ri->N);
355  for (int i = 1 + m1Length; i < 1 + m1Length + m2Length; ++i)
[dbbc24]356  {
[a718906]357    assume(m2ExpV[i - m1Length] <= 1);
358    m1ExpV[i] = m2ExpV[i - m1Length];
359  }
[220277f]360
361  assume(m1ExpV[0] == 0 || m2ExpV[0] == 0); // one component should be zero (otherwise this doesn't make any sense)
362  m1ExpV[0] += m2ExpV[0]; // as in the commutative variant (they use MemAdd)
[a718906]363#ifdef SHIFT_MULT_DEBUG
364  PrintLn(); WriteLPExpV(m1ExpV, ri);
365#endif
366}
367
368// prepends m2ExpV to m1ExpV where m1Last is the last Vblock of m1 and m2Last the last Vblock of m2
[220277f]369// also adds their components (one of them is always zero)
[a718906]370void p_LPExpVprepend(int *m1ExpV, int *m2ExpV, int m1Length, int m2Length, const ring ri) {
371#ifdef SHIFT_MULT_DEBUG
372  PrintLn(); PrintS("Prepend");
373  PrintLn(); WriteLPExpV(m1ExpV, ri);
374  PrintLn(); WriteLPExpV(m2ExpV, ri);
375#endif
376  assume(m1Length + m2Length <= ri->N);
377
378  // save m1
379  int *m1Tmp=(int *)omAlloc0((m1Length+1)*sizeof(int));
380  for (int i = 1; i < 1 + m1Length; ++i) {
381    m1Tmp[i] = m1ExpV[i];
382  }
383
384  // write m2 to m1
385  for (int i = 1; i < 1 + m2Length; ++i)
386  {
387    assume(m2ExpV[i] <= 1);
388    m1ExpV[i] = m2ExpV[i];
389  }
390  // then append m1 again
391  for (int i = 1 + m2Length; i < 1 + m2Length + m1Length; ++i) {
392    m1ExpV[i] = m1Tmp[i - m2Length];
[dbbc24]393  }
[a718906]394  omFreeSize((ADDRESS) m1Tmp, (m1Length+1)*sizeof(int));
[220277f]395
396  assume(m1ExpV[0] == 0 || m2ExpV[0] == 0); // one component should be zero (otherwise this doesn't make any sense)
397  m1ExpV[0] += m2ExpV[0]; // as in the commutative variant (they use MemAdd)
[dbbc24]398#ifdef SHIFT_MULT_DEBUG
[a718906]399  PrintLn(); WriteLPExpV(m1ExpV, ri);
[dbbc24]400#endif
401}
402
403void WriteLPExpV(int *expV, ring ri) {
[a718906]404  for (int i = 0; i <= ri->N; ++i) {
[dbbc24]405    Print("%d", expV[i]);
406    if (i == 0) {
407      Print("| ");
408    }
409    if (i % ri->isLPring == 0) {
410      Print(" ");
411    }
412  }
413}
Note: See TracBrowser for help on using the repository browser.