casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Primes.h
Go to the documentation of this file.
00001 //# Primes.h: This class provides some prime number operations using a cached table
00002 //# Copyright (C) 1994,1995,1999,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 
00026 //# $Id: Primes.h 21051 2011-04-20 11:46:29Z gervandiepen $
00027 
00028 #ifndef SCIMATH_PRIMES_H
00029 #define SCIMATH_PRIMES_H
00030 
00031 #include <casa/aips.h>
00032 #include <casa/Containers/Block.h>
00033 #include <casa/OS/Mutex.h>
00034 
00035 namespace casa { //# NAMESPACE CASA - BEGIN
00036 
00037 // <summary> Creates a reference table of prime numbers, and some functions </summary>
00038 //
00039 // <reviewed reviewer="Gareth Hunt" date="94/08/19" tests="tPrimes">
00040 //
00041 // <prerequisite>
00042 //   <li>Understanding Block is only peripherally important.
00043 // </prerequisite>
00044 //
00045 // <etymology>
00046 // Prime has its usual definition (a number whose only factors are
00047 // itself and one.)  Zero and one are not considered to be prime.
00048 // </etymology>
00049 //
00050 // <synopsis> 
00051 // The primary function of the Primes class is to create and maintain a list of
00052 // prime numbers.  This class has no constructors; all member functions are
00053 // therefore declared static.  The class maintains an internal cache table of
00054 // prime numbers.  There are also several member functions of more general use,
00055 // which do not access the cached table.
00056 // 
00057 // The table is initialized to contain the next prime greater than each power
00058 // of two.  The function "aLargerPrimeThan" accepts a number and returns a
00059 // larger prime number from the table of prime numbers.  The function
00060 // "nextLargerPrimeThan" finds the next greater integer that is a prime,
00061 // returns it, and inserts it into the table.  There are also functions to
00062 // initialize and examine the table.
00063 // 
00064 // The basic prime number operations are done in three functions: "isPrime"
00065 // determines whether a given number is a prime; "smallestPrimeFactor" finds
00066 // the smallest factor of a given number; and "factor" returns a Block<uInt>
00067 // containing a number's factors.
00068 // </synopsis> 
00069 //
00070 // <example>
00071 // <srcblock>
00072 // #include <scimath/Mathematics/Primes.h>
00073 // #include <casa/Utilities/Assert.h>
00074 // #include <iostream>
00075 //
00076 // // Refer also to tPrimes.cc
00077 //
00078 // int main() {
00079 //     Block<uInt> BB, DD;
00080 //     uInt C, i;
00081 //     if(! Primes::isPrime(4)) {                         //if this number 
00082 //         cout<<"Four is not a prime number"<<endl;      //is not prime
00083 //         BB = Primes::factor(4);                        //than factor it
00084 //
00085 //         if( BB[0] != Primes::smallestPrimeFactor(4) ){ //check that first 
00086 //                                                        //factor equals
00087 //              cerr<<"something is wrong"<<endl;         //the smallest 
00088 //         }
00089 //         cout<<"4 factored:"<<endl;
00090 //         for ( i = 0; i < BB.nelements(); i++ ) {
00091 //             cout<<BB[i]<<endl;
00092 //         }
00093 //
00094 //         C = Primes::aLargerPrimeThan(4);  
00095 //         if ( (C-5) > 4 ) {                         //if difference is more 
00096 //                                                    //than five, then
00097 //             C = Primes::nextLargerPrimeThan(4);    //find next lprime
00098 //         } 
00099 //         DebugAssertExit( C == Primes::aLargerPrimeThan(4)); //now the prime resides
00100 //     }                                              //in the cache table 
00101 //     if( Primes::nCachedPrimes() > 50 ) {
00102 //         Primes::initializeCache();
00103 //     }
00104 //     DD = Primes::cachedPrimes();
00105 //     cout<<"The Table of Primes"<<endl;
00106 //     for ( i = 0; i < Primes::nCachedPrimes(); i++ ) {
00107 //         cout<<DD[i]<<endl;
00108 //     }
00109 //     return 0;
00110 // }
00111 //
00112 // </srcblock>
00113 // </example>
00114 //
00115 // <motivation>
00116 // This class was conceived during the coding of a class that creates hash 
00117 // tables.  The hash table class works best with a table whose size is prime.
00118 // It uses the Primes class's function "nextLargerPrimeThan" to find a prime
00119 // number that is close to an appropriate size.  This prime number becomes the
00120 // size of the hash table.
00121 // </motivation>
00122 //
00123 // <todo asof="$DATE:$">
00124 //   <li> This class should not be used to generate large sets of prime
00125 //        numbers - it is not designed for efficiency at this.
00126 //        The algorithm checks 2, 3, and (6n +/- 1) up to the square
00127 //        root of the candidate prime.
00128 //   <li> The size of the prime numbers are restricted by the size of an
00129 //        unsigned integer (2^31-1 on 32 bit machines).
00130 // </todo>
00131 
00132 class Primes {
00133 public:
00134  
00135     //This function takes number and returns "True" if number is prime, "False" 
00136     //if it is not.
00137     static Bool isPrime(uInt number);
00138 
00139     //This function returns the closest integer larger than number from the 
00140     //table of primes.  If there is no entry in the table of primes which is 
00141     //larger than number, a zero is returned.
00142     static uInt aLargerPrimeThan(uInt number);
00143 
00144     //This function finds the next largest prime than number, returns that 
00145     //value and stores it in the table of primes.
00146     static uInt nextLargerPrimeThan(uInt number);   // adds to cache
00147 
00148     //This function returns the smallest factor of number.
00149     static uInt smallestPrimeFactor(uInt number);
00150 
00151     //This function returns a block, of variable length, with each factor 
00152     //indexed.  For example, if number equaled 4, then the return block would 
00153     //have a length of two, and have a two stored in each cell. One and zero
00154     //are special cases; this function returns a one-cell block which holds
00155     //one or zero, respectively.
00156     static Block<uInt> factor(uInt number);
00157 
00158     // This function returns the number of primes stored in the primes table.
00159   //    static uInt nCachedPrimes()
00160   //    { return cacheTable.nelements(); }
00161 
00162     //This function returns the table of prime numbers.
00163     //static Block<uInt> cachedPrimes()
00164   //    { return cacheTable; }
00165     
00166 private:
00167 
00168     //This function resets the table of prime numbers to contain 31 prime 
00169     //numbers to avoid consuming too much memory.
00170     static void initializeCache();
00171 
00172     //This is the table which stores the prime numbers.
00173     static Block<uInt> cacheTable;
00174     static Mutex       theirMutex;
00175 };
00176 
00177 
00178 } //# NAMESPACE CASA - END
00179 
00180 #endif