source: git/libpolys/polys/shiftop.cc @ 4819c4

spielwiese
Last change on this file since 4819c4 was 4819c4, checked in by Hans Schoenemann <hannes@…>, 5 years ago
moved freeAlgebra construction to kernel (libpolys/polys/shiftop)
  • Property mode set to 100644
File size: 19.0 KB
Line 
1#include "shiftop.h"
2
3#ifdef HAVE_SHIFTBBA
4
5#include "templates/p_MemCopy.h"
6#include "monomials/p_polys.h"
7#include "polys/simpleideals.h"
8
9/* #define SHIFT_MULT_DEBUG */
10
11/* enable compat mode until the user interface is updated to support xy instead of x(1)*y(2)
12 * NOTE: it already works, but all tests and the libraries need to be updated first
13 * -> wait until the new interface is released
14*/
15#define SHIFT_MULT_COMPAT_MODE
16
17#ifdef SHIFT_MULT_DEBUG
18#include "../kernel/polys.h"
19#endif
20
21poly shift_pp_Mult_mm(poly p, const poly m, const ring ri)
22{
23#ifdef SHIFT_MULT_DEBUG
24  PrintLn(); PrintS("shift_pp_Mult_mm: ("); p_wrp(p, ri, ri); PrintS(") * "); p_wrp(m, ri, ri);
25#endif
26
27  p_Test(p, ri);
28  p_LmTest(m, ri);
29  if (p == NULL)
30  {
31    return NULL;
32  }
33
34  int lV = ri->isLPring;
35  poly _m = m; // temp hack because m is const
36#ifdef SHIFT_MULT_COMPAT_MODE
37  _m = p_Copy(_m, ri);
38  p_mLPunshift(_m, ri);
39  p = p_Copy(p, ri);
40  poly pCopyHead = p; // used to delete p later
41  p_LPunshift(p, ri);
42#else
43  assume(p_mFirstVblock(_m, ri) <= 1);
44  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
45#endif
46  // at this point _m and p are shifted to 1
47
48  spolyrec rp;
49  poly q = &rp; // we use p for iterating and q for the result
50  number mCoeff = pGetCoeff(_m);
51  omBin bin = ri->PolyBin;
52  pAssume(!n_IsZero(mCoeff, ri->cf));
53  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
54
55  int *mExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
56  p_GetExpV(_m,mExpV,ri);
57  int mLength = p_mLastVblock(_m, mExpV, ri) * lV;
58  int *pExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
59  do
60  {
61    p_AllocBin(pNext(q), bin, ri);
62    pIter(q);
63    pSetCoeff0(q, n_Mult(mCoeff, pGetCoeff(p), ri->cf));
64
65    p_GetExpV(p, pExpV, ri);
66    p_LPExpVappend(pExpV, mExpV, p_mLastVblock(p, pExpV, ri) * lV, mLength, ri);
67    p_MemCopy_LengthGeneral(q->exp, p->exp, ri->ExpL_Size); // otherwise q is not initialized correctly
68    p_SetExpV(q, pExpV, ri);
69
70    pIter(p);
71  }
72  while (p != NULL);
73  omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
74  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
75  pNext(q) = NULL;
76#ifdef SHIFT_MULT_COMPAT_MODE
77  p_Delete(&_m, ri); // in this case we copied _m before
78  p_Delete(&pCopyHead, ri); // in this case we copied p before
79#endif
80#ifdef SHIFT_MULT_DEBUG
81  PrintLn(); PrintS("shift_pp_Mult_mm result: "); p_wrp(pNext(&rp), ri, ri); PrintLn();
82#endif
83  p_Test(pNext(&rp), ri);
84  return pNext(&rp);
85}
86
87// destroys p
88poly shift_p_Mult_mm(poly p, const poly m, const ring ri)
89{
90#ifdef SHIFT_MULT_DEBUG
91  PrintLn(); PrintS("shift_p_Mult_mm: ("); p_wrp(p, ri, ri); PrintS(") * "); p_wrp(m, ri, ri);
92#endif
93
94  p_Test(p, ri);
95  p_LmTest(m, ri);
96  pAssume(m != NULL);
97  assume(p!=NULL);
98
99  int lV = ri->isLPring;
100  poly _m = m; // temp hack because m is const
101#ifdef SHIFT_MULT_COMPAT_MODE
102  _m = p_Copy(_m, ri);
103  p_mLPunshift(_m, ri);
104  p_LPunshift(p, ri);
105#else
106  assume(p_mFirstVblock(_m, ri) <= 1);
107  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
108#endif
109  // at this point _m and p are shifted to 1
110
111  poly q = p; // we use p for iterating and q for the result
112  number mCoeff = pGetCoeff(_m);
113  number pCoeff;
114  pAssume(!n_IsZero(mCoeff, ri->cf));
115
116  int *mExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
117  p_GetExpV(_m,mExpV,ri);
118  int mLength = p_mLastVblock(_m, mExpV, ri) * lV;
119  int *pExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
120  while (p != NULL)
121  {
122    pCoeff = pGetCoeff(p);
123    pSetCoeff0(p, n_Mult(mCoeff, pCoeff, ri->cf));
124    n_Delete(&pCoeff, ri->cf); // delete the old coeff
125
126    p_GetExpV(p,pExpV,ri);
127    p_LPExpVappend(pExpV, mExpV, p_mLastVblock(p, pExpV, ri) * lV, mLength, ri);
128    p_SetExpV(p, pExpV, ri);
129
130    pIter(p);
131  }
132  omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
133  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
134#ifdef SHIFT_MULT_COMPAT_MODE
135  p_Delete(&_m, ri); // in this case we copied _m before
136#endif
137#ifdef SHIFT_MULT_DEBUG
138  PrintLn(); PrintS("shift_p_Mult_mm result: "); p_wrp(q, ri, ri); PrintLn();
139#endif
140  p_Test(q, ri);
141  return q;
142}
143
144poly shift_pp_mm_Mult(poly p, const poly m, const ring ri)
145{
146#ifdef SHIFT_MULT_DEBUG
147  PrintLn(); PrintS("shift_pp_mm_Mult: "); p_wrp(m, ri, ri); PrintS(" * ("); p_wrp(p, ri, ri); PrintS(")");
148#endif
149
150  p_Test(p, ri);
151  p_LmTest(m, ri);
152  if (p == NULL)
153  {
154    return NULL;
155  }
156
157  int lV = ri->isLPring;
158  poly _m = m; // temp hack because m is const
159#ifdef SHIFT_MULT_COMPAT_MODE
160  _m = p_Copy(_m, ri);
161  p_mLPunshift(_m, ri);
162  p = p_Copy(p, ri);
163  poly pCopyHead = p; // used to delete p later
164  p_LPunshift(p, ri);
165#else
166  assume(p_mFirstVblock(_m, ri) <= 1);
167  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
168#endif
169  // at this point _m and p are shifted to 1
170
171  spolyrec rp;
172  poly q = &rp; // we use p for iterating and q for the result
173  number mCoeff = pGetCoeff(_m);
174  omBin bin = ri->PolyBin;
175  pAssume(!n_IsZero(mCoeff, ri->cf));
176  pAssume1(p_GetComp(m, ri) == 0 || p_MaxComp(p, ri) == 0);
177
178  int *mExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
179  p_GetExpV(_m,mExpV,ri);
180  int mLength = p_mLastVblock(_m, mExpV, ri) * lV;
181  int *pExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
182  do
183  {
184    p_AllocBin(pNext(q), bin, ri);
185    pIter(q);
186    pSetCoeff0(q, n_Mult(mCoeff, pGetCoeff(p), ri->cf));
187
188    p_GetExpV(p, pExpV, ri);
189    p_LPExpVprepend(pExpV, mExpV, p_mLastVblock(p, pExpV, ri) * lV, mLength, ri);
190    p_MemCopy_LengthGeneral(q->exp, p->exp, ri->ExpL_Size); // otherwise q is not initialized correctly
191    p_SetExpV(q, pExpV, ri);
192
193    pIter(p);
194  }
195  while (p != NULL);
196  omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
197  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
198  pNext(q) = NULL;
199#ifdef SHIFT_MULT_COMPAT_MODE
200  p_Delete(&_m, ri); // in this case we copied _m before
201  p_Delete(&pCopyHead, ri); // in this case we copied p before
202#endif
203#ifdef SHIFT_MULT_DEBUG
204  PrintLn(); PrintS("shift_pp_mm_Mult result: "); p_wrp(pNext(&rp), ri, ri); PrintLn();
205#endif
206  p_Test(pNext(&rp), ri);
207  return pNext(&rp);
208}
209
210// destroys p
211poly shift_p_mm_Mult(poly p, const poly m, const ring ri)
212{
213#ifdef SHIFT_MULT_DEBUG
214  PrintLn(); PrintS("shift_p_mm_Mult: "); p_wrp(m, ri, ri); PrintS(" * ("); p_wrp(p, ri, ri); PrintS(")");
215#endif
216
217  p_Test(p, ri);
218  p_LmTest(m, ri);
219  pAssume(m != NULL);
220  assume(p!=NULL);
221
222  int lV = ri->isLPring;
223  poly _m = m; // temp hack because m is const
224#ifdef SHIFT_MULT_COMPAT_MODE
225  _m = p_Copy(_m, ri);
226  p_mLPunshift(_m, ri);
227  p_LPunshift(p, ri);
228#else
229  assume(p_mFirstVblock(_m, ri) <= 1);
230  assume(p_FirstVblock(p, ri) <= 1); // TODO check that each block is <=1
231#endif
232  // at this point _m and p are shifted to 1
233
234  poly q = p; // we use p for iterating and q for the result
235  number mCoeff = pGetCoeff(_m);
236  number pCoeff;
237  pAssume(!n_IsZero(mCoeff, ri->cf));
238
239  int *mExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
240  p_GetExpV(_m,mExpV,ri);
241  int mLength = p_mLastVblock(_m, mExpV, ri) * lV;
242  int *pExpV = (int *) omAlloc((ri->N+1)*sizeof(int));
243  while (p != NULL)
244  {
245    pCoeff = pGetCoeff(p);
246    pSetCoeff0(p, n_Mult(mCoeff, pCoeff, ri->cf));
247    n_Delete(&pCoeff, ri->cf); // delete the old coeff
248
249    p_GetExpV(p,pExpV,ri);
250    p_LPExpVprepend(pExpV, mExpV, p_mLastVblock(p, pExpV, ri) * lV, mLength, ri);
251    p_SetExpV(p, pExpV, ri);
252
253    pIter(p);
254  }
255  omFreeSize((ADDRESS) pExpV, (ri->N+1)*sizeof(int));
256  omFreeSize((ADDRESS) mExpV, (ri->N+1)*sizeof(int));
257#ifdef SHIFT_MULT_COMPAT_MODE
258  p_Delete(&_m, ri); // in this case we copied _m before
259#endif
260#ifdef SHIFT_MULT_DEBUG
261  PrintLn(); PrintS("shift_p_mm_Mult result: "); p_wrp(q, ri, ri); PrintLn();
262#endif
263  p_Test(q, ri);
264  return q;
265}
266
267// p - m*q destroys p
268poly shift_p_Minus_mm_Mult_qq(poly p, poly m, poly q, int& Shorter, const poly spNoether, const ring ri) {
269#ifdef SHIFT_MULT_DEBUG
270  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);
271#endif
272
273  Shorter = pLength(p) + pLength(q);
274
275  poly qq = p_Add_q(p, shift_pp_mm_Mult(q, p_Neg(p_Copy(m, ri), ri), ri), ri);
276
277#ifdef SHIFT_MULT_DEBUG
278  PrintLn(); PrintS("shift_p_Minus_mm_Mult_qq result: "); p_wrp(qq, ri, ri); PrintLn();
279#endif
280  Shorter -= pLength(qq);
281  return qq;
282}
283
284// Unsupported Operation STUBs
285poly shift_pp_Mult_mm_Noether_STUB(poly p, const poly m, const poly spNoether, int &ll, const ring ri) {
286  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.");
287
288  int pLen = 0;
289  if (ll >= 0)
290  {
291    pLen = pLength(p);
292  }
293
294  p = shift_pp_Mult_mm(p, m, ri);
295
296  if (ll >= 0)
297  {
298    ll = pLen - pLength(p);
299  }
300  else
301  {
302    ll = pLength(p);
303  }
304
305  return p;
306}
307
308
309poly shift_pp_Mult_Coeff_mm_DivSelectMult_STUB(poly p,const poly m, const poly a, const poly b, int &shorter,const ring r) {
310  PrintLn(); WarnS("pp_Mult_Coeff_mm_DivSelectMult is not supported yet by Letterplace. This might lead to unexpected behavior.");
311  return NULL;
312}
313
314poly shift_pp_Mult_Coeff_mm_DivSelect_STUB(poly p, const poly m, int &shorter, const ring r) {
315  PrintLn(); WarnS("pp_Mult_Coeff_mm_DivSelect is not supported yet by Letterplace. This might lead to unexpected behavior.");
316  return NULL;
317}
318
319// auxiliary
320
321// unshifts the monomial m
322void p_mLPunshift(poly m, const ring ri)
323{
324  if (m == NULL || p_LmIsConstantComp(m,ri)) return;
325
326  int lV = ri->isLPring;
327
328  int shift = p_mFirstVblock(m, ri) - 1;
329
330  if (shift == 0) return;
331
332  int *e=(int *)omAlloc((ri->N+1)*sizeof(int));
333  int *s=(int *)omAlloc0((ri->N+1)*sizeof(int));
334  p_GetExpV(m, e, ri);
335
336  int expVoffset = shift*lV;
337  for (int i = 1 + expVoffset; i <= ri->N; i++)
338  {
339    assume(e[i] <= 1);
340    s[i - expVoffset] = e[i];
341  }
342  p_SetExpV(m,s,ri);
343  omFreeSize((ADDRESS) e, (ri->N+1)*sizeof(int));
344  omFreeSize((ADDRESS) s, (ri->N+1)*sizeof(int));
345}
346
347// unshifts the polynomial p, note: the ordering can be destroyed if the shifts for the monomials are not equal
348void p_LPunshift(poly p, const ring ri)
349{
350  while (p!=NULL)
351  {
352    p_mLPunshift(p, ri);
353    pIter(p);
354  }
355}
356
357void p_mLPshift(poly m, int sh, const ring ri)
358{
359  if (sh == 0 || m == NULL || p_LmIsConstantComp(m,ri)) return;
360
361  int lV = ri->isLPring;
362
363  assume(p_mFirstVblock(m,ri) + sh >= 1);
364  assume(p_mLastVblock(m,ri) + sh <= ri->N/lV);
365
366  int *e=(int *)omAlloc((ri->N+1)*sizeof(int));
367  int *s=(int *)omAlloc0((ri->N+1)*sizeof(int));
368  p_GetExpV(m,e,ri);
369
370  for (int i = ri->N - sh*lV; i > 0; i--)
371  {
372    assume(e[i]<=1);
373    if (e[i]==1)
374    {
375      s[i + (sh*lV)] = e[i]; /* actually 1 */
376    }
377  }
378  p_SetExpV(m,s,ri);
379  omFreeSize((ADDRESS) e, (ri->N+1)*sizeof(int));
380  omFreeSize((ADDRESS) s, (ri->N+1)*sizeof(int));
381}
382
383void p_LPshift(poly p, int sh, const ring ri)
384{
385  if (sh == 0) return;
386
387  while (p!=NULL)
388  {
389    p_mLPshift(p, sh, ri);
390    pIter(p);
391  }
392}
393
394/* returns the number of maximal block */
395/* appearing among the monomials of p */
396/* the 0th block is the 1st one */
397int p_LastVblock(poly p, const ring r)
398{
399  poly q = p;
400  int ans = 0;
401  while (q!=NULL)
402  {
403    int ansnew = p_mLastVblock(q, r);
404    ans    = si_max(ans,ansnew);
405    pIter(q);
406  }
407  return(ans);
408}
409
410/* for a monomial p, returns the number of the last block */
411/* where a nonzero exponent is sitting */
412int p_mLastVblock(poly p, const ring ri)
413{
414  if (p == NULL || p_LmIsConstantComp(p,ri))
415  {
416    return(0);
417  }
418
419  int *e=(int *)omAlloc((ri->N+1)*sizeof(int));
420  p_GetExpV(p,e,ri);
421  int b = p_mLastVblock(p, e, ri);
422  omFreeSize((ADDRESS) e, (ri->N+1)*sizeof(int));
423  return b;
424}
425
426/* for a monomial p with exponent vector expV, returns the number of the last block */
427/* where a nonzero exponent is sitting */
428int p_mLastVblock(poly p, int *expV, const ring ri)
429{
430  if (p == NULL || p_LmIsConstantComp(p,ri))
431  {
432    return(0);
433  }
434
435  int lV = ri->isLPring;
436  int j,b;
437  j = ri->N;
438  while ( (!expV[j]) && (j>=1) ) j--;
439  assume(j>0);
440  b = (int)((j+lV-1)/lV); /* the number of the block, >=1 */
441  return b;
442}
443
444/* returns the number of maximal block */
445/* appearing among the monomials of p */
446/* the 0th block is the 1st one */
447int p_FirstVblock(poly p, const ring r)
448{
449  if (p == NULL) {
450    return 0;
451  }
452
453  poly q = p;
454  int ans = p_mFirstVblock(q, r);
455  while (q!=NULL)
456  {
457    int ansnew = p_mFirstVblock(q, r);
458    if (ansnew > 0) { // don't count constants
459      ans = si_min(ans,ansnew);
460    }
461    pIter(q);
462  }
463  /* do not need to delete q */
464  return(ans);
465}
466
467/* for a monomial p, returns the number of the first block */
468/* where a nonzero exponent is sitting */
469int p_mFirstVblock(poly p, const ring ri)
470{
471  if (p == NULL || p_LmIsConstantComp(p,ri))
472  {
473    return(0);
474  }
475
476  int *e=(int *)omAlloc((ri->N+1)*sizeof(int));
477  p_GetExpV(p,e,ri);
478  int b = p_mFirstVblock(p, e, ri);
479  omFreeSize((ADDRESS) e, (ri->N+1)*sizeof(int));
480  return b;
481}
482
483/* for a monomial p with exponent vector expV, returns the number of the first block */
484/* where a nonzero exponent is sitting */
485int p_mFirstVblock(poly p, int *expV, const ring ri)
486{
487  if (p == NULL || p_LmIsConstantComp(p,ri))
488  {
489    return(0);
490  }
491
492  int lV = ri->isLPring;
493  int j,b;
494  j = 1;
495  while ( (!expV[j]) && (j<=ri->N-1) ) j++;
496  assume(j <= ri->N);
497  b = (int)(j+lV-1)/lV; /* the number of the block, 1<= b <= r->N  */
498  return b;
499}
500
501// appends m2ExpV to m1ExpV, also adds their components (one of them is always zero)
502void p_LPExpVappend(int *m1ExpV, int *m2ExpV, int m1Length, int m2Length, const ring ri) {
503#ifdef SHIFT_MULT_DEBUG
504  PrintLn(); PrintS("Append");
505  PrintLn(); WriteLPExpV(m1ExpV, ri);
506  PrintLn(); WriteLPExpV(m2ExpV, ri);
507#endif
508  assume(m1Length + m2Length <= ri->N); // always throw an error?
509  for (int i = 1 + m1Length; i < 1 + m1Length + m2Length; ++i)
510  {
511    assume(m2ExpV[i - m1Length] <= 1);
512    m1ExpV[i] = m2ExpV[i - m1Length];
513  }
514
515  assume(m1ExpV[0] == 0 || m2ExpV[0] == 0); // one component should be zero (otherwise this doesn't make any sense)
516  m1ExpV[0] += m2ExpV[0]; // as in the commutative variant (they use MemAdd)
517#ifdef SHIFT_MULT_DEBUG
518  PrintLn(); WriteLPExpV(m1ExpV, ri);
519#endif
520}
521
522// prepends m2ExpV to m1ExpV, also adds their components (one of them is always zero)
523void p_LPExpVprepend(int *m1ExpV, int *m2ExpV, int m1Length, int m2Length, const ring ri)
524{
525#ifdef SHIFT_MULT_DEBUG
526  PrintLn(); PrintS("Prepend");
527  PrintLn(); WriteLPExpV(m1ExpV, ri);
528  PrintLn(); WriteLPExpV(m2ExpV, ri);
529#endif
530  assume(m1Length + m2Length <= ri->N); // always throw an error?
531
532  // shift m1 by m2Length
533  for (int i = m2Length + m1Length; i >= 1 + m2Length; --i)
534  {
535    m1ExpV[i] = m1ExpV[i - m2Length];
536  }
537
538  // write m2 to m1
539  for (int i = 1; i < 1 + m2Length; ++i)
540  {
541    assume(m2ExpV[i] <= 1);
542    m1ExpV[i] = m2ExpV[i];
543  }
544
545  assume(m1ExpV[0] == 0 || m2ExpV[0] == 0); // one component should be zero (otherwise this doesn't make any sense)
546  m1ExpV[0] += m2ExpV[0]; // as in the commutative variant (they use MemAdd)
547#ifdef SHIFT_MULT_DEBUG
548  PrintLn(); WriteLPExpV(m1ExpV, ri);
549#endif
550}
551
552void WriteLPExpV(int *expV, ring ri)
553{
554  char *s = LPExpVString(expV, ri);
555  PrintS(s);
556  omFree(s);
557}
558
559char* LPExpVString(int *expV, ring ri)
560{
561  StringSetS("");
562  for (int i = 0; i <= ri->N; ++i)
563  {
564    StringAppend("%d", expV[i]);
565    if (i == 0)
566    {
567      StringAppendS("| ");
568    }
569    if (i % ri->isLPring == 0)
570    {
571      StringAppendS(" ");
572    }
573  }
574  return StringEndS();
575}
576
577/* tests whether each polynomial of an ideal I lies in in V */
578int id_IsInV(ideal I, const ring r)
579{
580  int i;
581  int s    = IDELEMS(I)-1;
582  for(i = 0; i <= s; i++)
583  {
584    if ( !p_IsInV(I->m[i], r) )
585    {
586      return(0);
587    }
588  }
589  return(1);
590}
591
592/* tests whether the whole polynomial p in in V */
593int p_IsInV(poly p, const ring r)
594{
595  poly q = p;
596  while (q!=NULL)
597  {
598    if ( !p_mIsInV(q, r) )
599    {
600      return(0);
601    }
602    q = pNext(q);
603  }
604  return(1);
605}
606
607/* there should be two routines: */
608/* 1. test place-squarefreeness: in homog this suffices: isInV */
609/* 2. test the presence of a hole -> in the tail??? */
610
611int p_mIsInV(poly p, const ring r)
612{
613  int lV = r->isLPring;
614  /* investigate only the leading monomial of p in currRing */
615  if ( p_Totaldegree(p, r)==0 ) return(1);
616  /* returns 1 iff p is in V */
617  /* that is in each block up to a certain one there is only one nonzero exponent */
618  /* lV = the length of V = the number of orig vars */
619  int *e = (int *)omAlloc((r->N+1)*sizeof(int));
620  int  b = (int)((r->N+lV-1)/lV); /* the number of blocks */
621  //int b  = (int)(currRing->N)/lV;
622  int *B = (int *)omAlloc0((b+1)*sizeof(int)); /* the num of elements in a block */
623  p_GetExpV(p,e,r);
624  int i,j;
625  for (j=1; j<=b; j++)
626  {
627    /* we go through all the vars */
628    /* by blocks in lV vars */
629    for (i=(j-1)*lV + 1; i<= j*lV; i++)
630    {
631      if (e[i]) B[j] = B[j]+1;
632    }
633  }
634  //  j = b;
635  //  while ( (!B[j]) && (j>=1)) j--;
636  for (j=b; j>=1; j--)
637  {
638    if (B[j]!=0) break;
639  }
640  /* do not need e anymore */
641  omFreeSize((ADDRESS) e, (r->N+1)*sizeof(int));
642
643  if (j==0) goto ret_true;
644//   {
645//     /* it is a zero exp vector, which is in V */
646//     freeT(B, b);
647//     return(1);
648//   }
649  /* now B[j] != 0 and we test place-squarefreeness */
650  for (; j>=1; j--)
651  {
652    if (B[j]!=1)
653    {
654      omFreeSize((ADDRESS) B, (b+1)*sizeof(int));
655      return(0);
656    }
657  }
658 ret_true:
659  omFreeSize((ADDRESS) B, (b+1)*sizeof(int));
660  return(1);
661}
662
663ring freeAlgebra(ring r, int d)
664{
665  ring R=rCopy0(r);
666  int p;
667  if((r->order[0]==ringorder_C)
668  ||(r->order[0]==ringorder_c))
669    p=1;
670  else
671    p=0;
672  // create R->N
673  R->N=r->N*d;
674  R->isLPring=r->N;
675  R->block1[p]=R->N; /* only dp,Dp,wp,Wp; will be discarded for lp*/
676  // create R->order
677  switch(r->order[p])
678  {
679    case ringorder_dp:
680    case ringorder_Dp:
681      break;
682    case ringorder_wp:
683    case ringorder_Wp:
684    {
685      omFree(R->wvhdl[p]);
686      int *w=(int*)omAlloc(R->N*sizeof(int));
687      for(int b=1;b<d;b++)
688      {
689        for(int i=r->N-1;i>=0;i--)
690          w[b*r->N+i]=r->wvhdl[p][i];
691      }
692      R->wvhdl[p]=w;
693      break;
694    }
695    case ringorder_lp:
696    case ringorder_rp:
697    {
698      int ** wvhdl=(int**)omAlloc0((r->N+2)*sizeof(int*));
699      rRingOrder_t* ord=(rRingOrder_t*)omAlloc0((r->N+2)*sizeof(rRingOrder_t));
700      int* blk0=(int*)omAlloc0((r->N+2)*sizeof(int));
701      int* blk1=(int*)omAlloc0((r->N+2)*sizeof(int));
702      omFree(R->wvhdl);  R->wvhdl=wvhdl;
703      omFree(R->order);  R->order=ord;
704      omFree(R->block0); R->block0=blk0;
705      omFree(R->block1); R->block1=blk1;
706      for(int i=0;i<r->N;i++)
707      {
708        ord[i+p]=ringorder_a;
709        blk0[i+p]=1;
710        blk1[i+p]=R->N;
711        wvhdl[i+p]=(int*)omAlloc0(R->N*sizeof(int));
712        for(int j=0;j<d;j++)
713        {
714          assume(j*r->N+i<R->N);
715          if (r->order[p]==ringorder_lp)
716            wvhdl[i+p][j*r->N+i]=1;
717         else
718            wvhdl[i+p][(j+1)*r->N-i-1]=1;
719        }
720      }
721      ord[r->N+p]=r->order[p]; /* lp or rp */
722      blk0[r->N+p]=1;
723      blk1[r->N+p]=R->N;
724      // copy component order
725      if (p==1) ord[0]=r->order[0];
726      else /*p==0*/ ord[r->N+1]=r->order[1];
727      break;
728    }
729    default: WerrorS("ordering not implemented for LP-rings");
730      return NULL;
731  }
732  // create R->names
733  char **names=(char**)omAlloc(R->N*sizeof(char*));
734  for(int b=0;b<d;b++)
735  {
736    for(int i=r->N-1;i>=0;i--)
737      names[b*r->N+i]=omStrDup(r->names[i]);
738  }
739  for(int i=r->N-1;i>=0;i--) omFree(R->names[i]);
740  omFree(R->names);
741  R->names=names;
742
743  rComplete(R,TRUE);
744  return R;
745}
746#endif
Note: See TracBrowser for help on using the repository browser.