How to replace zero with a small number? - python

I want to replace the divisor with a very small number if it equals to 0. I am doing an operation which is like:
A = pow(X,2)/(q - P)
It computes these values and stores them in an array (for looped). However, at certain places q - P = 0, which throws a runtime error. I know that there is a work around, I do not want that. How can I set q - P to a very small number in case q - P = 0 for a particular iteration.

I would recommend to use a try except block and set A to a different value if a ZeroDivisionError error occurs:
try:
A = (pow(X,2))/(q - P))
except ZeroDivisionError:
A = 99999999999 #big nuber because devision by a small number
# you can also set A to infinity with `A = np.inf`
If thats not an option for you (e.g. you really want to change q or P and not only A) you can simply add a small number to q or P
if q == P:
q+= 0.00000000000001 # or P+=small_number or q-=small_number or P-=small_number

You can use an inline if:
very_small_number = 0.001
A = pow(X, 2) / ( q - P if q != P else very_small_number )

You can use the following trick:
diff = q - P or .001
A = pow(X, 2) / diff
or
A = pow(X, 2) / (q - P or .001)

Related

Geometric series: calculate quotient and number of elements from sum and first & last element

Creating evenly spaced numbers on a log scale (a geometric progression) can easily be done for a given base and number of elements if the starting and final values of the sequence are known, e.g., with numpy.logspace and numpy.geomspace. Now assume I want to define the geometric progression the other way around, i.e., based on the properties of the resulting geometric series. If I know the sum of the series as well as the first and last element of the progression, can I compute the quotient and number of elements?
For instance, assume the first and last elements of the progression are and and the sum of the series should be equal to . I know from trial and error that it works out for n=9 and r≈1.404, but how could these values be computed?
You have enough information to solve it:
Sum of series = a + a*r + a*(r^2) ... + a*(r^(n-1))
= a*((r^n)-1)/(r-1)
= a*((last element * r) - 1)/(r-1)
Given the sum of series, a, and the last element, you can use the above equation to find the value of r.
Plugging in values for the given example:
50 = 1 * ((15*r)-1) / (r-1)
50r - 50 = 15r - 1
35r = 49
r = 1.4
Then, using sum of series = a*((r^n)-1)/(r-1):
50 = 1*((1.4^n)-1)(1.4-1)
21 = 1.4^n
n = log(21)/log(1.4) = 9.04
You can approximate n and recalculate r if n isn't an integer.
We have to reconstruct geometric progesssion, i.e. obtain a, q, m (here ^ means raise into power):
a, a * q, a * q^2, ..., a * q^(m - 1)
if we know first, last, total:
first = a # first item
last = a * q^(m - 1) # last item
total = a * (q^m - 1) / (q - 1) # sum
Solving these equation we can find
a = first
q = (total - first) / (total - last)
m = log(last / a) / log(q)
if you want to get number of items n, note that n == m + 1
Code:
import math
...
def Solve(first, last, total):
a = first
q = (total - first) / (total - last)
n = math.log(last / a) / math.log(q) + 1
return (a, q, n);
Fiddle
If you put your data (1, 15, 50) you'll get the solution
a = 1
q = 1.4
n = 9.04836151801382 # not integer
since n is not an integer you, probably want to adjust; let last == 15 be exact, when total can vary. In this case q = (last / first) ^ (1 / (n - 1)) and total = first * (q ^ n - 1) / (q - 1)
a = 1
q = 1.402850552006674
n = 9
total = 49.752 # now n is integer, but total <> 50
You have to solve the following two equations for r and n:
a:= An / Ao = r^(n - 1)
and
s:= Sn / Ao = (r^n - 1) / (r - 1)
You can eliminate n by
s = (r a - 1) / (r - 1)
and solve for r. Then n follows by log(a) / log(r) + 1.
In your case, from s = 50 and a = 15, we obtain r = 7/5 = 1.4 and n = 9.048...
It makes sense to round n to 9, but then r^8 = 15 (r ~ 1.40285) and r = 1.4 are not quite compatible.

RSA validate p and q keys in python, python-rsa lib

