Python function to approximate mathematical value of e - python

I am writing a function to approximate the mathematical value of e.
We are told to use the factorial function and the inverse function above. It is also suggested to use map.
I have this so far, but it gives me an error saying: ValueError: factorial() only accepts integral values.
def inverse(n):
"""Returns the inverse of n"""
return 1 / n
def e(n):
"""Approximates the mathematical value e"""
lst = range(1, n+1)
lst2 = map(inverse, lst)
lst3 = map(math.factorial, lst2)
return sum(lst3)
Could someone point me in the right direction please?

e can be defined by Σ(1/k!), where k = 0 .. ∞.
So, for each k,
compute k!
invert
add to total
It looks like you're doing the inversion before the factorial instead of after, and starting from 1 instead of 0.
Note that this is not the most efficient way of doing this computation, as the factorial is unnecessarily being computed from scratch for each k.

This is now working for me. I needed to change the range from (1, n+1) to (0, n+1) and reverse the order of doing the factorial first and then doing the inverse.
def inverse(n):
"""Returns the inverse of n"""
return 1 / n
def e(n):
"""Approximates the mathematical value e"""
lst = map(math.factorial, range(0, n+1))
return sum(map(inverse, lst))

As everyone else pointed out:
You are missing the first term in the series which is 1.
In python, the division gives you an integer value if both numbers are integers. i.e. 1/2 == 0.
You need something like this:
def inverse(n):
"""Returns the inverse of n"""
# Using 1 as a float makes the division return a float value.
return 1. / n
def e(n):
"""Approximates the mathematical value e"""
lst = range(1, n+1) # k=1...n
lst2 = map(math.factorial, lst)
return 1 + sum(map(inverse, lst2))
You can compare your approximation against math.exp:
>>> abs(math.exp(1) - e(20)) < 1e-10
True

I has some fun with that question, using generators and decorators. First, you can create a generator to yield consecutively more precise values of e:
def compute_e():
currentFactorial = 1
currentSum = 1
for i in itertools.count(start=1):
currentFactorial *= i
currentSum += 1/currentFactorial
yield currentSum
And, after that, I create a decorator to find a fixed point (with a maximum number of iterations, and wanted precision) :
def getFixedPoint(gen, maxiter=10000, precision=0):
def mywrap(*args, **kwargs):
instanceGen = gen(*args, **kwargs)
prevValue = next(instanceGen)
for n, value in enumerate(instanceGen):
if (value - prevValue < precision) or (n > maxiter):
return value
else:
prevValue = value
return mywrap
which gives me stuff like this:
In [83]: getFixedPoint(compute_e)()
Out[83]: 2.7182818284590455
In [84]: getFixedPoint(compute_e, maxiter=5)()
Out[84]: 2.71827876984127
In [85]: getFixedPoint(compute_e, precision = 0.001)()
Out[85]: 2.7182539682539684
Of cours, now I can change my way of computing each successive value of e, for example by using from decimal import Decimal:
#getFixedPoint
def compute_e():
currentFactorial = Decimal(1)
currentSum = Decimal(1)
for i in itertools.count(start=1):
currentFactorial *= i
currentSum += 1/currentFactorial
yield currentSum
compute_e()
Out[95]: Decimal('2.718281828459045235360287474')

Related

Errors in Directly vs Recursively Calculating a given Fibonacci Number

I was bored at work and was playing with some math and python coding, when I noticed the following:
Recursively (or if using a for loop) you simply add integers together to get a given Fibonacci number. However there is also a direct equation for calculating Fibonacci numbers, and for large n this equation will give answers that are, frankly, quite wrong with respect to the recursively calculated Fibonacci number.
I imagine this is due to rounding and floating point arithmetic ( sqrt(5) is irrational after all), and if so can anyone point me into a direction on how I could modify the fibo_calc_direct function to return a more accurate result?
Thanks!
def fib_calc_recur(n, ii = 0, jj = 1):
#n is the index of the nth fibonacci number, F_n, where F_0 = 0, F_1 = 1, ...
if n == 0: #use recursion
return ii
if n == 1:
return jj
else:
return(fib_calc_recur(n -1, jj, ii + jj))
def fib_calc_direct(n):
a = (1 + np.sqrt(5))/2
b = (1 - np.sqrt(5))/2
f = (1/np.sqrt(5)) * (a**n - b**n)
return(f)
You could make use of Decimal numbers, and set its precision depending on the magninute of n
Not your question, but I'd use an iterative version of the addition method. Here is a script that makes both calculations (naive addition, direct with Decimal) for values of n up to 4000:
def fib_calc_iter(n):
a, b = 0, 1
if n < 2:
return n
for _ in range(1, n):
a, b = b, a + b
return b
from decimal import Decimal, getcontext
def fib_calc_decimal(n):
getcontext().prec = n // 4 + 3 # Choose a precision good enough for this n
sqrt5 = Decimal(5).sqrt()
da = (1 + sqrt5) / 2
db = (1 - sqrt5) / 2
f = (da**n - db**n) / sqrt5
return int(f + Decimal(0.5)) # Round to nearest int
# Test it...
for n in range(1, 4000):
x = fib_calc_iter(n)
y = fib_calc_decimal(n)
if x != y:
print(f"Difference found for n={n}.\nNaive method={x}.\nDecimal method={y}")
break
else:
print("No differences found")

