So, How to write a python code which finds a rational number, which is closed to a fraction say f, without the use of standard function modules?
E.g., 3.14=22/7
Also the numerator and denominators have limits, like:
numerator can't be greater than p
denominator can't be greater than q.
My work:
# calculates i/j upto a precision of 0.001 closer to f.
while( abs((i/j)-f)> 0.001 and i<p, j<q):
j=j-1
i =?,
Now here I'm confused, How should I modify my i and j to make it work? Can I use Newton Raphson algorithm in any way??
Consider that array [1,..q]
Then multiply each element by the given fraction f
then check the nearest element to p .I think this algorithm would execute in O(q) . well , you can improve upon the algorithm to check it p or q is smaller and then do likewise
import math
def foo(f,p,q):
m=9999
for i in range(1,q+1):
reqp=round(f*i)
if( abs((float(reqp)/i) -f ) <m and reqp>0 and reqp <=p ):
m=abs(float(reqp)/i-f)
values = [reqp,i]
return values
print(foo(3.14,30,30))
OUTPUT
[22.0, 7]
Pythons standard library has a module for this:
print(fractions.Fraction.from_float(math.pi).limit_denominator(30))
outputs
22/7
A brute force approach:
import math
def approx(number, p):
best = None
best_dist = number
for d in range(1, p + 1):
n0 = int(d / number)
for n in (n0 -1, n0, n0 + 1):
if n <= 0:
continue
dist = abs(number - d / n)
if dist < best_dist:
best_dist = dist
best = (d, n)
return best
print(approx(math.pi, 30))
outputs
(22, 7)
And then there is a third option: https://www.johndcook.com/blog/2010/10/20/best-rational-approximation/
Related
I am writing a program that handles numbers as large as 10 ** 100, everything looks good when dealing with smaller numbers but when values get big I get these kind of problems:
>>> N = 615839386751705599129552248800733595745824820450766179696019084949158872160074326065170966642688
>>> ((N + 63453534345) / sqrt(2)) == (N / sqrt(2))
>>> True
Clearly the above comparision is false, why is this happening?
Program code:
from math import *
def rec (n):
r = sqrt (2)
s = r + 2
m = int (floor (n * r))
j = int (floor (m / s))
if j <= 1:
return sum ([floor (r * i) for i in range (1, n + 1)])
assert m >= s * j and j > 1, "Error: something went wrong"
return m * (m + 1) / 2 - j * (j + 1) - rec (j)
print rec (1e100)
Edit:
I don't think my question is a duplicate of the linked question above because the decimal points in n, m and j are not important to me and I am looking for a solution to avoid this precision issue.
You can’t retain the precision you want while dividing by standard floating point numbers, so you should instead divide by a Fraction. The Fraction class in the fractions module lets you do exact rational arithmetic.
Of course, the square root of 2 is not rational. But if the error is less than one part in 10**100, you’ll get the right result.
So, how to compute an approximation to sqrt(2) as a Fraction? There are several ways to do it, but one simple way is to compute the integer square root of 2 * 10**200, which will be close to sqrt(2) * 10**100, then just make that the numerator and make 10**100 the denominator.
Here’s a little routine in Python 3 for integer square root.
def isqrt(n):
lg = -1
g = (1 >> n.bit_length() // 2) + 1
while abs(lg - g) > 1:
lg = g
g = (g + n//g) // 2
while g * g > n:
g -= 1
return g
You should be able to take it from there.
I'm using the following code for finding primitive roots modulo n in Python:
Code:
def gcd(a,b):
while b != 0:
a, b = b, a % b
return a
def primRoots(modulo):
roots = []
required_set = set(num for num in range (1, modulo) if gcd(num, modulo) == 1)
for g in range(1, modulo):
actual_set = set(pow(g, powers) % modulo for powers in range (1, modulo))
if required_set == actual_set:
roots.append(g)
return roots
if __name__ == "__main__":
p = 17
primitive_roots = primRoots(p)
print(primitive_roots)
Output:
[3, 5, 6, 7, 10, 11, 12, 14]
Code fragment extracted from: Diffie-Hellman (Github)
Can the primRoots method be simplified or optimized in terms of memory usage and performance/efficiency?
One quick change that you can make here (not efficiently optimum yet) is using list and set comprehensions:
def primRoots(modulo):
coprime_set = {num for num in range(1, modulo) if gcd(num, modulo) == 1}
return [g for g in range(1, modulo) if coprime_set == {pow(g, powers, modulo)
for powers in range(1, modulo)}]
Now, one powerful and interesting algorithmic change that you can make here is to optimize your gcd function using memoization. Or even better you can simply use built-in gcd function form math module in Python-3.5+ or fractions module in former versions:
from functools import wraps
def cache_gcd(f):
cache = {}
#wraps(f)
def wrapped(a, b):
key = (a, b)
try:
result = cache[key]
except KeyError:
result = cache[key] = f(a, b)
return result
return wrapped
#cache_gcd
def gcd(a,b):
while b != 0:
a, b = b, a % b
return a
# or just do the following (recommended)
# from math import gcd
Then:
def primRoots(modulo):
coprime_set = {num for num in range(1, modulo) if gcd(num, modulo) == 1}
return [g for g in range(1, modulo) if coprime_set == {pow(g, powers, modulo)
for powers in range(1, modulo)}]
As mentioned in comments, as a more pythoinc optimizer way you can use fractions.gcd (or for Python-3.5+ math.gcd).
Based on the comment of Pete and answer of Kasramvd, I can suggest this:
from math import gcd as bltin_gcd
def primRoots(modulo):
required_set = {num for num in range(1, modulo) if bltin_gcd(num, modulo) }
return [g for g in range(1, modulo) if required_set == {pow(g, powers, modulo)
for powers in range(1, modulo)}]
print(primRoots(17))
Output:
[3, 5, 6, 7, 10, 11, 12, 14]
Changes:
It now uses pow method's 3-rd argument for the modulo.
Switched to gcd built-in function that's defined in math (for Python 3.5) for a speed boost.
Additional info about built-in gcd is here: Co-primes checking
In the special case that p is prime, the following is a good bit faster:
import sys
# translated to Python from http://www.bluetulip.org/2014/programs/primitive.js
# (some rights may remain with the author of the above javascript code)
def isNotPrime(possible):
# We only test this here to protect people who copy and paste
# the code without reading the first sentence of the answer.
# In an application where you know the numbers are prime you
# will remove this function (and the call). If you need to
# test for primality, look for a more efficient algorithm, see
# for example Joseph F's answer on this page.
i = 2
while i*i <= possible:
if (possible % i) == 0:
return True
i = i + 1
return False
def primRoots(theNum):
if isNotPrime(theNum):
raise ValueError("Sorry, the number must be prime.")
o = 1
roots = []
r = 2
while r < theNum:
k = pow(r, o, theNum)
while (k > 1):
o = o + 1
k = (k * r) % theNum
if o == (theNum - 1):
roots.append(r)
o = 1
r = r + 1
return roots
print(primRoots(int(sys.argv[1])))
You can greatly improve your isNotPrime function by using a more efficient algorithm. You could double the speed by doing a special test for even numbers and then only testing odd numbers up to the square root, but this is still very inefficient compared to an algorithm such as the Miller Rabin test. This version in the Rosetta Code site will always give the correct answer for any number with fewer than 25 digits or so. For large primes, this will run in a tiny fraction of the time it takes to use trial division.
Also, you should avoid using the floating point exponentiation operator ** when you are dealing with integers as in this case (even though the Rosetta code that I just linked to does the same thing!). Things might work fine in a particular case, but it can be a subtle source of error when Python has to convert from floating point to integers, or when an integer is too large to represent exactly in floating point. There are efficient integer square root algorithms that you can use instead. Here's a simple one:
def int_sqrt(n):
if n == 0:
return 0
x = n
y = (x + n//x)//2
while (y<x):
x=y
y = (x + n//x)//2
return x
Those codes are all in-efficient, in many ways, first of all you do not need to iterate for all co-prime reminders of n, you need to check only for powers that are dividers of Euler's function from n. In the case n is prime Euler's function is n-1. If n i prime, you need to factorize n-1 and make check with only those dividers, not all. There is a simple mathematics behind this.
Second. You need better function for powering a number imagine the power is too big, I think in python you have the function pow(g, powers, modulo) which at each steps makes division and getting the remainder only ( _ % modulo ).
If you are going to implement the Diffie-Hellman algorithm it is better to use safe primes. They are such primes that p is a prime and 2p+1 is also prime, so that 2p+1 is called safe prime. If you get n = 2*p+1, then the dividers for that n-1 (n is prime, Euler's function from n is n-1) are 1, 2, p and 2p, you need to check only if the number g at power 2 and g at power p if one of them gives 1, then that g is not primitive root, and you can throw that g away and select another g, the next one g+1, If g^2 and g^p are non equal to 1 by modulo n, then that g is a primitive root, that check guarantees, that all powers except 2p would give numbers different from 1 by modulo n.
The example code uses Sophie Germain prime p and the corresponding safe prime 2p+1, and calculates primitive roots of that safe prime 2p+1.
You can easily re-work the code for any prime number or any other number, by adding a function to calculate Euler's function and to find all divisors of that value. But this is only a demo not a complete code. And there might be better ways.
class SGPrime :
'''
This object expects a Sophie Germain prime p, it does not check that it accept that as input.
Euler function from any prime is n-1, and the order (see method get_order) of any co-prime
remainder of n could be only a divider of Euler function value.
'''
def __init__(self, pSophieGermain ):
self.n = 2*pSophieGermain+1
#TODO! check if pSophieGermain is prime
#TODO! check if n is also prime.
#They both have to be primes, elsewhere the code does not work!
# Euler's function is n-1, #TODO for any n, calculate Euler's function from n
self.elrfunc = self.n-1
# All divisors of Euler's function value, #TODO for any n, get all divisors of the Euler's function value.
self.elrfunc_divisors = [1, 2, pSophieGermain, self.elrfunc]
def get_order(self, r):
'''
Calculate the order of a number, the minimal power at which r would be congruent with 1 by modulo p.
'''
r = r % self.n
for d in self.elrfunc_divisors:
if ( pow( r, d, self.n) == 1 ):
return d
return 0 # no such order, not possible if n is prime, - see small Fermat's theorem
def is_primitive_root(self, r):
'''
Check if r is a primitive root by modulo p. Such always exists if p is prime.
'''
return ( self.get_order(r) == self.elrfunc )
def find_all_primitive_roots(self, max_num_of_roots = None):
'''
Find all primitive roots, only for demo if n is large the list is large for DH or any other such algorithm
better to stop at first primitive roots.
'''
primitive_roots = []
for g in range(1, self.n):
if ( self.is_primitive_root(g) ):
primitive_roots.append(g)
if (( max_num_of_roots != None ) and (len(primitive_roots) >= max_num_of_roots)):
break
return primitive_roots
#demo, Sophie Germain's prime
p = 20963
sggen = SGPrime(p)
print (f"Safe prime : {sggen.n}, and primitive roots of {sggen.n} are : " )
print(sggen.find_all_primitive_roots())
Regards
I have a very large number, both before and after the decimal, but for this I'll just call it 4.58.
I want to know the number, Y, that will yield me an integer if multiplied by X and not any sort of float number.
Here is my code:
from decimal import *
setcontext(ExtendedContext)
getcontext().prec = 300
x=Decimal('4.58')
while True:
i=1
a=Decimal(i*x)
if float(a).is_integer():
print(i*x)
break
else:
i=+1
However, this method is incredibly slow and inefficient. I was wondering how could I implement continued fractions or some other method to make it predict the value of Y?
Edit
The decimal module stores float numbers more accurately (As strings), so 0.5 won't become 0.499999999.
Edit 2
I've got X (4.58).
I want to know what number will multiply by X to make an integer; as efficiently as possible.
Edit 3
Okay, maybe not my best question yet.
Here's my dilemma.
I've got a number spat out from a trivial programme I made. That number is a decimal number, 1.5.
All I want to do is find what integer will multiply by my decimal to yield another integer.
For 1.5, the best answer will be 2. (1.5*2=3) (float*int=int)
My while-loop above will do that, eventually, but I just wanted to know whether there was a better way to do this, such as continued fractions; and if there was, how could I implement it.
Edit 4
Here's my code thanks to user6794072. It's lengthy but functional.
from gmpy2 import mpz, isqrt
from fractions import Fraction
import operator
import functools
from decimal import *
setcontext(ExtendedContext)
getcontext().prec = 300
def factors(n):
n = mpz(n)
result = set()
result |= {mpz(1), n}
def all_multiples(result, n, factor):
z = n
f = mpz(factor)
while z % f == 0:
result |= {f, z // f}
f += factor
return result
result = all_multiples(result, n, 2)
result = all_multiples(result, n, 3)
for i in range(1, isqrt(n) + 1, 6):
i1 = i + 1
i2 = i + 5
if not n % i1:
result |= {mpz(i1), n // i1}
if not n % i2:
result |= {mpz(i2), n // i2}
return result
j=Decimal('4.58')
a=(Fraction(j).numerator)
b=(Fraction(j).denominator)
y=(factors(a))
x=(factors(b))
q=([item for item in x if item not in y])
w=([item for item in y if item not in x]) q.extend(w)
p=(functools.reduce(operator.mul, q, 1)) ans=(p*j)
print(ans)
If I understand your question correctly, you want to find the smallest integer (i) that can be multiplied to a non-integer number (n) so that:
i*n is an integer
I would do this by finding the factors of the numerator and denominator for n. In your example, if n = 4.58, then you can extract 458 for the numerator and 100 for the denominator.
The multiples of 458 are 2 and 229
The multiples of 100 are 2, 2, 5, 5
You can cross off one instance of 2 for the numerator and denominator. Then your solution is just multiplying the remaining factors in the denominator: in this case, 2*5*5 or 50.
Well think of what if you wanted to reach z = 1 and then use the fact that z == z * 1 to scale the answer. For any float x != 0.0, y = 1/x will yield z = 1, so for arbitrary integer z, just use y = z/x.
I'm not a Python programmer, but what about round function?
This question already has answers here:
Python basic math [closed]
(3 answers)
Closed 8 years ago.
What would the easiest way to represent the following equation be?
Just to clarify, my question is asking for some code that calculates the answer to the equation.
There are two problems with this:
The summation warrants an infinite loop which is impossible to get an answer from
I hoping for a long, detailed answer (maybe to 40 digits or so).
If you need more precision, you could try to use Fraction:
from fractions import Fraction # use rational numbers, they are more precise than floats
e = Fraction(0)
f = Fraction(1)
n = Fraction(1)
while True:
d = Fraction(1) / f # this ...
if d < Fraction(1, 10**40): # don't continue if the advancement is too small
break
e += d # ... and this are the formula you wrote for "e"
f *= n # calculate factorial incrementally, faster than calling "factorial()" all the time
n += Fraction(1) # we will use this for calculating the next factorial
print(float(e))
or Decimal:
from decimal import Decimal, getcontext
getcontext().prec = 40 # set the precision to 40 places
e = Decimal(0)
f = Decimal(1)
n = Decimal(1)
while True:
olde = e
e += Decimal(1) / f
if e == olde: # if there was no change in the 40 places, stop.
break
f *= n
n += Decimal(1)
print(float(e))
So here is e in 1000 places:
2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035044
To see more clearly what it does, here is its simplified version:
e = f = 1.0
for i in range(2, 16):
e += 1.0 / f
f *= i
print(e)
The obvious solution would be
import math
def e(n=10):
return sum(1 / float(math.factorial(i)) for i in range(n))
but it loses precision around n=20 (the error as compared to math.e is around 10^-16)
40-digits precision might be a challenge, and might require arbitrary precision arithmetic
I do not really see the point to have such precise "e" value since you won't be able to perform any calculations with such precision (if you do anything to it, you will lose that precision, unless you do everything in some arbitrary precision arithmetic).
To produce a similar result to my answer from a question on approximating pi:
from functools import wraps
def memoize(f):
"""Store and retrive previous results of the decorated function f."""
cache = {}
#wraps(f)
def func(*args):
if args not in cache:
cache[args] = f(*args)
return cache[args]
return func
#memoize
def fact(n):
"""Recursively calculates n!."""
if n <= 1:
return 1
return n * fact(n - 1)
def inverse_fact_n(start_n=0):
"""Generator producing the infinite series 1/n!."""
numerator = 1.0
denominator = start_n
while True:
yield numerator / fact(denominator)
denominator += 1
def approximate_e(steps=None, tolerance=None):
"""Calculate an approximation of e from summation of 1/n!."""
if steps is None and tolerance is None:
raise ValueError("Must supply one of steps or tolerance.")
series = inverse_fact_n()
if steps is not None: # stepwise method
return sum(next(series) for _ in range(steps))
output = 0 # tolerance method
term = next(series)
while abs(term) > tolerance:
output += term
term = next(series)
return output
if __name__ == "__main__":
from math import e
print("math.e:\t\t{0:.20f}.".format(e))
stepwise = approximate_e(steps=100)
print("Stepwise:\t{0:.20f}.".format(stepwise))
tolerated = approximate_e(tolerance=0.0000000001)
print("Tolerated:\t{0:.20f}.".format(tolerated))
The function approximate_e allows you to specify either:
A number of steps ("I want it to take this long"); or
A desired tolerance ("I want it to be this accurate").
There is some relatively advanced Python around this (e.g. the memoizing decorator function and the generator function to produce the series), but you can just focus on the main function, where next(series) gives you the next term of the summation.
This gives me the output:
math.e: 2.71828182845904509080.
Stepwise: 2.71828182845904553488.
Tolerated: 2.71828182844675936281.
The most effective way is to use the properties of the exponential function.
exp(x)=(exp(x/N))^N
Thus you compute x=exp(2^(-n)) with 2n bits more precision than required in the final result, and compute e by squaring the result n times.
For small numbers x, the error of truncating the series for exp(x) at the term with power m-1 is smaller than two times the next term with power m.
To summarize, to compute e with a precision/accuracy of d bit, you select some medium large n and select m such that
2^(1-mn)/m! is smaller than 2^(-d-2n)
This determination of m can also be done dynamically (using Decimal as in the answer of user22698)
from decimal import Decimal, getcontext
def eulernumber(d):
dd=d
n=4
while dd > 1:
dd /= 8
n += 1
getcontext().prec = d+n
x = Decimal(1)/Decimal(1 << n)
eps = Decimal(1)/Decimal(1 << (1 + (10*d)/3 ))
term = x
expsum = Decimal(1) + x
m = 2
while term > eps:
term *= x / Decimal(m)
m += 1
expsum += term
for k in range(n):
expsum *= expsum
getcontext().prec = d
expsum += Decimal(0)
return expsum
if __name__ == "__main__":
for k in range(1,6):
print(k,eulernumber(4*k))
for k in range(10,13):
print(k,eulernumber(4*k))
with output
( 1, Decimal('2.718'))
( 2, Decimal('2.7182818'))
( 3, Decimal('2.71828182846'))
( 4, Decimal('2.718281828459045'))
( 5, Decimal('2.7182818284590452354'))
(10, Decimal('2.718281828459045235360287471352662497757'))
(11, Decimal('2.7182818284590452353602874713526624977572471'))
(12, Decimal('2.71828182845904523536028747135266249775724709370'))
See the (unix/posix) bc math library for a more professional implementation of this idea, also for the logarithm and trig functions. The code of the exponential function is even given as example in the man page.
I am trying to Write a function called sum_square_difference which takes a number n and returns the difference between the sum of the squares of the first n natural numbers and the square of their sum.
I think i know how to write a function that defines the sum of squares
def sum_of_squares(numbers):
total = 0
for num in numbers:
total += (num ** 2)
return(total)
I have tried to implement a square of sums function:
def square_sum(numbers):
total = 0
for each in range:
total = total + each
return total**2
I don't know how to combine functions to tell the difference and i don't know if my functions are correct.
Any suggestions please? I am using Python 3.3
Thank you.
The function can be written with pure math like this:
Translated into Python:
def square_sum_difference(n):
return int((3*n**2 + 2*n) * (1 - n**2) / 12)
The formula is a simplification of two other formulas:
def square_sum_difference(n):
return int(n*(n+1)*(2*n+1)/6 - (n*(n+1)/2)**2)
n*(n+1)*(2*n+1)/6 is the formula described here, which returns the sum of the squares of the first n natural numbers.
(n*(n+1)/2))**2 uses the triangle number formula, which is the sum of the first n natural numbers, and which is then squared.
This can also be done with the built in sum function. Here it is:
def sum_square_difference(n):
r = range(1, n+1) # first n natural numbers
return sum(i**2 for i in r) - sum(r)**2
The range(1, n+1) produces an iterator of the first n natural numbers.
>>> list(range(1, 4+1))
[1, 2, 3, 4]
sum(i**2 for i in r) returns the sum of the squares of the numbers in r, and sum(r)**2 returns the square of the sum of the numbers in r.
# As beta says,
# (sum(i))^2 - (sum(i^2)) is very easy to calculate :)
# A = sum(i) = i*(i+1)/2
# B = sum(i^2) = i*(i+1)*(2*i + 1)/6
# A^2 - B = i(i+1)(3(i^2) - i - 2) / 12
# :)
# no loops... just a formula !**
This is a case where it pays to do the math beforehand. You can derive closed-form solutions for both the sum of the squares and the square of the sum. Then the code is trivial (and O(1)).
Need help with the two solutions?
def sum_square_difference(n):
r = range(1,n+1)
sum_of_squares = sum(map(lambda x: x*x, r))
square_sum = sum(r)**2
return sum_of_squares - square_sum
In Ruby language you can achieve this in this way
def diff_btw_sum_of_squars_and_squar_of_sum(from=1,to=100) # use default values from 1..100.
((1..100).inject(:+)**2) -(1..100).map {|num| num ** 2}.inject(:+)
end
diff_btw_sum_of_squars_and_squar_of_sum #call for above method