source: git/factory/facFqBivarUtil.cc @ b728bf

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