source: git/factory/facFqBivarUtil.cc @ 7a1151

spielwiese
Last change on this file since 7a1151 was d1dc39, checked in by Martin Lee <martinlee84@…>, 12 years ago
fix: deleted unused variables
  • Property mode set to 100644
File size: 20.5 KB
Line 
1/*****************************************************************************\
2 * Computer Algebra System SINGULAR
3\*****************************************************************************/
4/** @file facFqBivarUtil.cc
5 *
6 * This file provides utility functions for bivariate factorization
7 *
8 * @author Martin Lee
9 *
10 * @internal @version \$Id$
11 *
12 **/
13/*****************************************************************************/
14
15#include "config.h"
16
17#include "cf_map.h"
18#include "algext.h"
19#include "cf_map_ext.h"
20#include "templates/ftmpl_functions.h"
21#include "ExtensionInfo.h"
22#include "cf_algorithm.h"
23#include "cf_factory.h"
24#include "cf_util.h"
25#include "imm.h"
26#include "cf_iter.h"
27#include "facFqBivarUtil.h"
28#include "cfNewtonPolygon.h"
29#include "facHensel.h"
30#include "facMul.h"
31
32
33void append (CFList& factors1, const CFList& factors2)
34{
35  for (CFListIterator i= factors2; i.hasItem(); i++)
36  {
37    if (!i.getItem().inCoeffDomain())
38      factors1.append (i.getItem());
39  }
40  return;
41}
42
43void decompress (CFList& factors, const CFMap& N)
44{
45  for (CFListIterator i= factors; i.hasItem(); i++)
46    i.getItem()= N (i.getItem());
47}
48
49void decompress (CFFList& factors, const CFMap& N)
50{
51  for (CFFListIterator i= factors; i.hasItem(); i++)
52    i.getItem()= CFFactor (N (i.getItem().factor()), i.getItem().exp());
53}
54
55void appendSwapDecompress (CFList& factors1, const CFList& factors2,
56                           const CFList& factors3, const bool swap1,
57                           const bool swap2, const CFMap& N)
58{
59  Variable x= Variable (1);
60  Variable y= Variable (2);
61  for (CFListIterator i= factors1; i.hasItem(); i++)
62  {
63    if (swap1)
64    {
65      if (!swap2)
66        i.getItem()= swapvar (i.getItem(), x, y);
67    }
68    else
69    {
70      if (swap2)
71        i.getItem()= swapvar (i.getItem(), y, x);
72    }
73    i.getItem()= N (i.getItem());
74  }
75  for (CFListIterator i= factors2; i.hasItem(); i++)
76    factors1.append (N (i.getItem()));
77  for (CFListIterator i= factors3; i.hasItem(); i++)
78    factors1.append (N (i.getItem()));
79  return;
80}
81
82void swapDecompress (CFList& factors, const bool swap, const CFMap& N)
83{
84  Variable x= Variable (1);
85  Variable y= Variable (2);
86  for (CFListIterator i= factors; i.hasItem(); i++)
87  {
88    if (swap)
89      i.getItem()= swapvar (i.getItem(), x, y);
90    i.getItem()= N (i.getItem());
91  }
92  return;
93}
94
95static inline
96bool GFInExtensionHelper (const CanonicalForm& F, const int number)
97{
98  if (F.isOne()) return false;
99  InternalCF* buf;
100  int exp;
101  bool result= false;
102  if (F.inBaseDomain())
103  {
104    buf= F.getval();
105    exp= imm2int (buf);
106    if (exp%number != 0)
107      return true;
108    else
109      return result;
110  }
111  else
112  {
113    for (CFIterator i= F; i.hasTerms(); i++)
114    {
115      result= GFInExtensionHelper (i.coeff(), number);
116      if (result == true)
117        return result;
118    }
119  }
120  return result;
121}
122
123static inline
124bool FqInExtensionHelper (const CanonicalForm& F, const CanonicalForm& gamma,
125                          const CanonicalForm& delta, CFList& source,
126                          CFList& dest)
127{
128  bool result= false;
129  if (F.inBaseDomain())
130    return result;
131  else if (F.inCoeffDomain())
132  {
133    if (!fdivides (gamma, F))
134      return true;
135    else
136    {
137      int pos= findItem (source, F);
138      if (pos > 0)
139        return false;
140      Variable a;
141      hasFirstAlgVar (F, a);
142      int bound= ipower (getCharacteristic(), degree (getMipo (a)));
143      CanonicalForm buf= 1;
144      for (int i= 1; i < bound; i++)
145      {
146        buf *= gamma;
147        if (buf == F)
148        {
149          source.append (buf);
150          dest.append (power (delta, i));
151          return false;
152        }
153      }
154      return true;
155    }
156  }
157  else
158  {
159    for (CFIterator i= F; i.hasTerms(); i++)
160    {
161      result= FqInExtensionHelper (i.coeff(), gamma, delta, source, dest);
162      if (result == true)
163        return result;
164    }
165  }
166  return result;
167}
168
169bool isInExtension (const CanonicalForm& F, const CanonicalForm& gamma,
170                    const int k, const CanonicalForm& delta,
171                    CFList& source, CFList& dest)
172{
173  bool result;
174  if (CFFactory::gettype() == GaloisFieldDomain)
175  {
176    int p= getCharacteristic();
177    int orderFieldExtension= ipower (p, getGFDegree()) - 1;
178    int order= ipower (p, k) - 1;
179    int number= orderFieldExtension/order;
180    result= GFInExtensionHelper (F, number);
181    return result;
182  }
183  else
184  {
185    result= FqInExtensionHelper (F, gamma, delta, source, dest);
186    return result;
187  }
188}
189
190CanonicalForm
191mapDown (const CanonicalForm& F, const ExtensionInfo& info, CFList& source,
192         CFList& dest)
193{
194  int k= info.getGFDegree();
195  Variable beta= info.getAlpha();
196  CanonicalForm primElem= info.getGamma();
197  CanonicalForm imPrimElem= info.getDelta();
198  if (k > 1)
199    return GFMapDown (F, k);
200  else if (k == 1)
201    return F;
202  if (/*k==0 &&*/ beta == Variable (1))
203    return F;
204  else /*if (k==0 && beta != Variable (1))*/
205    return mapDown (F, imPrimElem, primElem, beta, source, dest);
206}
207
208void appendTestMapDown (CFList& factors, const CanonicalForm& f,
209                        const ExtensionInfo& info, CFList& source, CFList& dest)
210{
211  int k= info.getGFDegree();
212  Variable beta= info.getBeta();
213  Variable alpha= info.getAlpha();
214  CanonicalForm delta= info.getDelta();
215  CanonicalForm gamma= info.getGamma();
216  CanonicalForm g= f;
217  int degMipoBeta;
218  if (!k && beta.level() == 1)
219    degMipoBeta= 1;
220  else if (!k && beta.level() != 1)
221    degMipoBeta= degree (getMipo (beta));
222  if (k > 1)
223  {
224    if (!isInExtension (g, gamma, k, delta, source, dest))
225    {
226      g= GFMapDown (g, k);
227      factors.append (g);
228    }
229  }
230  else if (k == 1)
231  {
232    if (!isInExtension (g, gamma, k, delta, source, dest))
233      factors.append (g);
234  }
235  else if (!k && beta == Variable (1))
236  {
237    if (degree (g, alpha) < degMipoBeta)
238      factors.append (g);
239  }
240  else if (!k && beta != Variable (1))
241  {
242    if (!isInExtension (g, gamma, k, delta, source, dest))
243    {
244      g= mapDown (g, delta, gamma, alpha, source, dest);
245      factors.append (g);
246    }
247  }
248  return;
249}
250
251void
252appendMapDown (CFList& factors, const CanonicalForm& g,
253               const ExtensionInfo& info, CFList& source, CFList& dest)
254{
255  int k= info.getGFDegree();
256  Variable beta= info.getBeta();
257  Variable alpha= info.getAlpha();
258  CanonicalForm gamma= info.getGamma();
259  CanonicalForm delta= info.getDelta();
260  if (k > 1)
261    factors.append (GFMapDown (g, k));
262  else if (k == 1)
263    factors.append (g);
264  else if (!k && beta == Variable (1))
265    factors.append (g);
266  else if (!k && beta != Variable (1))
267    factors.append (mapDown (g, delta, gamma, alpha, source, dest));
268  return;
269}
270
271void normalize (CFList& factors)
272{
273  for (CFListIterator i= factors; i.hasItem(); i++)
274    i.getItem() /= Lc(i.getItem());
275  return;
276}
277
278void normalize (CFFList& factors)
279{
280  for (CFFListIterator i= factors; i.hasItem(); i++)
281    i.getItem()= CFFactor (i.getItem().factor()/Lc(i.getItem().factor()),
282                           i.getItem().exp());
283  return;
284}
285
286CFList subset (int index [], const int& s, const CFArray& elements,
287               bool& noSubset)
288{
289  int r= elements.size();
290  int i= 0;
291  CFList result;
292  noSubset= false;
293  if (index[s - 1] == 0)
294  {
295    while (i < s)
296    {
297      index[i]= i + 1;
298      result.append (elements[i]);
299      i++;
300    }
301    return result;
302  }
303  int buf;
304  int k;
305  bool found= false;
306  if (index[s - 1] == r)
307  {
308    if (index[0] == r - s + 1)
309    {
310      noSubset= true;
311      return result;
312    }
313    else {
314      while (found == false)
315      {
316        if (index[s - 2 - i] < r - i - 1)
317          found= true;
318        i++;
319      }
320      buf= index[s - i - 1];
321      k= 0;
322      while (s - i - 1 + k < s)
323      {
324        index[s - i - 1 + k]= buf + k + 1;
325        k++;
326      }
327    }
328    for (int j= 0; j < s; j++)
329      result.append (elements[index[j] - 1]);
330    return result;
331  }
332  else
333  {
334    index[s - 1] += 1;
335    for (int j= 0; j < s; j++)
336      result.append (elements[index[j] - 1]);
337    return result;
338  }
339}
340
341CFArray copy (const CFList& list)
342{
343  CFArray array= CFArray (list.length());
344  int j= 0;
345  for (CFListIterator i= list; i.hasItem(); i++, j++)
346    array[j]= i.getItem();
347  return array;
348}
349
350void indexUpdate (int index [], const int& subsetSize, const int& setSize,
351                   bool& noSubset)
352{
353  noSubset= false;
354  if (subsetSize > setSize)
355  {
356    noSubset= true;
357    return;
358  }
359  int * v= new int [setSize];
360  for (int i= 0; i < setSize; i++)
361    v[i]= index[i];
362  if (subsetSize == 1)
363  {
364    v[0]= v[0] - 1;
365    if (v[0] >= setSize)
366    {
367      noSubset= true;
368      delete [] v;
369      return;
370    }
371  }
372  else
373  {
374    if (v[subsetSize - 1] - v[0] + 1 == subsetSize && v[0] > 1)
375    {
376      if (v[0] + subsetSize - 1 > setSize)
377      {
378        noSubset= true;
379        delete [] v;
380        return;
381      }
382      v[0]= v[0] - 1;
383      for (int i= 1; i < subsetSize - 1; i++)
384        v[i]= v[i - 1] + 1;
385      v[subsetSize - 1]= v[subsetSize - 2];
386    }
387    else
388    {
389      if (v[0] + subsetSize - 1 > setSize)
390      {
391        noSubset= true;
392        delete [] v;
393        return;
394      }
395      for (int i= 1; i < subsetSize - 1; i++)
396        v[i]= v[i - 1] + 1;
397      v[subsetSize - 1]= v[subsetSize - 2];
398    }
399  }
400  for (int i= 0; i < setSize; i++)
401    index[i]= v[i];
402  delete [] v;
403}
404
405int subsetDegree (const CFList& S)
406{
407  int result= 0;
408  for (CFListIterator i= S; i.hasItem(); i++)
409    result += degree (i.getItem(), Variable (1));
410  return result;
411}
412
413CFFList multiplicity (CanonicalForm& F, const CFList& factors)
414{
415  if (F.inCoeffDomain())
416    return CFFList (CFFactor (F, 1));
417  CFFList result;
418  int multi= 0;
419  CanonicalForm quot;
420  for (CFListIterator i= factors; i.hasItem(); i++)
421  {
422    while (fdivides (i.getItem(), F, quot))
423    {
424      multi++;
425      F= quot;
426    }
427    if (multi > 0)
428      result.append (CFFactor (i.getItem(), multi));
429    multi= 0;
430  }
431  return result;
432}
433
434#ifdef HAVE_NTL
435CFArray
436logarithmicDerivative (const CanonicalForm& F, const CanonicalForm& G, int l,
437                       CanonicalForm& Q
438                      )
439{
440  Variable x= Variable (2);
441  Variable y= Variable (1);
442  CanonicalForm xToL= power (x, l);
443  CanonicalForm q,r;
444  CanonicalForm logDeriv;
445
446  q= newtonDiv (F, G, xToL);
447
448  logDeriv= mulMod2 (q, deriv (G, y), xToL);
449
450  logDeriv= swapvar (logDeriv, x, y);
451  int j= degree (logDeriv) + 1;
452  CFArray result= CFArray (j);
453  for (CFIterator i= logDeriv; i.hasTerms() && !logDeriv.isZero(); i++)
454  {
455    if (i.exp() == j - 1)
456    {
457      result [j - 1]= swapvar (i.coeff(), x, y);
458      j--;
459    }
460    else
461    {
462      for (; i.exp() < j - 1; j--)
463        result [j - 1]= 0;
464      result [j - 1]= swapvar (i.coeff(), x, y);
465      j--;
466    }
467  }
468  for (; j > 0; j--)
469    result [j - 1]= 0;
470  Q= q;
471  return result;
472}
473
474CFArray
475logarithmicDerivative (const CanonicalForm& F, const CanonicalForm& G, int l,
476                       int oldL, const CanonicalForm& oldQ, CanonicalForm& Q
477                      )
478{
479  Variable x= Variable (2);
480  Variable y= Variable (1);
481  CanonicalForm xToL= power (x, l);
482  CanonicalForm xToOldL= power (x, oldL);
483  CanonicalForm xToLOldL= power (x, l-oldL);
484  CanonicalForm q,r;
485  CanonicalForm logDeriv;
486
487  CanonicalForm bufF;
488  if ((oldL > 100 && l - oldL < 50) || (oldL < 100 && l - oldL < 30))
489  {
490    bufF= F;
491    CanonicalForm oldF= mulMod2 (G, oldQ, xToL);
492    bufF -= oldF;
493    bufF= div (bufF, xToOldL);
494  }
495  else
496  {
497    //middle product style computation of [G*oldQ]^{l}_{oldL}
498    CanonicalForm G3= div (G, xToOldL);
499    CanonicalForm Up= mulMod2 (G3, oldQ, xToLOldL);
500    CanonicalForm xToOldL2= power (x, oldL/2);
501    CanonicalForm G2= mod (G, xToOldL);
502    CanonicalForm G1= div (G2, xToOldL2);
503    CanonicalForm G0= mod (G2, xToOldL2);
504    CanonicalForm oldQ1= div (oldQ, xToOldL2);
505    CanonicalForm oldQ0= mod (oldQ, xToOldL2);
506    CanonicalForm Mid= mulMod2 (G1, oldQ1, xToLOldL);
507    //computation of Low might be faster using a real middle product?
508    CanonicalForm Low= mulMod2 (G0, oldQ1, xToOldL)+mulMod2 (G1, oldQ0, xToOldL);
509    Low= div (Low, xToOldL2);
510    Up += Mid + Low;
511    bufF= div (F, xToOldL);
512    bufF -= Up;
513  }
514
515  q= newtonDiv (bufF, G, xToLOldL);
516  q *= xToOldL;
517  q += oldQ;
518
519  logDeriv= mulMod2 (q, deriv (G, y), xToL);
520
521  logDeriv= swapvar (logDeriv, x, y);
522  int j= degree (logDeriv) + 1;
523  CFArray result= CFArray (j);
524  for (CFIterator i= logDeriv; i.hasTerms() && !logDeriv.isZero(); i++)
525  {
526    if (i.exp() == j - 1)
527    {
528      result [j - 1]= swapvar (i.coeff(), x, y);
529      j--;
530    }
531    else
532    {
533      for (; i.exp() < j - 1; j--)
534        result [j - 1]= 0;
535      result [j - 1]= swapvar (i.coeff(), x, y);
536      j--;
537    }
538  }
539  for (; j > 0; j--)
540    result [j - 1]= 0;
541  Q= q;
542  return result;
543}
544#endif
545
546void
547writeInMatrix (CFMatrix& M, const CFArray& A, const int column,
548               const int startIndex
549              )
550{
551  ASSERT (A.size () - startIndex >= 0, "wrong starting index");
552  ASSERT (A.size () - startIndex <= M.rows(), "wrong starting index");
553  ASSERT (column > 0 && column <= M.columns(), "wrong column");
554  if (A.size() - startIndex <= 0) return;
555  int j= 1;
556  for (int i= startIndex; i < A.size(); i++, j++)
557    M (j, column)= A [i];
558}
559
560CFArray getCoeffs (const CanonicalForm& F, const int k)
561{
562  ASSERT (F.isUnivariate() || F.inCoeffDomain(), "univariate input expected");
563  if (degree (F, 2) < k)
564    return CFArray();
565
566  CFArray result= CFArray (degree (F) - k + 1);
567  CFIterator j= F;
568  for (int i= degree (F); i >= k; i--)
569  {
570    if (j.exp() == i)
571    {
572      result [i - k]= j.coeff();
573      j++;
574      if (!j.hasTerms())
575        return result;
576    }
577    else
578      result[i - k]= 0;
579  }
580  return result;
581}
582
583CFArray getCoeffs (const CanonicalForm& F, const int k, const Variable& alpha)
584{
585  ASSERT (F.isUnivariate() || F.inCoeffDomain(), "univariate input expected");
586  if (degree (F, 2) < k)
587    return CFArray ();
588
589  int d= degree (getMipo (alpha));
590  CFArray result= CFArray ((degree (F) - k + 1)*d);
591  CFIterator j= F;
592  CanonicalForm buf;
593  CFIterator iter;
594  for (int i= degree (F); i >= k; i--)
595  {
596    if (j.exp() == i)
597    {
598      iter= j.coeff();
599      for (int l= degree (j.coeff(), alpha); l >= 0; l--)
600      {
601        if (iter.exp() == l)
602        {
603          result [(i - k)*d + l]= iter.coeff();
604          iter++;
605          if (!iter.hasTerms())
606            break;
607        }
608      }
609      j++;
610      if (!j.hasTerms())
611        return result;
612    }
613    else
614    {
615      for (int l= 0; l < d; l++)
616        result[(i - k)*d + l]= 0;
617    }
618  }
619  return result;
620}
621
622#ifdef HAVE_NTL
623CFArray
624getCoeffs (const CanonicalForm& G, const int k, const int l, const int degMipo,
625           const Variable& alpha, const CanonicalForm& evaluation,
626           const mat_zz_p& M)
627{
628  ASSERT (G.isUnivariate() || G.inCoeffDomain(), "univariate input expected");
629  CanonicalForm F= G (G.mvar() - evaluation, G.mvar());
630  if (F.isZero())
631    return CFArray ();
632
633  Variable y= Variable (2);
634  F= F (power (y, degMipo), y);
635  F= F (y, alpha);
636  zz_pX NTLF= convertFacCF2NTLzzpX (F);
637  NTLF.rep.SetLength (l*degMipo);
638  NTLF.rep= M*NTLF.rep;
639  NTLF.normalize();
640  F= convertNTLzzpX2CF (NTLF, y);
641
642  if (degree (F, 2) < k)
643    return CFArray();
644
645  CFArray result= CFArray (degree (F) - k + 1);
646
647  CFIterator j= F;
648  for (int i= degree (F); i >= k; i--)
649  {
650    if (j.exp() == i)
651    {
652      result [i - k]= j.coeff();
653      j++;
654      if (!j.hasTerms())
655        return result;
656    }
657    else
658      result[i - k]= 0;
659  }
660  return result;
661}
662#endif
663
664int * computeBounds (const CanonicalForm& F, int& n)
665{
666  n= degree (F, 1);
667  int* result= new int [n];
668  int sizeOfNewtonPolygon;
669  int** newtonPolyg= newtonPolygon (F, sizeOfNewtonPolygon);
670
671  int minX, minY, maxX, maxY;
672  minX= newtonPolyg [0] [0];
673  minY= newtonPolyg [0] [1];
674  maxX= minX;
675  maxY= minY;
676  for (int i= 1; i < sizeOfNewtonPolygon; i++)
677  {
678    if (minX > newtonPolyg [i] [0])
679      minX= newtonPolyg [i] [0];
680    if (maxX < newtonPolyg [i] [0])
681      maxX= newtonPolyg [i] [0];
682    if (minY > newtonPolyg [i] [1])
683      minY= newtonPolyg [i] [1];
684    if (maxY < newtonPolyg [i] [1])
685      maxY= newtonPolyg [i] [1];
686  }
687
688  int k= maxX;
689  for (int i= 0; i < n; i++)
690  {
691    if (i + 1 > maxY || i + 1 < minY)
692    {
693      result [i]= 0;
694      continue;
695    }
696    int* point= new int [2];
697    point [0]= k;
698    point [1]= i + 1;
699    while (!isInPolygon (newtonPolyg, sizeOfNewtonPolygon, point) && k > 0)
700    {
701      k--;
702      point [0]= k;
703    }
704    result [i]= k;
705    k= maxX;
706    delete [] point;
707  }
708
709  return result;
710}
711
712int
713substituteCheck (const CanonicalForm& F, const Variable& x)
714{
715  if (F.inCoeffDomain())
716    return 0;
717  if (degree (F, x) < 0)
718    return 0;
719  CanonicalForm f= swapvar (F, F.mvar(), x);
720  int sizef= 0;
721  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
722  {
723    if (i.exp() == 1)
724      return 0;
725  }
726  int * expf= new int [sizef];
727  int j= 0;
728  for (CFIterator i= f; i.hasTerms(); i++, j++)
729    expf [j]= i.exp();
730
731  int indf= sizef - 1;
732  if (expf[indf] == 0)
733    indf--;
734
735  int result= expf[indf];
736  for (int i= indf - 1; i >= 0; i--)
737  {
738    if (expf [i]%result != 0)
739    {
740      delete [] expf;
741      return 0;
742    }
743  }
744
745  delete [] expf;
746  return result;
747}
748
749static int
750substituteCheck (const CanonicalForm& F, const CanonicalForm& G)
751{
752  if (F.inCoeffDomain() || G.inCoeffDomain())
753    return 0;
754  Variable x= Variable (1);
755  if (degree (F, x) <= 1 || degree (G, x) <= 1)
756    return 0;
757  CanonicalForm f= swapvar (F, F.mvar(), x);
758  CanonicalForm g= swapvar (G, G.mvar(), x);
759  int sizef= 0;
760  int sizeg= 0;
761  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
762  {
763    if (i.exp() == 1)
764      return 0;
765  }
766  for (CFIterator i= g; i.hasTerms(); i++, sizeg++)
767  {
768    if (i.exp() == 1)
769      return 0;
770  }
771  int * expf= new int [sizef];
772  int * expg= new int [sizeg];
773  int j= 0;
774  for (CFIterator i= f; i.hasTerms(); i++, j++)
775  {
776    expf [j]= i.exp();
777  }
778  j= 0;
779  for (CFIterator i= g; i.hasTerms(); i++, j++)
780  {
781    expg [j]= i.exp();
782  }
783
784  int indf= sizef - 1;
785  int indg= sizeg - 1;
786  if (expf[indf] == 0)
787    indf--;
788  if (expg[indg] == 0)
789    indg--;
790
791  if ((expg[indg]%expf [indf] != 0 && expf[indf]%expg[indg] != 0) ||
792      (expg[indg] == 1 && expf[indf] == 1))
793  {
794    delete [] expg;
795    delete [] expf;
796    return 0;
797  }
798
799  int result;
800  if (expg [indg]%expf [indf] == 0)
801    result= expf[indf];
802  else
803    result= expg[indg];
804  for (int i= indf - 1; i >= 0; i--)
805  {
806    if (expf [i]%result != 0)
807    {
808      delete [] expf;
809      delete [] expg;
810      return 0;
811    }
812  }
813
814  for (int i= indg - 1; i >= 0; i--)
815  {
816    if (expg [i]%result != 0)
817    {
818      delete [] expf;
819      delete [] expg;
820      return 0;
821    }
822  }
823
824  delete [] expg;
825  delete [] expf;
826  return result;
827}
828
829int recSubstituteCheck (const CanonicalForm& F, const int d)
830{
831  if (F.inCoeffDomain())
832    return 0;
833  Variable x= Variable (1);
834  if (degree (F, x) <= 1)
835    return 0;
836  CanonicalForm f= swapvar (F, F.mvar(), x);
837  int sizef= 0;
838  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
839  {
840    if (i.exp() == 1)
841      return 0;
842  }
843  int * expf= new int [sizef];
844  int j= 0;
845  for (CFIterator i= f; i.hasTerms(); i++, j++)
846  {
847    expf [j]= i.exp();
848  }
849
850  int indf= sizef - 1;
851  if (expf[indf] == 0)
852    indf--;
853
854  if ((d%expf [indf] != 0 && expf[indf]%d != 0) || (expf[indf] == 1))
855  {
856    delete [] expf;
857    return 0;
858  }
859
860  int result;
861  if (d%expf [indf] == 0)
862    result= expf[indf];
863  else
864    result= d;
865  for (int i= indf - 1; i >= 0; i--)
866  {
867    if (expf [i]%result != 0)
868    {
869      delete [] expf;
870      return 0;
871    }
872  }
873
874  delete [] expf;
875  return result;
876}
877
878int substituteCheck (const CFList& L)
879{
880  ASSERT (L.length() > 1, "expected a list of at least two elements");
881  if (L.length() < 2)
882    return 0;
883  CFListIterator i= L;
884  i++;
885  int result= substituteCheck (L.getFirst(), i.getItem());
886  if (result <= 1)
887    return result;
888  i++;
889  for (;i.hasItem(); i++)
890  {
891    result= recSubstituteCheck (i.getItem(), result);
892    if (result <= 1)
893      return result;
894  }
895  return result;
896}
897
898void
899subst (const CanonicalForm& F, CanonicalForm& A, const int d, const Variable& x)
900{
901  if (d <= 1)
902  {
903    A= F;
904    return;
905  }
906  if (degree (F, x) <= 0)
907  {
908    A= F;
909    return;
910  }
911  CanonicalForm C= 0;
912  CanonicalForm f= swapvar (F, x, F.mvar());
913  for (CFIterator i= f; i.hasTerms(); i++)
914    C += i.coeff()*power (f.mvar(), i.exp()/ d);
915  A= swapvar (C, x, F.mvar());
916}
917
918CanonicalForm
919reverseSubst (const CanonicalForm& F, const int d, const Variable& x)
920{
921  if (d <= 1)
922    return F;
923  if (degree (F, x) <= 0)
924    return F;
925  CanonicalForm f= swapvar (F, x, F.mvar());
926  CanonicalForm result= 0;
927  for (CFIterator i= f; i.hasTerms(); i++)
928    result += i.coeff()*power (f.mvar(), d*i.exp());
929  return swapvar (result, x, F.mvar());
930}
931
932void
933reverseSubst (CFList& L, const int d, const Variable& x)
934{
935  for (CFListIterator i= L; i.hasItem(); i++)
936    i.getItem()= reverseSubst (i.getItem(), d, x);
937}
938
Note: See TracBrowser for help on using the repository browser.