source: git/factory/facFqBivarUtil.cc @ 686ce3

spielwiese
Last change on this file since 686ce3 was 686ce3, checked in by Martin Lee <martinlee84@…>, 13 years ago
added substitution of x^n->x git-svn-id: file:///usr/local/Singular/svn/trunk@13793 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.1 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 "cf_map_ext.h"
19#include "templates/ftmpl_functions.h"
20#include "ExtensionInfo.h"
21#include "cf_algorithm.h"
22#include "cf_factory.h"
23#include "cf_util.h"
24#include "imm.h"
25#include "cf_iter.h"
26#include "facFqBivarUtil.h"
27
28
29void append (CFList& factors1, const CFList& factors2)
30{
31  for (CFListIterator i= factors2; i.hasItem(); i++)
32  {
33    if (!i.getItem().inCoeffDomain())
34      factors1.append (i.getItem());
35  }
36  return;
37}
38
39void decompress (CFList& factors, const CFMap& N)
40{
41  for (CFListIterator i= factors; i.hasItem(); i++)
42    i.getItem()= N (i.getItem());
43  return;
44}
45
46void appendSwapDecompress (CFList& factors1, const CFList& factors2,
47                           const CFList& factors3, const bool swap1,
48                           const bool swap2, const CFMap& N)
49{
50  Variable x= Variable (1);
51  Variable y= Variable (2);
52  for (CFListIterator i= factors1; i.hasItem(); i++)
53  {
54    if (swap1)
55    {
56      if (!swap2)
57        i.getItem()= swapvar (i.getItem(), x, y);
58    }
59    else
60    {
61      if (swap2)
62        i.getItem()= swapvar (i.getItem(), y, x);
63    }
64    i.getItem()= N (i.getItem());
65  }
66  for (CFListIterator i= factors2; i.hasItem(); i++)
67    factors1.append (N (i.getItem()));
68  for (CFListIterator i= factors3; i.hasItem(); i++)
69    factors1.append (N (i.getItem()));
70  return;
71}
72
73void swapDecompress (CFList& factors, const bool swap, const CFMap& N)
74{
75  Variable x= Variable (1);
76  Variable y= Variable (2);
77  for (CFListIterator i= factors; i.hasItem(); i++)
78  {
79    if (swap)
80      i.getItem()= swapvar (i.getItem(), x, y);
81    i.getItem()= N (i.getItem());
82  }
83  return;
84}
85
86static inline
87bool GFInExtensionHelper (const CanonicalForm& F, const int number)
88{
89  if (F.isOne()) return false;
90  InternalCF* buf;
91  int exp;
92  bool result= false;
93  if (F.inBaseDomain())
94  {
95    buf= F.getval();
96    exp= imm2int (buf);
97    if (exp%number != 0)
98      return true;
99    else
100      return result;
101  }
102  else
103  {
104    for (CFIterator i= F; i.hasTerms(); i++)
105    {
106      result= GFInExtensionHelper (i.coeff(), number);
107      if (result == true)
108        return result;
109    }
110  }
111  return result;
112}
113
114static inline
115bool FqInExtensionHelper (const CanonicalForm& F, const CanonicalForm& gamma)
116{
117  bool result= false;
118  if (F.inBaseDomain())
119    return result;
120  else if (F.inCoeffDomain())
121  {
122    if (!fdivides (gamma, F))
123      return true;
124    else
125      return result;
126  }
127  else
128  {
129    for (CFIterator i= F; i.hasTerms(); i++)
130    {
131      result= FqInExtensionHelper (i.coeff(), gamma);
132      if (result == true)
133        return result;
134    }
135  }
136  return result;
137}
138
139bool isInExtension (const CanonicalForm& F, const CanonicalForm& gamma,
140                    const int k)
141{
142  bool result;
143  if (CFFactory::gettype() == GaloisFieldDomain)
144  {
145    int p= getCharacteristic();
146    int orderFieldExtension= ipower (p, getGFDegree()) - 1;
147    int order= ipower (p, k) - 1;
148    int number= orderFieldExtension/order;
149    result= GFInExtensionHelper (F, number);
150    return result;
151  }
152  else
153  {
154    result= FqInExtensionHelper (F, gamma);
155    return result;
156  }
157}
158
159CanonicalForm
160mapDown (const CanonicalForm& F, const ExtensionInfo& info, CFList& source,
161         CFList& dest)
162{
163  int k= info.getGFDegree();
164  Variable beta= info.getAlpha();
165  CanonicalForm primElem= info.getGamma();
166  CanonicalForm imPrimElem= info.getDelta();
167  if (k > 1)
168    return GFMapDown (F, k);
169  else if (k == 1)
170    return F;
171  else if (!k && beta == Variable (1))
172    return F;
173  else if (!k && beta != Variable (1))
174    return mapDown (F, primElem, imPrimElem, beta, source, dest);
175}
176
177void appendTestMapDown (CFList& factors, const CanonicalForm& f,
178                        const ExtensionInfo& info, CFList& source, CFList& dest)
179{
180  int k= info.getGFDegree();
181  Variable beta= info.getBeta();
182  Variable alpha= info.getAlpha();
183  CanonicalForm delta= info.getDelta();
184  CanonicalForm gamma= info.getGamma();
185  CanonicalForm g= f;
186  int degMipoBeta;
187  if (!k && beta.level() == 1)
188    degMipoBeta= 1;
189  else if (!k && beta.level() != 1)
190    degMipoBeta= degree (getMipo (beta));
191  if (k > 1)
192  {
193    if (!isInExtension (g, delta, k))
194    {
195      g= GFMapDown (g, k);
196      factors.append (g);
197    }
198  }
199  else if (k == 1)
200  {
201    if (!isInExtension (g, delta, k));
202      factors.append (g);
203  }
204  else if (!k && beta == Variable (1))
205  {
206    if (degree (g, alpha) < degMipoBeta)
207      factors.append (g);
208  }
209  else if (!k && beta != Variable (1))
210  {
211    if (!isInExtension (g, delta, k))
212    {
213      g= mapDown (g, gamma, delta, alpha, source, dest);
214      factors.append (g);
215    }
216  }
217  return;
218}
219
220void
221appendMapDown (CFList& factors, const CanonicalForm& g,
222               const ExtensionInfo& info, CFList& source, CFList& dest)
223{
224  int k= info.getGFDegree();
225  Variable beta= info.getBeta();
226  Variable alpha= info.getAlpha();
227  CanonicalForm gamma= info.getGamma();
228  CanonicalForm delta= info.getDelta();
229  if (k > 1)
230    factors.append (GFMapDown (g, k));
231  else if (k == 1)
232    factors.append (g);
233  else if (!k && beta == Variable (1))
234    factors.append (g);
235  else if (!k && beta != Variable (1))
236    factors.append (mapDown (g, gamma, delta, alpha, source, dest));
237  return;
238}
239
240void normalize (CFList& factors)
241{
242  for (CFListIterator i= factors; i.hasItem(); i++)
243    i.getItem() /= Lc(i.getItem());
244  return;
245}
246
247CFList subset (int index [], const int& s, const CFArray& elements,
248               bool& noSubset)
249{
250  int r= elements.size();
251  int i= 0;
252  CFList result;
253  noSubset= false;
254  if (index[s - 1] == 0)
255  {
256    while (i < s)
257    {
258      index[i]= i + 1;
259      result.append (elements[i]);
260      i++;
261    }
262    return result;
263  }
264  int buf;
265  int k;
266  bool found= false;
267  if (index[s - 1] == r)
268  {
269    if (index[0] == r - s + 1)
270    {
271      noSubset= true;
272      return result;
273    }
274    else {
275      while (found == false)
276      {
277        if (index[s - 2 - i] < r - i - 1)
278          found= true;
279        i++;
280      }
281      buf= index[s - i - 1];
282      k= 0;
283      while (s - i - 1 + k < s)
284      {
285        index[s - i - 1 + k]= buf + k + 1;
286        k++;
287      }
288    }
289    for (int j= 0; j < s; j++)
290      result.append (elements[index[j] - 1]);
291    return result;
292  }
293  else
294  {
295    index[s - 1] += 1;
296    for (int j= 0; j < s; j++)
297      result.append (elements[index[j] - 1]);
298    return result;
299  }
300}
301
302CFArray copy (const CFList& list)
303{
304  CFArray array= CFArray (list.length());
305  int j= 0;
306  for (CFListIterator i= list; i.hasItem(); i++, j++)
307    array[j]= i.getItem();
308  return array;
309}
310
311void indexUpdate (int index [], const int& subsetSize, const int& setSize,
312                   bool& noSubset)
313{
314  noSubset= false;
315  if (subsetSize > setSize)
316  {
317    noSubset= true;
318    return;
319  }
320  int v [setSize];
321  for (int i= 0; i < setSize; i++)
322    v[i]= index[i];
323  if (subsetSize == 1)
324  {
325    v[0]= v[0] - 1;
326    if (v[0] >= setSize)
327    {
328      noSubset= true;
329      return;
330    }
331  }
332  else
333  {
334    if (v[subsetSize - 1] - v[0] + 1 == subsetSize && v[0] > 1)
335    {
336      if (v[0] + subsetSize - 1 > setSize)
337      {
338        noSubset= true;
339        return;
340      }
341      v[0]= v[0] - 1;
342      for (int i= 1; i < subsetSize - 1; i++)
343        v[i]= v[i - 1] + 1;
344      v[subsetSize - 1]= v[subsetSize - 2];
345    }
346    else
347    {
348      if (v[0] + subsetSize - 1 > setSize)
349      {
350        noSubset= true;
351        return;
352      }
353      for (int i= 1; i < subsetSize - 1; i++)
354        v[i]= v[i - 1] + 1;
355      v[subsetSize - 1]= v[subsetSize - 2];
356    }
357  }
358  for (int i= 0; i < setSize; i++)
359    index[i]= v[i];
360  return;
361}
362
363int subsetDegree (const CFList& S)
364{
365  int result= 0;
366  for (CFListIterator i= S; i.hasItem(); i++)
367    result += degree (i.getItem(), Variable (1));
368  return result;
369}
370
371CFFList multiplicity (CanonicalForm& F, const CFList& factors)
372{
373  if (F.inCoeffDomain())
374    return CFFList (CFFactor (F, 1));
375  CFFList result;
376  int multi= 0;
377  for (CFListIterator i= factors; i.hasItem(); i++)
378  {
379    while (fdivides (i.getItem(), F))
380    {
381      multi++;
382      F /= i.getItem();
383    }
384    if (multi > 0)
385      result.append (CFFactor (i.getItem(), multi));
386    multi= 0;
387  }
388  return result;
389}
390
391static int
392substituteCheck (const CanonicalForm& F, const CanonicalForm& G)
393{
394  if (F.inCoeffDomain() || G.inCoeffDomain())
395    return 0;
396  Variable x= Variable (1);
397  if (degree (F, x) <= 1 || degree (G, x) <= 1)
398    return 0;
399  CanonicalForm f= swapvar (F, F.mvar(), x);
400  CanonicalForm g= swapvar (G, G.mvar(), x);
401  int sizef= 0;
402  int sizeg= 0;
403  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
404  {
405    if (i.exp() == 1)
406      return 0;
407  }
408  for (CFIterator i= g; i.hasTerms(); i++, sizeg++)
409  {
410    if (i.exp() == 1)
411      return 0;
412  }
413  int * expf= new int [sizef];
414  int * expg= new int [sizeg];
415  int j= 0;
416  for (CFIterator i= f; i.hasTerms(); i++, j++)
417  {
418    expf [j]= i.exp();
419  }
420  j= 0;
421  for (CFIterator i= g; i.hasTerms(); i++, j++)
422  {
423    expg [j]= i.exp();
424  }
425
426  int indf= sizef - 1;
427  int indg= sizeg - 1;
428  if (expf[indf] == 0)
429    indf--;
430  if (expg[indg] == 0)
431    indg--;
432
433  if ((expg[indg]%expf [indf] != 0 && expf[indf]%expg[indg] != 0) ||
434      (expg[indg] == 1 && expf[indf] == 1))
435  {
436    delete [] expg;
437    delete [] expf;
438    return 0;
439  }
440
441  int result;
442  if (expg [indg]%expf [indf] == 0)
443    result= expf[indf];
444  else
445    result= expg[indg];
446  for (int i= indf - 1; i >= 0; i--)
447  {
448    if (expf [i]%result != 0)
449    {
450      delete [] expf;
451      delete [] expg;
452      return 0;
453    }
454  }
455
456  for (int i= indg - 1; i >= 0; i--)
457  {
458    if (expg [i]%result != 0)
459    {
460      delete [] expf;
461      delete [] expg;
462      return 0;
463    }
464  }
465
466  delete [] expg;
467  delete [] expf;
468  return result;
469}
470
471int recSubstituteCheck (const CanonicalForm& F, const int d)
472{
473  if (F.inCoeffDomain())
474    return 0;
475  Variable x= Variable (1);
476  if (degree (F, x) <= 1)
477    return 0;
478  CanonicalForm f= swapvar (F, F.mvar(), x);
479  int sizef= 0;
480  for (CFIterator i= f; i.hasTerms(); i++, sizef++)
481  {
482    if (i.exp() == 1)
483      return 0;
484  }
485  int * expf= new int [sizef];
486  int j= 0;
487  for (CFIterator i= f; i.hasTerms(); i++, j++)
488  {
489    expf [j]= i.exp();
490  }
491
492  int indf= sizef - 1;
493  if (expf[indf] == 0)
494    indf--;
495
496  if ((d%expf [indf] != 0 && expf[indf]%d != 0) || (expf[indf] == 1))
497  {
498    delete [] expf;
499    return 0;
500  }
501
502  int result;
503  if (d%expf [indf] == 0)
504    result= expf[indf];
505  else
506    result= d;
507  for (int i= indf - 1; i >= 0; i--)
508  {
509    if (expf [i]%result != 0)
510    {
511      delete [] expf;
512      return 0;
513    }
514  }
515
516  delete [] expf;
517  return result;
518}
519
520int substituteCheck (const CFList& L)
521{
522  ASSERT (L.length() > 1, "expected a list of at least two elements");
523  if (L.length() < 2)
524    return 0;
525  CFListIterator i= L;
526  i++;
527  int result= substituteCheck (L.getFirst(), i.getItem());
528  if (result <= 1)
529    return result;
530  i++;
531  for (;i.hasItem(); i++)
532  {
533    result= recSubstituteCheck (i.getItem(), result);
534    if (result <= 1)
535      return result;
536  }
537  return result;
538}
539
540void
541subst (const CanonicalForm& F, CanonicalForm& A, const int d, const Variable& x)
542{
543  if (d <= 1)
544  {
545    A= F;
546    return;
547  }
548  if (degree (F, x) <= 0)
549  {
550    A= F;
551    return;
552  }
553  CanonicalForm C= 0;
554  CanonicalForm f= swapvar (F, x, F.mvar());
555  for (CFIterator i= f; i.hasTerms(); i++)
556    C += i.coeff()*power (f.mvar(), i.exp()/ d);
557  A= swapvar (C, x, F.mvar());
558}
559
560CanonicalForm
561reverseSubst (const CanonicalForm& F, const int d, const Variable& x)
562{
563  if (d <= 1)
564    return F;
565  if (degree (F, x) <= 0)
566    return F;
567  CanonicalForm f= swapvar (F, x, F.mvar());
568  CanonicalForm result= 0;
569  for (CFIterator i= f; i.hasTerms(); i++)
570    result += i.coeff()*power (f.mvar(), d*i.exp());
571  return swapvar (result, x, F.mvar());
572}
573
574void
575reverseSubst (CFList& L, const int d, const Variable& x)
576{
577  for (CFListIterator i= L; i.hasItem(); i++)
578    i.getItem()= reverseSubst (i.getItem(), d, x);
579}
580
Note: See TracBrowser for help on using the repository browser.