calculating arithmetic progression with recursion

I'm trying to make a function that is given the first number in an arithmetic progression, the derivation d and the number of terms in the series which is n and then calculate their sum using recursion
I tried the following
def rec_sum(a_1, d, n):
if n == 0:
return 0
return (n*(a_1+rec_sum(a_1,d,n-1)))/2
print rec_sum(2,2,4)
which gives me 18 instead of 20
thanks for the help
There is a simpler way to find the sum of arithmetic progression, but if you need the recursion -
def rec_sum(first_element, step, seq_length):
if seq_length <= 0:
return 0
return first_element + rec_sum(first_element + step, step, seq_length - 1)
Another solution:
def rec_sum(a_1, d, n):
if n == 0:
return 0
return a_1 + rec_sum(a_1 + d, d, n-1)
print rec_sum(2, 2, 4)
output:
20

Nearest Square Function with Python

I have this sample quiz question but not to sure how to approach it with while loops.
Implement the nearest_square function. The function takes an integer argument limit, and returns the largest square number that is less than limit.
A square number is the product of an integer multiplied by itself, for example 36 is a square number because it equals 6*6.
There's more than one way to write this code, but I suggest you use a while loop!
Here is a test case you can copy to test your code. Feel free to write additional tests too!
test1 = nearest_square(40)
print("expected result: 36, actual result: {}".format(test1))
I have managed to solve it. Thank you.
def nearest_square(limit):
limit = limit ** (0.5)
y = int (limit)
while y < limit :
y = y*y
return y
test1 = nearest_square(40)
print("expected result: 36,actual result:{}".format(test1))
Try using the following method to return the nearest square given the limit parameter:
def nearest_square(limit):
answer = 0
while (answer+1)**2 < limit:
answer += 1
return answer**2
Normally, it's more efficient to approach this kind of questions mathematically (maybe not for low inputs but certainly yes for pretty big numbers). That said, we have a good tool at hand: the square root.
If computing the square root of any number, n, yields a double value whose decimal part is fully composed by zeroes then your number is a perfect square (square of an integer).
Interestingly (and this is more related to your question), if you choose another number (that is not a perfect square) and apply a rounding operation (floor or ceil) you'll get the closest square (lower or bigger).
An example:
n = 24
sqrt = math.sqrt(n) # sqrt(24) = 4.898979485566356...
closest = [math.floor(sqrt)**2, math.ceil(sqrt)**2] # closest = [16, 25]
this is how i did it with while loop:
def nearest_square(value):
i = 2
while i < value:
square = i*i
if square == value:
return square
i+=1
value-=1
print (nearest_square(40))
def nearest_square(value):
i = 1
result = 1
while (result < value):
if (result == value):
return result
i+=1
result = i*i
return (i-1)*(i-1)
print (nearest_square(82))
Here is my code:
`
def nearest_square(limit):
while limit > 3:
i = 2
while i <= limit//2:
square = i*i
if square == limit:
return square
else:
i += 1
limit -= 1
return 1
`
Here's what i did.
def nearest_square(limit):
y = 0
while y**2 < limit:
y+=1
if y**2 == limit:
return(y)
return(y-1)
print(nearest_square(40))
Here is my implementation of it.
this one is with while loop
def near1(limit):
i = 1
square = 1
while (i*i) < limit:
square = i*i
i = i+1
return square
but the easiest one is below.
Simple math and modulo
import math
def near(limit):
i = int(math.pow(limit, .5))
return i*i
This is what i did.
import math
def nearest_square(limit):
a = math.sqrt(limit)
while type(a) != type(int()):
limit -=1
return limit

Euclidean algorithm (GCD) with multiple numbers?