UPDATE
I have a program to get two public and private keys for validate those keys.
Either those key are valid or not.
We assume that our keys are valid.
(pub , privateKey) = rsa.newkeys(1024)
However I have a relation for p, q and nlen.
This is our mathematical equation for p and q:
The primes p and q shall be selected with the following constraints:
(a) (p–1) and (q–1) shall be relatively prime to the
public exponent e.
(b) The private prime factor p shall be selected and shall satisfy
(a) condition passed successfully.
But I can't understand item (b).
In the other hands we said len(p) = len(q) = nlen/2.
nlen equal to size of module in bites.
Let's talk about this condition :
This codes are definitions of p, q, d, e and nlen.
p = privkey.p
q = privkey.q
d = privkey.d
e = privkey.e
nlen = privkey.n.bit_length()
We implemented our conditions with this code :
if not sqrt(2) * (2 ** ((nlen/2) - 1)) <= p <= (2 ** (nlen/2)) - 1:
return "Invalid P prime number size"
And another conditions implemented with this following codes :
Check q len
if not sqrt(2) * (2 ** ((nlen/2) - 1)) <= q <= (2 ** (nlen/2)) - 1:
return "Invalid Q prime number size"
Above conditions didn't match and their bodies ran.
Anyway this problem is true for decryption len condition.
Second condition passes successfully.
But first throw my written error to parent class.
This my code :
if not 2 ** (nlen/2) < d < lcm(p-1, q-1):
return "Invalid decryption key"
But why ?
I think my problem related to nlen. cause everywhere i used nlen, my Tests didn't passed and failed.
I checked its values but i don't know what i can do for fixing this problem.
I think you text is wrong because both prime factors are only used for calculations of the keys and not published. the following answer will check if the keys are valid, not if they are secure:
In order to check if two keys are valid, you need to have the following values:
p and q (prime numbers selected)
n (mod-number = p * q)
key1 and key2 (public and private key)
def is_valid(p, q, key1, key2, n): # assuming p and q are actually prime
if n != p * q: # check if n is actually p * q
return False
num = (p - 1) * (q - 1)
if (key1 * key2) % num != 1: # check if keys are valid
return False
return True
This private and public keys are absolutely valid. but our conditions are true for a secure key.
We can use pycryptodome python library for increase our key tests security.
In this case we should create a key pair with those passphrases and load them with same passphrase in pycryptodome.

How to avoid math domain error when we have sqrt

I wrote the following code, after printing about 10 outputs it gets error
return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
ValueError: math domain error
the three first functions are correct and work well in other programs please do not be sensitive about their structures, I think the problem is in for-loop and choosing some values which cannot satisfy the condition of sqrt. Could I add some lines to tell Python avoid numbers which lead to math domain error? If yes, How should I do that? I mean passing the step which leads to negative value under sqrt?
Cov is a 31*31 mtrix, xx[n] is a list of 31 numbers.
def ant(z,Om,w):
return 1/sqrt(Om*(1+z)**3+w*(1+z)**6+(1-Om-w))
def dl(n,Om,w,M):
q=quad(ant,0,xx[n],args=(Om,w))[0]
h=5*log10((1+xx[n])*q)
fn=(yy[n]-M-h)
return fn
def c(Om,w,M):
f_list = []
for i in range(31): # the value '2' reflects matrix size
f_list.append(dl(i,Om,w,M))
A=[f_list]
B=[[f] for f in f_list]
C=np.dot(A,Cov)
D=np.dot(C,B)
F=np.linalg.det(D)*0.000001
return F
N=100
for i in range (1,N):
R3=np.random.uniform(0,1)
Omn[i]=Omo[i-1]+0.05*np.random.normal()
wn[i]=wo[i-1]+0.05*np.random.normal()
Mn[i]=Mo[i-1]+0.1*np.random.normal()
L=exp(-0.5*(c(Omn[i],wn[i],Mn[i])-c(Omo[i-1],wo[i-1],Mo[i-1])))
if L>R3:
wo[i]=wn[i]
else:
wo[i]=wo[i-1]
print(wo[i])
The output is:
0.12059556415714912
0.16292726528216397
0.16644447885609648
0.1067588804671105
0.0321446951572128
0.0321446951572128
0.013169965429457382
Traceback (most recent call last):
......
return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
ValueError: math domain error
Here are some options:
Replace sqrt(...) with (...)**0.5. This will produce complex numbers, which may or may not be acceptable. For example (-1)**0.5 produces i which in Python will appear as 1j (ignoring floating point errors).
Catch errors and move on. Since you probably want to catch the errors higher up, I recommend translating the ValueError from sqrt into a custom error:
class SqrtError(ValueError):
pass
def ant(z, Om, w):
val = Om * (1 + z) ** 3 + w * (1 + z) ** 6 + (1 - Om - w)
try:
sq = sqrt(val)
except ValueError:
raise SqrtError
return 1 / sq
Then it sounds like you want to keep trying new random numbers until you get one that works, which could be done like so:
for i in range(1, N):
R3 = np.random.uniform(0, 1)
while True:
Omn[i] = Omo[i - 1] + 0.05 * np.random.normal()
wn[i] = wo[i - 1] + 0.05 * np.random.normal()
Mn[i] = Mo[i - 1] + 0.1 * np.random.normal()
try:
L = exp(-0.5 * (c(Omn[i], wn[i], Mn[i]) - c(Omo[i - 1], wo[i - 1], Mo[i - 1])))
except SqrtError:
continue
else:
break
if L > R3:
wo[i] = wn[i]
else:
wo[i] = wo[i - 1]
Your code is trying to find the square root of a negative number.
This is not allowed with real-valued numbers (for obvious mathematical reasons), so your best bet is to use a try/except block:
def ant(z,Om,w):
try:
return 1/sqrt(Om*(1+z)**3+omg0*(1+z)**6+(1-Om-omg0))
except ValueError:
return None

