source: git/factory/cf_cyclo.cc @ 380173

spielwiese
Last change on this file since 380173 was 380173, checked in by Hans Schoenemann <hannes@…>, 4 years ago
factory: clean up: remove unused NTL
  • 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
24int* integerFactorizer (const long integer, int& length, bool& fail)
25{
26  ASSERT (integer != 0 && integer != 1 && integer != -1,
27          "non-zero non-unit expected");
28  int* result=NULL;
29  length= 0;
30  fail= false;
31  int i= integer;
32  if (integer < 0)
33    i = -integer;
34
35  int exp= 0;
36  while ((i != 1) && (i%2 == 0))
37  {
38    i /= 2;
39    exp++;
40  }
41  if (exp != 0)
42  {
43    result= new int [exp];
44    for (int k= 0; k < exp; k++)
45      result[k]= 2;
46    length += exp;
47  }
48  if (i == 1) return result;
49
50  long j= 0;
51  exp= 0;
52  int next_prime;
53  while ((i != 1) && (j < 31937))
54  {
55    next_prime= cf_getPrime (j);
56    while ((i != 1) && (i%next_prime == 0))
57    {
58      i /= next_prime;
59      exp++;
60    }
61    if (exp != 0)
62    {
63      int *buf= result;
64      result= new int [length + exp];
65      for (int k= 0; k < length; k++)
66        result [k]= buf[k];
67      for (int k= 0; k < exp; k++)
68        result [k + length]= next_prime;
69      length += exp;
70      delete[] buf;
71    }
72    exp= 0;
73    j++;
74  }
75  if (j >= 31397)
76    fail= true;
77  ASSERT (j < 31397, "integer factorizer ran out of primes"); //sic
78  return result;
79}
80
81/// make prime factorization distinct
82static inline
83int* makeDistinct (int* factors, const int factors_length, int& length)
84{
85  length= 1;
86  int* result= new int [length];
87  result[0]= factors [0];
88  for (int i= 1; i < factors_length; i++)
89  {
90    if (factors[i - 1] != factors[i])
91    {
92      int *buf= result;
93      result= new int [length + 1];
94      for (int j= 0; j < length; j++)
95        result[j]= buf [j];
96      result[length]= factors[i];
97      delete[] buf;
98      length++;
99    }
100  }
101  return result;
102}
103
104CanonicalForm cyclotomicPoly (int n, bool& fail)
105{
106  fail= false;
107  Variable x= Variable (1);
108  CanonicalForm result= x - 1;
109  if (n == 1)
110    return result;
111  int* prime_factors;
112  int prime_factors_length;
113  int distinct_factors_length;
114  prime_factors= integerFactorizer (n, prime_factors_length, fail);
115  int* distinct_factors= makeDistinct (prime_factors, prime_factors_length,
116                                        distinct_factors_length);
117  delete [] prime_factors;
118  if (fail)
119    return 1;
120  CanonicalForm buf;
121  int prod= 1;
122  for (int i= 0; i < distinct_factors_length; i++)
123  {
124    result= leftShift (result, distinct_factors[i])/result;
125    prod *= distinct_factors[i];
126  }
127  delete [] distinct_factors;
128  return leftShift (result, n/prod);
129}
130
131bool isPrimitive (const Variable& alpha, bool& fail)
132{
133  int p= getCharacteristic();
134  CanonicalForm mipo= getMipo (alpha);
135  int order= ipower(p, degree(mipo)) - 1;
136  CanonicalForm cyclo= cyclotomicPoly (order, fail);
137  if (fail)
138    return false;
139  if (mod(cyclo, mipo (Variable(1), alpha)) == 0)
140    return true;
141  else
142    return false;
143}
Note: See TracBrowser for help on using the repository browser.