source: git/factory/cf_cyclo.cc @ b7cc2b

spielwiese
Last change on this file since b7cc2b was b7cc2b, checked in by Hans Schoenemann <hannes@…>, 4 years ago
factory: FindRoot via FLINT
  • Property mode set to 100644
File size: 3.2 KB
Line 
1// -*- c++ -*-
2//*****************************************************************************
3/** @file cf_cyclo.cc
4 *
5 * Compute cyclotomic polynomials and factorize integers by brute force
6 *
7 * @par Copyright:
8 *   (c) by The SINGULAR Team, see LICENSE file
9 *
10 * @author Martin Lee
11 * @date 29.01.2010
12**/
13//*****************************************************************************
14
15
16#include "config.h"
17
18
19#include "canonicalform.h"
20#include "cf_primes.h"
21#include "cf_util.h"
22#include "cf_assert.h"
23
24#ifdef HAVE_NTL
25#include <NTL/ZZ.h>
26#endif
27
28int* integerFactorizer (const long integer, int& length, bool& fail)
29{
30  ASSERT (integer != 0 && integer != 1 && integer != -1,
31          "non-zero non-unit expected");
32  int* result=NULL;
33  length= 0;
34  fail= false;
35  int i= integer;
36  if (integer < 0)
37    i = -integer;
38
39  int exp= 0;
40  while ((i != 1) && (i%2 == 0))
41  {
42    i /= 2;
43    exp++;
44  }
45  if (exp != 0)
46  {
47    result= new int [exp];
48    for (int k= 0; k < exp; k++)
49      result[k]= 2;
50    length += exp;
51  }
52  if (i == 1) return result;
53
54  long j= 0;
55  exp= 0;
56  int next_prime;
57  while ((i != 1) && (j < 31937))
58  {
59    next_prime= cf_getPrime (j);
60    while ((i != 1) && (i%next_prime == 0))
61    {
62      i /= next_prime;
63      exp++;
64    }
65    if (exp != 0)
66    {
67      int *buf= result;
68      result= new int [length + exp];
69      for (int k= 0; k < length; k++)
70        result [k]= buf[k];
71      for (int k= 0; k < exp; k++)
72        result [k + length]= next_prime;
73      length += exp;
74      delete[] buf;
75    }
76    exp= 0;
77    j++;
78  }
79  if (j >= 31397)
80    fail= true;
81  ASSERT (j < 31397, "integer factorizer ran out of primes"); //sic
82  return result;
83}
84
85/// make prime factorization distinct
86static inline
87int* makeDistinct (int* factors, const int factors_length, int& length)
88{
89  length= 1;
90  int* result= new int [length];
91  result[0]= factors [0];
92  for (int i= 1; i < factors_length; i++)
93  {
94    if (factors[i - 1] != factors[i])
95    {
96      int *buf= result;
97      result= new int [length + 1];
98      for (int j= 0; j < length; j++)
99        result[j]= buf [j];
100      result[length]= factors[i];
101      delete[] buf;
102      length++;
103    }
104  }
105  return result;
106}
107
108CanonicalForm cyclotomicPoly (int n, bool& fail)
109{
110  fail= false;
111  Variable x= Variable (1);
112  CanonicalForm result= x - 1;
113  if (n == 1)
114    return result;
115  int* prime_factors;
116  int prime_factors_length;
117  int distinct_factors_length;
118  prime_factors= integerFactorizer (n, prime_factors_length, fail);
119  int* distinct_factors= makeDistinct (prime_factors, prime_factors_length,
120                                        distinct_factors_length);
121  delete [] prime_factors;
122  if (fail)
123    return 1;
124  CanonicalForm buf;
125  int prod= 1;
126  for (int i= 0; i < distinct_factors_length; i++)
127  {
128    result= leftShift (result, distinct_factors[i])/result;
129    prod *= distinct_factors[i];
130  }
131  delete [] distinct_factors;
132  return leftShift (result, n/prod);
133}
134
135bool isPrimitive (const Variable& alpha, bool& fail)
136{
137  int p= getCharacteristic();
138  CanonicalForm mipo= getMipo (alpha);
139  int order= ipower(p, degree(mipo)) - 1;
140  CanonicalForm cyclo= cyclotomicPoly (order, fail);
141  if (fail)
142    return false;
143  if (mod(cyclo, mipo (Variable(1), alpha)) == 0)
144    return true;
145  else
146    return false;
147}
Note: See TracBrowser for help on using the repository browser.