Related
I'm trying to solve a problem about Bernoulli numbers using Python. The aim is to output the numerator and the denominator of the $n$-th Bernoulli number. I use the conventions and the generic formula given in this source.
Here is my code. I use the auxiliary function aux_bernoulli to compute Bernoulli numbers using recursivity.
from fractions import Fraction
from math import factorial
def aux_bernoulli(n):
if n == 0:
return 1
elif n == 1: # convention
return -0.5
elif (n-1)%2==0: # B(n)=0 when n is odd
return 0
else:
somme = 0
for k in range(n):
somme += (factorial(n)/(factorial(n+1-k)*factorial(k))) * aux_bernoulli(k)
return -somme
def bernoulli(n):
ber = aux_bernoulli(n)
print(ber) # for debugging purposes
numerator, denominator = Fraction(ber).numerator, Fraction(ber).denominator
return numerator, denominator
This code is giving me wrong values that are very close to the right ones and I can't understand figure out why. Here are some examples:
bernoulli(4)
bernoulli(6)
bernoulli(8)
Output:
-0.03333333333333338
(-600479950316067, 18014398509481984)
0.023809523809524058
(214457125112883, 9007199254740992)
-0.033333333333335075
(-1200959900632195, 36028797018963968)
Correct values according to this source:
-0.033333
(-1, 30)
0.0280952
(1/42)
-0.033333
(-1, 30)
Does anyone know what's wrong with my approach?
Combining #Stef's various suggestions (multiple +1s), I came up with the following simplification:
from math import comb
from fractions import Fraction
from functools import lru_cache
#lru_cache
def bernoulli(n):
if n == 0:
return Fraction(1)
if n == 1: # convention
return Fraction(-1/2)
somme = Fraction(0)
if n % 2: # B(n) = 0 when n is odd
return somme
for k in range(n):
somme += bernoulli(k) * comb(n, k) / (n + 1 - k)
return -somme
print(bernoulli(60).as_integer_ratio())
It's easy to mess up the result by moving between Fraction and float.
I want to use str.format to convert 2 number to scientific notation raised to the same exponential but the exponential need to be set off the str.format.
Example:
from math import log10
y=10000
x=round(np.log10(y))
m=10
y="{:e}".format(y)
m="{:e}".format(m)
print(y)
print(m)
here I have that m has e = 1 and y e = 4 and what I want is for both to have the same "e". i want to set both to exponencial x.
I think you have to calculate this yourself, for example using a helper function which returns a string:
def format_exp(x, n):
significand = x / 10 ** n
exp_sign = '+' if n >= 0 else '-'
return f'{significand:f}e{exp_sign}{n:02d}'
Explanation:
x is the number to format, and n is the power that you want to display;
significand calculates the part to show in front of the e by dividing x by 10n (10 ** n);
exp_sign is either + or -, depending on the value of n (to replicate the default behaviour).
Example usage:
>>> import math
>>> y = 10000
>>> m = 10
>>> x = math.floor(math.log10(y)) # x = 4
>>> print(format_exp(y, x))
1.000000e+04
>>> print(format_exp(m, x))
0.001000e+04
>>> print(format_exp(y, 1))
1000.000000e+01
>>> print(format_exp(m, 1))
1.000000e+01
You can increase the complexity of this function by adding an additional parameter d to set the number of decimals printed in the significand part (with a default value of 6 to reproduce the default Python behaviour):
def format_exp(x, n, d=6):
significand = x / 10 ** n
exp_sign = '+' if n >= 0 else '-'
return f'{significand:.{d}f}e{exp_sign}{n:02d}'
With this function, you can control the number of decimals printed:
>>> print(format_exp(y, x)) # default behaviour still works
1.000000e+04
>>> print(format_exp(y, x, 4))
1.0000e+04
>>> print(format_exp(y, x, 1))
1.0e+04
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
I had written a simple pascal triangle code in python but I am getting a error
def factorial(n):
c=1
re=1
for c in range(n):
re = re * c;
return(re)
print "Enter how many rows of pascal triangle u want to show \n"
n=input();
i=1
c=1
for i in range(n):
for c in range(n-i-1):
print ""
for c in range(i):
a = factorial(i);
b = factorial(c);
d = factorial(i-c);
z = (a/(b*d));
print "%d" % z
print "\n"
ERROR:
Traceback (most recent call last):
File "/home/tanmaya/workspace/abc/a.py", line 19, in <module>
z = (a/(b*d));
ZeroDivisionError: integer division or modulo by zero
Your factorial() function returns 0 for any input because of how you defined your range.
The range builtin starts at 0 unless otherwise defined so:
for c in range(n):
re = re * c # no semicolons in Python
is doing:
re = re * 0
on the first iteration so for all subsequent iterations:
re = 0 * c
will always be 0
Start your range at 1 like so
for c in range(1, n):
re *= c # The *= operator is short hand for a = a * b
you can see this more explicityly:
>>> print(list(range(5)))
[0, 1, 2, 3, 4]
>>> print(list(range(1,5)))
[1, 2, 3, 4]
>>>
or instead of rolling your own function use the one that comes with Python:
>>> from math import factorial
>>> factorial(3)
6
Upon closer reading of your code it seems you tried to circumvent this by setting c = 1 outside your for loop. This is not going to work because the variables you declared outside the loop are being reassigned inside it.
ZeroDivisionError means that you were trying to divide or modulo, a number n with 0.
in your case, z = (a/(b*d)) resulted in z = (a/0)
Also, as #theB pointed out, your factorial function is incorrect.
Try fixing those.
Also, you don't really need ; in your code. It's usually the case we put ; when we want to make the code one liner.
Does some standard Python module contain a function to compute modular multiplicative inverse of a number, i.e. a number y = invmod(x, p) such that x*y == 1 (mod p)? Google doesn't seem to give any good hints on this.
Of course, one can come up with home-brewed 10-liner of extended Euclidean algorithm, but why reinvent the wheel.
For example, Java's BigInteger has modInverse method. Doesn't Python have something similar?
Python 3.8+
y = pow(x, -1, p)
Python 3.7 and earlier
Maybe someone will find this useful (from wikibooks):
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
If your modulus is prime (you call it p) then you may simply compute:
y = x**(p-2) mod p # Pseudocode
Or in Python proper:
y = pow(x, p-2, p)
Here is someone who has implemented some number theory capabilities in Python: http://www.math.umbc.edu/~campbell/Computers/Python/numbthy.html
Here is an example done at the prompt:
m = 1000000007
x = 1234567
y = pow(x,m-2,m)
y
989145189L
x*y
1221166008548163L
x*y % m
1L
You might also want to look at the gmpy module. It is an interface between Python and the GMP multiple-precision library. gmpy provides an invert function that does exactly what you need:
>>> import gmpy
>>> gmpy.invert(1234567, 1000000007)
mpz(989145189)
Updated answer
As noted by #hyh , the gmpy.invert() returns 0 if the inverse does not exist. That matches the behavior of GMP's mpz_invert() function. gmpy.divm(a, b, m) provides a general solution to a=bx (mod m).
>>> gmpy.divm(1, 1234567, 1000000007)
mpz(989145189)
>>> gmpy.divm(1, 0, 5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: not invertible
>>> gmpy.divm(1, 4, 9)
mpz(7)
divm() will return a solution when gcd(b,m) == 1 and raises an exception when the multiplicative inverse does not exist.
Disclaimer: I'm the current maintainer of the gmpy library.
Updated answer 2
gmpy2 now properly raises an exception when the inverse does not exists:
>>> import gmpy2
>>> gmpy2.invert(0,5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: invert() no inverse exists
As of 3.8 pythons pow() function can take a modulus and a negative integer. See here. Their case for how to use it is
>>> pow(38, -1, 97)
23
>>> 23 * 38 % 97 == 1
True
Here is a one-liner for CodeFights; it is one of the shortest solutions:
MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1]
It will return -1 if A has no multiplicative inverse in n.
Usage:
MMI(23, 99) # returns 56
MMI(18, 24) # return -1
The solution uses the Extended Euclidean Algorithm.
Sympy, a python module for symbolic mathematics, has a built-in modular inverse function if you don't want to implement your own (or if you're using Sympy already):
from sympy import mod_inverse
mod_inverse(11, 35) # returns 16
mod_inverse(15, 35) # raises ValueError: 'inverse of 15 (mod 35) does not exist'
This doesn't seem to be documented on the Sympy website, but here's the docstring: Sympy mod_inverse docstring on Github
Here is a concise 1-liner that does it, without using any external libraries.
# Given 0<a<b, returns the unique c such that 0<c<b and a*c == gcd(a,b) (mod b).
# In particular, if a,b are relatively prime, returns the inverse of a modulo b.
def invmod(a,b): return 0 if a==0 else 1 if b%a==0 else b - invmod(b%a,a)*b//a
Note that this is really just egcd, streamlined to return only the single coefficient of interest.
I try different solutions from this thread and in the end I use this one:
def egcd(a, b):
lastremainder, remainder = abs(a), abs(b)
x, lastx, y, lasty = 0, 1, 1, 0
while remainder:
lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder)
x, lastx = lastx - quotient*x, x
y, lasty = lasty - quotient*y, y
return lastremainder, lastx * (-1 if a < 0 else 1), lasty * (-1 if b < 0 else 1)
def modinv(a, m):
g, x, y = self.egcd(a, m)
if g != 1:
raise ValueError('modinv for {} does not exist'.format(a))
return x % m
Modular_inverse in Python
Here is my code, it might be sloppy but it seems to work for me anyway.
# a is the number you want the inverse for
# b is the modulus
def mod_inverse(a, b):
r = -1
B = b
A = a
eq_set = []
full_set = []
mod_set = []
#euclid's algorithm
while r!=1 and r!=0:
r = b%a
q = b//a
eq_set = [r, b, a, q*-1]
b = a
a = r
full_set.append(eq_set)
for i in range(0, 4):
mod_set.append(full_set[-1][i])
mod_set.insert(2, 1)
counter = 0
#extended euclid's algorithm
for i in range(1, len(full_set)):
if counter%2 == 0:
mod_set[2] = full_set[-1*(i+1)][3]*mod_set[4]+mod_set[2]
mod_set[3] = full_set[-1*(i+1)][1]
elif counter%2 != 0:
mod_set[4] = full_set[-1*(i+1)][3]*mod_set[2]+mod_set[4]
mod_set[1] = full_set[-1*(i+1)][1]
counter += 1
if mod_set[3] == B:
return mod_set[2]%B
return mod_set[4]%B
The code above will not run in python3 and is less efficient compared to the GCD variants. However, this code is very transparent. It triggered me to create a more compact version:
def imod(a, n):
c = 1
while (c % a > 0):
c += n
return c // a
from the cpython implementation source code:
def invmod(a, n):
b, c = 1, 0
while n:
q, r = divmod(a, n)
a, b, c, n = n, c, b - q*c, r
# at this point a is the gcd of the original inputs
if a == 1:
return b
raise ValueError("Not invertible")
according to the comment above this code, it can return small negative values, so you could potentially check if negative and add n when negative before returning b.
To figure out the modular multiplicative inverse I recommend using the Extended Euclidean Algorithm like this:
def multiplicative_inverse(a, b):
origA = a
X = 0
prevX = 1
Y = 1
prevY = 0
while b != 0:
temp = b
quotient = a/b
b = a%b
a = temp
temp = X
a = prevX - quotient * X
prevX = temp
temp = Y
Y = prevY - quotient * Y
prevY = temp
return origA + prevY
Well, here's a function in C which you can easily convert to python. In the below c function extended euclidian algorithm is used to calculate inverse mod.
int imod(int a,int n){
int c,i=1;
while(1){
c = n * i + 1;
if(c%a==0){
c = c/a;
break;
}
i++;
}
return c;}
Translates to Python Function
def imod(a,n):
i=1
while True:
c = n * i + 1;
if(c%a==0):
c = c/a
break;
i = i+1
return c
Reference to the above C function is taken from the following link C program to find Modular Multiplicative Inverse of two Relatively Prime Numbers