source: git/factory/cf_cyclo.cc @ ab547e2

spielwiese
Last change on this file since ab547e2 was c1b9927, checked in by Hans Schoenemann <hannes@…>, 13 years ago
- removed some unsed variables - never put static inline routine without a body in a .h file git-svn-id: file:///usr/local/Singular/svn/trunk@14265 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 3.6 KB
Line 
1// -*- c++ -*-
2//*****************************************************************************
3/** @file cf_cyclo.cc
4 *
5 * @author Martin Lee
6 * @date 29.01.2010
7 *
8 * Compute cyclotomic polynomials and factorize integers by brute force
9 *
10 * @par Copyright:
11 *   (c) by The SINGULAR Team, see LICENSE file
12 *
13 * @internal
14 * @version \$Id$
15 *
16**/
17//*****************************************************************************
18
19#include <config.h>
20
21#include "canonicalform.h"
22#include "cf_primes.h"
23#include "cf_util.h"
24
25#ifdef HAVE_NTL
26#include <NTL/ZZ.h>
27#endif
28
29
30/// integer factorization using table look-ups,
31/// function may fail if integer contains primes which exceed the largest prime
32/// in our table
33int* integerFactorizer (const long integer, int& length, bool& fail)
34{
35  ASSERT (integer != 0 && integer != 1 && integer != -1,
36          "non-zero non-unit expected");
37  int* result=NULL;
38  length= 0;
39  fail= false;
40  int i= integer;
41  if (integer < 0)
42    i = -integer;
43
44  int exp= 0;
45  while ((i != 1) && (i%2 == 0))
46  {
47    i /= 2;
48    exp++;
49  }
50  if (exp != 0)
51  {
52    result= new int [exp];
53    for (int k= 0; k < exp; k++)
54      result[k]= 2;
55    length += exp;
56  }
57  if (i == 1) return result;
58
59  long j= 0;
60  exp= 0;
61  int* buf;
62  int next_prime;
63  while ((i != 1) && (j < 31937))
64  {
65    next_prime= cf_getPrime (j);
66    while ((i != 1) && (i%next_prime == 0))
67    {
68      i /= next_prime;
69      exp++;
70    }
71    if (exp != 0)
72    {
73      buf= result;
74      result= new int [length + exp];
75      for (int k= 0; k < length; k++)
76        result [k]= buf[k];
77      for (int k= 0; k < exp; k++)
78        result [k + length]= next_prime;
79      length += exp;
80    }
81    exp= 0;
82    j++;
83  }
84  if (j >= 31397)
85    fail= true;
86  ASSERT (j < 31397, "integer factorizer ran out of primes") //sic
87  return result;
88}
89
90/// make prime factorization distinct
91static inline
92int* makeDistinct (int* factors, const int factors_length, int& length)
93{
94  length= 1;
95  int* result= new int [length];
96  int* buf;
97  result[0]= factors [0];
98  for (int i= 1; i < factors_length; i++)
99  {
100    if (factors[i - 1] != factors[i])
101    {
102      buf= result;
103      result= new int [length + 1];
104      for (int j= 0; j < length; j++)
105        result[j]= buf [j];
106      result[length]= factors[i];
107      length++;
108    }
109  }
110  return result;
111}
112
113/// compute the n-th cyclotomic polynomial,
114/// function may fail if integer_factorizer fails to factorize n
115CanonicalForm cyclotomicPoly (int n, bool& fail)
116{
117  fail= false;
118  Variable x= Variable (1);
119  CanonicalForm result= x - 1;
120  if (n == 1)
121    return result;
122  int* prime_factors;
123  int prime_factors_length;
124  int distinct_factors_length;
125  prime_factors= integerFactorizer (n, prime_factors_length, fail);
126  int* distinct_factors= makeDistinct (prime_factors, prime_factors_length,
127                                        distinct_factors_length);
128  if (fail)
129    return 1;
130  CanonicalForm buf;
131  int prod= 1;
132  for (int i= 0; i < distinct_factors_length; i++)
133  {
134    result= result (power (x, distinct_factors[i]), x)/result;
135    prod *= distinct_factors[i];
136  }
137  return result (power (x, n/prod), x);
138}
139
140#ifdef HAVE_NTL
141/// checks if alpha is a primitive element, alpha is assumed to be an algebraic
142/// variable over some finite prime field
143bool isPrimitive (const Variable& alpha, bool& fail)
144{
145  int p= getCharacteristic();
146  CanonicalForm mipo= getMipo (alpha);
147  int order= ipower(p, degree(mipo)) - 1;
148  CanonicalForm cyclo= cyclotomicPoly (order, fail);
149  if (fail)
150    return false;
151  if (mod(cyclo, mipo (Variable(1), alpha)) == 0)
152    return true;
153  else
154    return false;
155}
156
157#endif
Note: See TracBrowser for help on using the repository browser.