subroutine aptprim (ipmax, npmax, nd, ip, fp, np, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTPRIM c c call aptprim (ipmax, npmax, nd, ip, fp, np, nerr) c c Version: aptprim Updated 2003 June 20 15:00. c aptprim Originated 2003 June 10 16:00. c c Authors: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c c Purpose: Find the prime numbers ip(n), n = 1, np <= npmax, such that c ip(np) <= ipmax, and if power nd > 0, find the prime number c functions fp(n) = Product {1 - 1/ip(i)**nd}, i = 2, n, c for n = 1, np. c c For nd = 1, fp(n) is the approximate density of prime numbers c among the integers from ip(n) + 1 to ip(n+1)**2 - 1, or less c accurately, from 1 to ip(n)**2. c c For nd > 1, fp(n) is the approximate density of irreducible c proportions (no common factors) between all possible c combinations of nd integers (k, l, m, ...) from (1, 1, 1, ...) c to (K, L, M, ...), with ip(n) no larger then the largest c possible common prime factor of k, l, m, ... c c Flag nerr indicates any input error or limited results. c c Input: ipmax, npmax, nd c c Output: ip, fp, np, nerr c c Calls: (none) c c Glossary: c c fp(n) Output If nd > 0, function fp(1) = 1, and fp(n) is the c product of all factors (1 - 1/ip(i)**nd), i = 2, n, c for n = 2, np <= npmax. c Size at least npmax, if nd > 0. Otherwise, zero. c c For nd = 1 and very large n, fp(n) ~ 0.5/ln(ip(n)). c For nd = 2 and n > 10000, fp(n) ~ 0.60792756, c For nd = 3 and n > 900, fp(n) ~ 0.831907373. c For nd = 4 and n > 90, fp(n) ~ 0.923938403. c For nd = 5 and n > 40, fp(n) ~ 0.964387340. c c For nd = 1, fp(n) is the approximate density of c prime numbers among the integers from ip(n) + 1 c to ip(n+1)**2 - 1, or less accurately, from 1 to c ip(n)**2. c c For nd > 1, fp(n) is the approximate density of c irreducible proportions (no common factors) between c all possible combinations of nd integers c (k, l, m, ...) from (1, 1, 1, ...) to (K, L, M, ...), c with ip(n) no larger then the largest possible c common prime factor of k, l, m, ... c c If R(k, l, m, ...) is a point in nd-dimensional c space, with R(1, 1, 1, ...) defined as the origin, c and any increment in one of the indices k, l, m, ... c represents a spatial displacement unique to that c index, then fp(n) is the approximate fraction of all c points R for which a line from point R to the origin c does not pass through another point nearer the c origin. Each such point may define a unique c direction from the origin through multiple points c farther from the origin. c c ip(n) Output The n'th prime number. Size at least npmax. c None will be returned if nd < 1 (nerr = 1), or c ipmax < 1 (nerr = 2) or npmax < 1 (nerr = 3). c c The density of prime numbers from 1 to ip(n) is c d = n/ip(n). For large ip(n), c d ~ dlim = 1/ln(ip(n)), and c n ~ nlim = ip(n)/ln (ip(n)), and c d/dlim = n/nlim = n*ln(ip(n))/ip(n). c c d = dlim = d/dlim = c n ip n/ip 1/ln(ip) n/nlim c -------------------------------------------- c 1 1 1.000 infinite 0.000 c 2 2 1.000 1.443 0.683 c 3 3 1.000 0.910 1.099 c 4 5 0.800 0.621 1.288 c 5 7 0.714 0.514 1.390 c 10 23 0.435 0.319 1.363 c 30 109 0.275 0.213 1.291 c 100 523 0.191 0.160 1.197 c 300 1979 0.152 0.132 1.150 c 1000 7907 0.126 0.111 1.135 c 3000 27437 0.109 0.098 1.117 c 10000 104723 0.095 0.087 1.104 c 30000 350351 0.086 0.078 1.093 c c ipmax Input The limit on the size of the maximum prime number c ip(n) to find, if possible without n exceeding npmax. c If ipmax is not prime, the next lower prime number c will be the actual limit. c c nd Input The power of ip to be used in function fp. c If nd = 0, no function fp will be calculated. c It may be the dimension of a symmetric array of c points for which unique directions are to be found. c c nerr Output Indicates an input error, if not zero: c -1 if npmax prime numbers are found without reaching c the highest prime number not exceeding ipmax. c 1 if nd is less than 0. c 2 if ipmax is less than 1. c 3 if npmax is less than 1. c c npmax Input The maximum number of sequential prime numbers to find, c from 1 up to but not exceeding ipmax. c For large ipmax, the necessary npmax is at least c nlim = ip/ln (ip). See the table under "ip(n)" c above for factors n/nlim to estimate a sufficient c value of npmax. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. c.... Declarations for arguments. integer ip(1) ! An array of up to npmax prime numbers. integer ipmax ! Upper limit on size of ip. integer np ! The actual number of prime numbers. integer nd ! Power of ip in function fp. integer npmax ! Maximum number of prime numbers to find. integer nerr ! Indicates error, if not zero. real fp(1) ! Product (1 - 1/ip(i)**nd)), i = 2, n. c.... Declarations for local variables. integer int ! A number to be tested. integer i ! Index of preceding prime number. integer n ! Index of current prime number. cbugc***DEBUG begins. cbug 9901 format (/ 'aptprim finding prime numbers from 1 to',i13 / cbug $ 'but no more than',i13,' prime numbers, and the products' / cbug & 'fp(n) = (1-1/ip(i)**k), i = 2 to n, for nd =',i3) cbug write ( 3, 9901) ipmax, npmax, nd cbugc***DEBUG ends. c.... Initialize. nerr = 0 np = 0 if (npmax .gt. 0) then do 100 n = 1, npmax ip(n) = -999999999 100 continue if (nd .gt. 0) then do 105 n = 1, npmax fp(n) = -1.e99 105 continue endif endif c.... Test for input errors. if (nd .lt. 0) then nerr = 2 go to 210 endif if (ipmax .lt. 1) then nerr = 2 go to 210 endif if (npmax .lt. 1) then nerr = 3 go to 210 endif c.... Find the first prime number. np = 1 ip(1) = 1 if (ipmax .eq. 1) go to 150 if (npmax .eq. 1) go to 150 c.... Find the second prime number. np = 2 ip(2) = 2 if (ipmax .eq. 2) go to 150 if (npmax .eq. 2) go to 150 c.... Loop over higher integers to find prime numbers and functions. int = 2 110 int = int + 1 c.... See if maximum prime number has been reached. if (int .gt. ipmax) go to 150 c.... Search for factors among prime numbers less than square root of c.... current integer. do 120 i = 2, np if (ip(i)**2 .gt. int) go to 130 ! Integer int is prime. if (mod (int, ip(i)) .eq. 0) go to 110 ! Integer int is not prime. 120 continue c.... Found a prime. 130 np = np + 1 ip(np) = int c.... See if npmax primes have been found. if (np .lt. npmax) go to 110 c.... Reached npmax without reaching largest prime not exceeding ipmax. nerr = -1 c.... Find the prime number functions. 150 if (nd .eq. 0) go to 210 fp(1) = 1.0 do 160 n = 2, np fip = ip(n) fp(n) = fp(n-1) * (1.0 - 1.0 / fip**nd) 160 continue 210 continue cbugc***DEBUG begins. cbug 9902 format (/ 'aptprim found',i12,' primes. nerr =',i3,'.' // cbug & 'np, ip=' / ) cbug 9903 format (3(i6,i7,f13.9)) cbug write ( 3, 9902) np, nerr cbug if (nerr .le. 0) then cbug nn = 1 cbug 220 nmax = nn + 2 cbug if (nmax .gt. np) nmax = np cbug write ( 3, 9903) (i, ip(i), fp(i), i = nn, nmax) cbug nn = nn + 3 cbug if (nn .le. np) go to 220 cbug endif cbugc***DEBUG ends. return c.... End of subroutine aptprim. (+1 line.) end UCRL-WEB-209832