/*============================================================================== | | File Name: | | ppFactor.h | | Description: | | Methods for factoring. | | Legal: | | Primpoly Version 7.7 - A Program for Computing Primitive Polynomials. | Copyright (C) 1999-2008 by Sean Erik O'Connor. All Rights Reserved. | | This program is free software; you can redistribute it and/or | modify it under the terms of the GNU General Public License | as published by the Free Software Foundation; version 2 | of the License. | | This program is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License | along with this program; if not, write to the Free Software | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | | The author's address is artifex@seanerikoconnor.freeservers.com | ==============================================================================*/ #ifndef __PPFACTOR_H__ #define __PPFACTOR_H__ // TODO exception type. template class PrimeFactor { public: PrimeFactor( IntType prime = 0, uint count = 0 ) : prime_( prime ) , count_( count ) { } ; ~PrimeFactor() { } ; PrimeFactor( const PrimeFactor & factor ) : prime_( factor.prime_ ) , count_( factor.count_ ) { } PrimeFactor & operator=( const PrimeFactor & factor ) { if (this == &factor) return *this ; prime_ = factor.prime_ ; count_ = factor.count_ ; return *this ; } ; public: IntType prime_ ; uint count_ ; } ; template class CompareFactor { public: bool operator()( const PrimeFactor & s1, const PrimeFactor & s2 ) { return s1.prime_ < s2.prime_ ; } } ; // 0 e // Test for unit factors of the form p or 1 = 1 // template class Unit { public: bool operator()( const PrimeFactor & s ) { return s.count_ == 0 || s.prime_ == static_cast( 1u ) ; } } ; /*============================================================================= | | NAME | | Factor | | DESCRIPTION | | Class for single and multiprecision factoring. | | BigInt n ; | | Factor fact( n ) Factor n into primes. | int numDistinctFactors = fact.num() ; | BigInt primeFactor = fact[ i ] ; | | NOTES | | The member functions and friends are documented in detail ppBigInt.cpp | | BUGS | +============================================================================*/ // We need both single precision and multi-precision factoring, so use // a template with an integer type. template class Factor { // TODO: create exception type for out of range conditions. public: // Factor n into distinct primes. Default constructor factors nothing. Factor( const IntType n = 1u ) ; ~Factor() ; // Copy constructor. Factor( const Factor & f ) ; // Assignment operator. Factor & operator=( const Factor & g ) ; // Return the number of distinct factors. unsigned int num() const ; // Return the ith prime factor. // TODO range check. // throws out_of_range exception IntType operator[]( unsigned int i ) const ; // Return the count for the ith prime factor. IntType count( unsigned int i ) const ; // Euler Phi function of n. IntType EulerPhi() ; // True if p | (p - 1). // i bool skip_test( int p, int i ) const ; // Factoring by trial division up to \/ n void trialDivision( const IntType & n ) ; // Fast probabilistic factoring method. With default parameter. bool PollardRho( const IntType & n, const IntType & c = static_cast( 2u )) ; private: // Array of distinct prime factors of n with their multiplicities. vector< PrimeFactor > factor_ ; // Total number of distinct factors. uint numFactors_ ; } ; // True if n is likely to be prime. Tests on a random integer x. template bool is_probably_prime( const IntType & n, const IntType & x ) ; // True if n is probabilistically prime. template bool is_almost_surely_prime( const IntType & n ) ; #endif // __PPFACTOR_H__