So I'm writing a program in Python to get the GCD of any amount of numbers.
def GCD(numbers):
if numbers[-1] == 0:
return numbers[0]
# i'm stuck here, this is wrong
for i in range(len(numbers)-1):
print GCD([numbers[i+1], numbers[i] % numbers[i+1]])
print GCD(30, 40, 36)
The function takes a list of numbers.
This should print 2. However, I don't understand how to use the the algorithm recursively so it can handle multiple numbers. Can someone explain?
updated, still not working:
def GCD(numbers):
if numbers[-1] == 0:
return numbers[0]
gcd = 0
for i in range(len(numbers)):
gcd = GCD([numbers[i+1], numbers[i] % numbers[i+1]])
gcdtemp = GCD([gcd, numbers[i+2]])
gcd = gcdtemp
return gcd
Ok, solved it
def GCD(a, b):
if b == 0:
return a
else:
return GCD(b, a % b)
and then use reduce, like
reduce(GCD, (30, 40, 36))
Since GCD is associative, GCD(a,b,c,d) is the same as GCD(GCD(GCD(a,b),c),d). In this case, Python's reduce function would be a good candidate for reducing the cases for which len(numbers) > 2 to a simple 2-number comparison. The code would look something like this:
if len(numbers) > 2:
return reduce(lambda x,y: GCD([x,y]), numbers)
Reduce applies the given function to each element in the list, so that something like
gcd = reduce(lambda x,y:GCD([x,y]),[a,b,c,d])
is the same as doing
gcd = GCD(a,b)
gcd = GCD(gcd,c)
gcd = GCD(gcd,d)
Now the only thing left is to code for when len(numbers) <= 2. Passing only two arguments to GCD in reduce ensures that your function recurses at most once (since len(numbers) > 2 only in the original call), which has the additional benefit of never overflowing the stack.
You can use reduce:
>>> from fractions import gcd
>>> reduce(gcd,(30,40,60))
10
which is equivalent to;
>>> lis = (30,40,60,70)
>>> res = gcd(*lis[:2]) #get the gcd of first two numbers
>>> for x in lis[2:]: #now iterate over the list starting from the 3rd element
... res = gcd(res,x)
>>> res
10
help on reduce:
>>> reduce?
Type: builtin_function_or_method
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
Python 3.9 introduced multiple arguments version of math.gcd, so you can use:
import math
math.gcd(30, 40, 36)
3.5 <= Python <= 3.8.x:
import functools
import math
functools.reduce(math.gcd, (30, 40, 36))
3 <= Python < 3.5:
import fractions
import functools
functools.reduce(fractions.gcd, (30, 40, 36))
A solution to finding out the LCM of more than two numbers in PYTHON is as follow:
#finding LCM (Least Common Multiple) of a series of numbers
def GCD(a, b):
#Gives greatest common divisor using Euclid's Algorithm.
while b:
a, b = b, a % b
return a
def LCM(a, b):
#gives lowest common multiple of two numbers
return a * b // GCD(a, b)
def LCMM(*args):
#gives LCM of a list of numbers passed as argument
return reduce(LCM, args)
Here I've added +1 in the last argument of range() function because the function itself starts from zero (0) to n-1. Click the hyperlink to know more about range() function :
print ("LCM of numbers (1 to 5) : " + str(LCMM(*range(1, 5+1))))
print ("LCM of numbers (1 to 10) : " + str(LCMM(*range(1, 10+1))))
print (reduce(LCMM,(1,2,3,4,5)))
those who are new to python can read more about reduce() function by the given link.
The GCD operator is commutative and associative. This means that
gcd(a,b,c) = gcd(gcd(a,b),c) = gcd(a,gcd(b,c))
So once you know how to do it for 2 numbers, you can do it for any number
To do it for two numbers, you simply need to implement Euclid's formula, which is simply:
// Ensure a >= b >= 1, flip a and b if necessary
while b > 0
t = a % b
a = b
b = t
end
return a
Define that function as, say euclid(a,b). Then, you can define gcd(nums) as:
if (len(nums) == 1)
return nums[1]
else
return euclid(nums[1], gcd(nums[:2]))
This uses the associative property of gcd() to compute the answer
Try calling the GCD() as follows,
i = 0
temp = numbers[i]
for i in range(len(numbers)-1):
temp = GCD(numbers[i+1], temp)
My way of solving it in Python. Hope it helps.
def find_gcd(arr):
if len(arr) <= 1:
return arr
else:
for i in range(len(arr)-1):
a = arr[i]
b = arr[i+1]
while b:
a, b = b, a%b
arr[i+1] = a
return a
def main(array):
print(find_gcd(array))
main(array=[8, 18, 22, 24]) # 2
main(array=[8, 24]) # 8
main(array=[5]) # [5]
main(array=[]) # []
Some dynamics how I understand it:
ex.[8, 18] -> [18, 8] -> [8, 2] -> [2, 0]
18 = 8x + 2 = (2y)x + 2 = 2z where z = xy + 1
ex.[18, 22] -> [22, 18] -> [18, 4] -> [4, 2] -> [2, 0]
22 = 18w + 4 = (4x+2)w + 4 = ((2y)x + 2)w + 2 = 2z
As of python 3.9 beta 4, it has got built-in support for finding gcd over a list of numbers.
Python 3.9.0b4 (v3.9.0b4:69dec9c8d2, Jul 2 2020, 18:41:53)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> A = [30, 40, 36]
>>> print(math.gcd(*A))
2
One of the issues is that many of the calculations only work with numbers greater than 1. I modified the solution found here so that it accepts numbers smaller than 1. Basically, we can re scale the array using the minimum value and then use that to calculate the GCD of numbers smaller than 1.
# GCD of more than two (or array) numbers - alows folating point numbers
# Function implements the Euclidian algorithm to find H.C.F. of two number
def find_gcd(x, y):
while(y):
x, y = y, x % y
return x
# Driver Code
l_org = [60e-6, 20e-6, 30e-6]
min_val = min(l_org)
l = [item/min_val for item in l_org]
num1 = l[0]
num2 = l[1]
gcd = find_gcd(num1, num2)
for i in range(2, len(l)):
gcd = find_gcd(gcd, l[i])
gcd = gcd * min_val
print(gcd)
HERE IS A SIMPLE METHOD TO FIND GCD OF 2 NUMBERS
a = int(input("Enter the value of first number:"))
b = int(input("Enter the value of second number:"))
c,d = a,b
while a!=0:
b,a=a,b%a
print("GCD of ",c,"and",d,"is",b)
As You said you need a program who would take any amount of numbers
and print those numbers' HCF.
In this code you give numbers separated with space and click enter to get GCD
num =list(map(int,input().split())) #TAKES INPUT
def print_factors(x): #MAKES LIST OF LISTS OF COMMON FACTROS OF INPUT
list = [ i for i in range(1, x + 1) if x % i == 0 ]
return list
p = [print_factors(numbers) for numbers in num]
result = set(p[0])
for s in p[1:]: #MAKES THE SET OF COMMON VALUES IN LIST OF LISTS
result.intersection_update(s)
for values in result:
values = values*values #MULTIPLY ALL COMMON FACTORS TO FIND GCD
values = values//(list(result)[-1])
print('HCF',values)
Hope it helped