working with large numbers in the fraction module in Python

EDIT: solved but since the solution was in the comments and I cant accept my own solution reffering to the comment till tomorrow it is still open. Once again a big thank you to this great community and its people
optional context: I am computing sollutions for the Pell equation
http://mathworld.wolfram.com/PellEquation.html
On the buttom of the page is a table with values for D -> x, y.
My code works perfectly for EVERY VALUE EXCEPT D = 61. I believe it could have something to do with the values of x and y being very big and maybe the fraction module cant handle such big numbers and there is an overflow?
I made the observation, that whether I give my input/ starting value as a fraction or a decimal changes my solution (but only for D = 61).
Why is my code failing with the value of D = 61? What do I need to change/use to get it to work? Thank you very much for your time and help.
code:
from math import sqrt, floor
from fractions import Fraction
def continued_fraction(D):
# to make sure it is not a problem on converting decimals to fractions I made EVERYTHING a fraction (which shouldnt and didnt affect the output)
# input is the value for D, output is a tuple with (x, y)
D = Fraction(sqrt(D))
aS = []
a0 = D
r1 = Fraction(D - floor(D))
a = Fraction(a0 - r1)
r = Fraction(-1)
count = 0
while a <= 2*floor(D):
aS.append((a, count))
if a == 2*floor(D):
if count % 2 == 0:
break
else:
r = count
if count == 2*r:
break
try:
a0 = Fraction(1/r1)
except ZeroDivisionError:
break
r1 = Fraction(a0 - floor(a0))
a = Fraction(a0 - r1)
count += 1
pS = []
qS = []
a0 = Fraction(floor(D))
p0 = a0
p1 = Fraction(a0 * aS[1][0] + 1)
q0 = Fraction(1)
q1 = Fraction(aS[1][0])
count = 2
while count < len(aS):
pS.append((p0, count - 2))
qS.append((q0, count - 2))
pn = Fraction(aS[count][0] * p1 + p0)
qn = Fraction(aS[count][0] * q1 + q0)
p0 = Fraction(p1)
p1 = Fraction(pn)
q0 = Fraction(q1)
q1 = Fraction(qn)
count += 1
pS.append((p0, count-1))
#pS.append((p1, count))
qS.append((q0, count - 1))
#qS.append((q1, count))
#print(pS)
#print(qS)
return Fraction(pS[-1][0]), Fraction(qS[-1][0])
print(continued_fraction(Fraction(61)))
Fraction(1/r1) means to compute the reciprocal of r1 as an inexact floating-point number, and then find a rational approximation of that inexact number. You want Fraction(1, r1) to directly specify the numerator and denominator of your fraction, without any approximation errors creeping in.
A big thanks to GalAbra and jasonharper for your responds. After knowing with certainty, that it is a percision problem (thank you GalAbra) I knew I needed more decimals for the sqrt(D). I used the decimal module from Python:
from decimal import *
getcontext().prec = 1000
D = Fraction(Decimal(D).sqrt())
with this and the change suggested by jasonharper (thank you again) it works now.

Solving a mathematical equation recursively in Python

