def onemin(p, otherprimes, n = 1, primefact = None, num = None, den = None): """Finds the minimum exponent with which a prime and the rest of the primelist with infinite exponent is abundant. The extra variables \'n\' and \'primefact\' allow one to include a number along with the prime and the prime list; the other extra arguments are designed to override the internal structure of this function, thus allowing more efficient calls in other functions, such as progmin.""" if num == None or den == None: #if the programmer wants the computer to find out, or has omitted one variable num = reduce(lambda x, y: x*y, otherprimes, number_theory2.sigma(n, None, primefact))#see paper to see why den = reduce(lambda x, y: x*y, [x-1 for x in otherprimes], n)#see paper to see why q, r = (num*p)/(den*(p-1)), (num*p)%(den*(p-1))#The quotioent and the remainder are assigned if test(q, r, otherprimes == []): #if this has the potential of being abundant at all e = -1 #initiate exponent one below first necessary value q, r = 1, 0 #Give bogus initial values for quotient and remainder that will not pass "test" while not test(q, r, otherprimes == []): #While we have not yet found the right exponent. . . e += 1 #Incrememnt the exponent by one from what it used to be x, y = number_theory2.sigma(1, None, [(p, e)]), p**e #These values are what are multiplied to num, den a, b = num*x, den*y #We must take above values into account in num and den now q, r = a/b, a%b #Reassign quotient and remainder correctly return [y, (p, e)] #If we are done, this p**e (or y) has passed. We return it and prime fact. elif q == 2: #if this is a perfect number in the infinite case (have yet to find one) . . . return ["infinity", (p, "infinity")] #Our process will never end, but the infinite exponent checks out else: #An exceptional case; no abundance whatsoever on the horizon print "error: always deficient" #No reason to return anything; this is a bogus argument
def onemax(p, primelist, n = 1, primefactorization = None, num = None, den = None, hasinf = None): """Finding the maximum exponent of that still generates a deficient number (with n and with primelist)""" if num == None or den == None or hasinf == None: #Works just like onemin, but with the extra detail of the infinite scenario. ndh = numdeninf(primelist, n = 1, primefactorization = None) else: ndh = [num, den, hasinf] a, b = ndh[0]*(p+1), ndh[1]*p q, r = a/b, a%b if test2(q, r, ndh[2]): a, b = ndh[0]*p, ndh[1]*(p-1) q, r = a/b, a%b if test2(q, r, True): #The infinite case: we wish to avoid infinite loops return ["infinity", (p, "infinity")] else: e = 0 q, r = 1, 0 while test2(q, r, ndh[2]): e += 1 x, y = number_theory2.sigma(1, None, [(p, e)]), p**e a, b = ndh[0]*x, ndh[1]*y q, r = a/b, a%b return [y/p, (p, e-1)] else: return None
def progmin(ordprimes, showfact = False): """Progresive minimization, as in paper, starting with the first prime of the list, returning a prim. ab. number. Note: ORDER MATTERS. showfact, if True, will show the prime factorization of the number along with the number itself, the two in a tuple.""" c = ordprimes[:] #This way, we will not modify "ordprimes" if we need it later z = len(c) #It is easier here to use list.pop(0), rather than "for x in list"; thus, the index primefact = [] #Initiate one of the results n = 1 #initiate other of the results num = reduce(lambda x, y: x*y, ordprimes, 1) #Initiate num with default value den = reduce(lambda x, y: x*y, [x-1 for x in ordprimes], 1) #Initiate den with default value for i in range(z): #The loop; we want to do what follows to all elements of c p = c.pop(0) #Take out next prime; shorten remaining list to exclude said prime num /= p #No reason to include p in num anymore, as it is now an external prime den /= (p-1) #Same as above r = onemin(p, c, n, primefact, num, den) #Find the exponent of the prime primefact.append(r[1]) #This is one of the factors of n that we have found n *= r[0] #Ditto num *= number_theory2.sigma(r[0], None, [r[1]]) #Faster to build up num than recalculate sigma(n) den *= r[0] #Seeing as we are building up, why not build den as well if showfact: #If user wants the prime factorization, . . . return (n, primes2.remtriv(primefact)) #We return number AND prime factorization else: #If not, . . . return n #We assume they don't, and only return the number.
def numdeninf(primelist, n = 1, primefactorization = None): """Returns the num, den, and hasinf for primelist, n, and primefactorization. More convenient than retyping each time.""" if n == "infinity": #Not unlikely. hasinf = True #Clearly nunum, nuden = 1, 1 #We need to start at the multiplicative identity and move on from there for x in primefactorization: if x[1] == "infinity": #Not unlikely . . . nunum *= p #We use the limit behavior of the nu function (see paper) nuden *= (p-1) else: nunum *= number_theory2.sigma(1, None, [x]) #Otherwise, just treat this as a normal prime factorization nuden *= (x[0]**x[1]) else: hasinf = False #Clearly nunum, nuden = number_theory2.sigma(n), n #No need to care about the limit scenario. num = reduce(lambda x, y: x*y, [x+1 for x in primelist], nunum) #Here, we are dealing with deficiency. For more detail, see paper den = reduce(lambda x, y: x*y, primelist, nuden) return [num, den, hasinf] #What we are after
def hasabs(primelist, n = 1, primefactorization = None): """As promised in the paper, here is a function to test whether or not a set of primes is the (non-distinct) prime factorization for any abundant or perfect numbers. The n here is the same as in the paper; a number, none of whose factors are in primelist, and with whose sigma it is needed to test the primitive abundance of the set of primes.""" numerator = reduce(lambda x, y: x*y,primelist,number_theory2.sigma(n, None, primefactorization)) denominator = reduce(lambda x, y: x*y,[x -1 for x in primelist], n) q, r = numerator/denominator, numerator%denominator return test(q, r)
def progmax(ordprimes, showfact = False, shownumden = False): """This function will find the deficient number (possibly infinite) that comes about from progressively maximizing the exponents of ordprimes in the order given. It will also return the nu value of the number generated. On our way to finding the maximum deficient number of a set of primes.""" c = ordprimes[:] #This way, we will not modify "ordprimes" if we need it later hasinf = False #We assume no infinite exponents until we find them z = len(c) #It is easier here to use list.pop(0), rather than "for x in list"; thus, the index primefact = [] #Initiate one of the results n = 1 #initiate other of the results num = reduce(lambda x, y: x*y, [x+1 for x in ordprimes], 1) #Initiate num with default value den = reduce(lambda x, y: x*y, ordprimes, 1) #Initiate den with default value for i in range(z): #The loop; we want to do what follows to all elements of c p = c.pop(0) #Take out next prime; shorten remaining list to exclude said prime num /= (p+1) #No reason to include p+1 in num anymore, as it is now an external prime den /= p #Same as above r = onemax(p, c, n, primefact, num, den, hasinf) #Find the exponent of the prime if r == None: #If this was not deficient, ever . . . return None primefact.append(r[1]) #This is one of the factors of n that we have found if r[0] == "infinity": #Now, if we have found an infinite exponent, we need to be tricky hasinf = True #First, we now know we are dealing with infinity n = "infinity" #Likewise num *= p #Look at the section on nu in paper den *= (p-1) #Likewise else: #Otherwise, if not hasinf: #Unless we are already dealing with infinity, n *= r[0] #We need to change the value of n num *= number_theory2.sigma(r[0], None, [r[1]]) #Faster to build up num than recalculate sigma(n) den *= r[0] #Seeing as we are building up, why not build den as well result = (n, float(num)/den) if showfact: result += (primefact,) if shownumden: result += (num, den) return result