iterative Newton's method

I have got this code to solve Newton's method for a given polynomial and initial guess value. I want to turn into an iterative process which Newton's method actually is. The program should keeping running till the output value "x_n" becomes constant. And that final value of x_n is the actual root. Also, while using this method in my algorithm it should always produce a positive root between 0 and 1. So does converting the negative output (root) into a positive number would make any difference? Thank you.
import copy
poly = [[-0.25,3], [0.375,2], [-0.375,1], [-3.1,0]]
def poly_diff(poly):
""" Differentiate a polynomial. """
newlist = copy.deepcopy(poly)
for term in newlist:
term[0] *= term[1]
term[1] -= 1
return newlist
def poly_apply(poly, x):
""" Apply a value to a polynomial. """
sum = 0.0
for term in poly:
sum += term[0] * (x ** term[1])
return sum
def poly_root(poly):
""" Returns a root of the polynomial"""
poly_d = poly_diff(poly)
x = float(raw_input("Enter initial guess:"))
x_n = x - (float(poly_apply(poly, x)) / poly_apply(poly_d, x))
print x_n
if __name__ == "__main__" :
poly_root(poly)
First, in poly_diff, you should check to see if the exponent is zero, and if so simply remove that term from the result. Otherwise you will end up with the derivative being undefined at zero.
def poly_root(poly):
""" Returns a root of the polynomial"""
poly_d = poly_diff(poly)
x = None
x_n = float(raw_input("Enter initial guess:"))
while x != x_n:
x = x_n
x_n = x - (float(poly_apply(poly, x)) / poly_apply(poly_d, x))
return x_n
That should do it. However, I think it is possible that for certain polynomials this may not terminate, due to floating point rounding error. It may end up in a repeating cycle of approximations that differ only in the least significant bits. You might terminate when the percentage of change reaches a lower limit, or after a number of iterations.
import copy
poly = [[1,64], [2,109], [3,137], [4,138], [5,171], [6,170]]
def poly_diff(poly):
newlist = copy.deepcopy(poly)
for term in newlist:
term[0] *= term[1]
term[1] -= 1
return newlist
def poly_apply(poly, x):
sum = 0.0
for term in poly:
sum += term[0] * (x ** term[1])
return sum
def poly_root(poly):
poly_d = poly_diff(poly)
x = float(input("Enter initial guess:"))
x_n = x - (float(poly_apply(poly, x)) / poly_apply(poly_d, x))
print (x_n)
if __name__ == "__main__" :
poly_root(poly)

Categories