I want to solve an equation which I am supposed to solve it recursively, I uploaded the picture of formula (Sorry! I did not know how to write mathematical formulas here!)
I wrote the code in Python as below:
import math
alambda = 1.0
rho = 0.8
c = 1.0
b = rho * c / alambda
P0 = (1 - (alambda*b))
P1 = (1-(alambda*b))*(math.exp(alambda*b) - 1)
def a(n):
a_n = math.exp(-alambda*b) * ((alambda*b)**n) / math.factorial(n)
return a_n
def P(n):
P(n) = (P0+P1)*a(n) + sigma(n)
def sigma(n):
j = 2
result = 0
while j <= n+1:
result = result + P(j)*a(n+1-j)
j += 1
return result
It is obvious that I could not finish P function. So please help me with this.
when n=1 I should extract P2, when n=2 I should extract P3.
By the way, P0 and P1 are as written in line 6 and 7.
When I call P(5) I want to see P(0), P(1), P(2), P(3), P(4), P(5), P(6) at the output.
You need to reorganize the formula so that you don't have to calculate P(3) to calculate P(2). This is pretty easy to do, by bringing the last term of the summation, P(n+1)a(0), to the left side of the equation and dividing through by a(0). Then you have a formula for P(n+1) in terms of P(m) where m <= n, which is solvable by recursion.
As Bruce mentions, it's best to cache your intermediate results for P(n) by keeping them in a dict so that a) you don't have to recalculate P(2) etc everytime you need it, and b) after you get the value of P(n), you can just print the dict to see all the values of P(m) where m <= n.
import math
a_lambda = 1.0
rho = 0.8
c = 1.0
b = rho * c / a_lambda
p0 = (1 - (a_lambda*b))
p1 = (1-(a_lambda*b))*(math.exp(a_lambda*b) - 1)
p_dict = {0: p0, 1: p1}
def a(n):
return math.exp(-a_lambda*b) * ((a_lambda*b)**n) / math.factorial(n)
def get_nth_p(n, p_dict):
# return pre-calculated value if p(n) is already known
if n in p_dict:
return p_dict[n]
# Calculate p(n) using modified formula
p_n = ((get_nth_p(n-1, p_dict)
- (get_nth_p(0, p_dict) + get_nth_p(1, p_dict)) * a(n - 1)
- sum(get_nth_p(j, p_dict) * a(n + 1 - j) for j in xrange(2, n)))
/ a(0))
# Save computed value into the dict
p_dict[n] = p_n
return p_n
get_nth_p(6, p_dict)
print p_dict
Edit 2
Some cosmetic updates to the code - shortening the name and making p_dict a mutable default argument (something I try to use only sparingly) really makes the code much more readable:
import math
# Customary to distinguish variables that are unchanging by making them ALLCAP
A_LAMBDA = 1.0
RHO = 0.8
C = 1.0
B = RHO * C / A_LAMBDA
P0 = (1 - (A_LAMBDA*B))
P1 = (1-(A_LAMBDA*B))*(math.exp(A_LAMBDA*B) - 1)
p_value_cache = {0: P0, 1: P1}
def a(n):
return math.exp(-A_LAMBDA*B) * ((A_LAMBDA*B)**n) / math.factorial(n)
def p(n, p_dict=p_value_cache):
# return pre-calculated value if p(n) is already known
if n in p_dict:
return p_dict[n]
# Calculate p(n) using modified formula
p_n = ((p(n-1)
- (p(0) + p(1)) * a(n - 1)
- sum(p(j) * a(n + 1 - j) for j in xrange(2, n)))
/ a(0))
# Save computed value into the dict
p_dict[n] = p_n
return p_n
p(6)
print p_value_cache
You could fix if that way:
import math
alambda = 1.0
rho = 0.8
c = 1.0
b = rho * c / alambda
def a(n):
# you might want to cache a as well
a_n = math.exp(-alambda*b) * ((alambda*b)**n) / math.factorial(n)
return a_n
PCache={0:(1 - (alambda*b)),1:(1-(alambda*b))*(math.exp(alambda*b) - 1)}
def P(n):
if n in PCache:
return PCache[n]
ret= (P(0)+P(1))*a(n) + sigma(n)
PCache[n]=ret
return ret
def sigma(n):
# caching this seems smart as well
j = 2
result = 0
while j <= n+1:
result = result + P(j)*a(n+1-j)
j += 1
return result
void displayP(n):
P(n) # fill cache :-)
for x in range(n):
print ("%u -> %d\n" % (x,PCache[x]))
Instead of managing the cache manually, you might want to use a memoize decorator (see http://www.python-course.eu/python3_memoization.php )
Notes:
not tested, but you should get the idea behind it
your recurrence won't work P(n) depends on P(n+1) on your equation... This will never end
It looks like I misunderstood P0 and P1 as being Both constants (big numbers) and results (small numbers, indices)... Notation is not the best choice I guess...

Categories

Resources