Photo Formula
def prob(i, r, b): #r and b may be np.arrays or lists()
if i == 0:
return 1
else:
return (1 / i) * #And what's next?
Formula denotes unnormalized probability probability P(i) - the probability that the system is in state i, wherein and P(0) = 1, where I() - indicator function, b_k and r_k - const parameters, which fed to the input. I don't know how I can implement this code. I will appreciate any help!
def prob(i, rs, bs): # i: int, rs: [num], bs: [num]:
# I not know if the elems in rs are integers, neither positives
# I apply abs in rs elems and compare with equals and less
if i <= 0:
return 1
return (1 / i) * sum(b * prop(i - abs(r)) for (r, b) in zip(rs, bs))
Related
Say, we have f(t) = v * t + A * sin(w * t). I call such functions "saw-like":
I want to solve saw(t) = C, that is, find a root of saw(t) - C (still "saw-like").
I tried writing down a ternary search for function abs(saw(t) - C) to find its minima. If we are lucky (or crafty), it would be the root. Unfortunately, my code does not always work: sometimes we get stuck in those places:
My code (python3):
def calculate(fun):
eps = 0.000000001
eps_l = 0.1
x = terns(fun, 0, 100000000000000)
t = terns(fun, 0, x)
cnt = 0
while fun(x) > eps:
t = x
x = terns(fun, 0, t)
if abs(t - x) < eps_l:
cnt += 1
# A sorry attempt pass some wrong value as a right one.
# Gets us out of an infinite loop at least.
if cnt == 10:
break
return t
def terns(f, l, r):
eps = 0.00000000001
while r - l > eps:
x_1 = l + (r - l) / 3
x_2 = r - (r - l) / 3
if f(x_1) < f(x_2):
r = x_2
else:
l = x_1
return (l + r) / 2
So, how is it done? Is using ternary search the right way?
My other idea was somehow sending the equation over to the net, passing it to Wolfram Alpha and fetching the answers. Yet, I don't how it's done, as I am not quite fluent at python.
How could this be done?
I am currently working on a project replicating RSA key generation and testing using euclidean algorithm, extended euclidean algorithm to find the modular inverse of the value.
I used the Miller-Rabin test to choose two prime numbers, p and q.
After running the code, I am able to obtain Kpub and e, however Kpr returns as nan.
Please help!
#Euclidean Algorithm func
def EucAlgo(a, b):
if a==0:
return b
return EucAlgo(b % a,a)
def ExEucAlgo(a,b):
if a==0:
return b,0,1
gcd, s1, t1 = ExEucAlgo(b%a,a)
#gcd of a,b
s = t1 - (b/a) * s1
t = s1
return gcd, s, t
def ExEucAlgo_modInverse(a,b):
gcd, s, t = ExEucAlgo(b,a)
if (gcd == 1):
i = t % a
elif (gcd !=1):
print("There is no inverse modulo for the input.")
return i
def SqMul_ModularExpo(b, exp, n):
bin_exp = bin(exp)
base = b
for i in range (3, len(bin_exp)):
base = (base ** 2) % n
if(bin_exp[i]=='1'):
i+=1
base = (base * b) %n
return base
#RSA Key generation
p=9054583561027584891319616491815785011595937977633787663340258672121877196627062461308487615739189212918799813327175451021729047602129396754172486202100997
q=10115395220079214686776355235686624745626962891667413288473649946208213820942557513105240135405981494333016032659525466362014175268953946332375459648688023
n= p * q
phi_n= (p-1) * (q-1)
e= randint(1, phi_n - 1)
while((EucAlgo(e,phi_n)) !=1):
e = randint(1, (phi_n-1))
d = ExEucAlgo_modInverse(e,phi_n)
print(f"\nKpr={d}")
print(f"\nKpub=(n={n})\n \ne={e}")
The problem is that you are using float point division which will result in returning float a point which when dealing with large int can result in very large floats which python can't handle so the solution is to use integer division which means 5//2=2 not 2.5. The problem is that Now encrypting and decrypting data would result in wrong decryption. (You wont get 2 again) because of some bugs in your functions.
FIRST: use public exponent pf 65537(prime number) which is the default for all RSA implementations(see your browser certificates) rather than finding a random one. Then after calculating the extended Euclidean algorithm which is used to find modulo inverse you dont have to make any more calculations(just return this value if GCD is 1 otherwise raise an error or whatever).
Here is the complete code that works after removing some unneeded (functions, imports, and random public exponent) READ comments.
def EucAlgo(a, b):
if a == 0:
return b
return EucAlgo(b % a, a)
def ExEucAlgo(a,b):
if a==0:
return b, 0, 1
gcd, s1, t1 = ExEucAlgo(b%a, a)
# You dont use / use // to make integer division
s = t1 - (b//a) * s1
t = s1
return gcd, s, t
def ExEucAlgo_modInverse(a,b):
gcd, s, t = ExEucAlgo(a, b)
if (gcd == 1):
# Just return s which is the inverse of public exponent
return s
elif (gcd != 1):
# I think it's better to raise an error but it's up to you
print("There is no inverse modulo for the input.")
#RSA Key generation
p = 9054583561027584891319616491815785011595937977633787663340258672121877196627062461308487615739189212918799813327175451021729047602129396754172486202100997
q = 10115395220079214686776355235686624745626962891667413288473649946208213820942557513105240135405981494333016032659525466362014175268953946332375459648688023
n = p * q
phi_n = (p-1) * (q-1)
# Just use fixed prime public exponent rather than trying fixed ones
e = 65537
d = ExEucAlgo_modInverse(e, phi_n)
print(f"\nKpr={d}")
print(f"\nKpub=(n={n})\n \ne={e}")
# Try to encrypt and decrypt 36
ciphertext = pow(36, e, n)
print("Encrypted data {}".format(ciphertext))
print("Decrypted data is {}".format(pow(ciphertext, d, n)))
trying to write a function that will calculate present value of list of cash flows. I know that numpy can do this very easily but for an assignment I have to write my own function for this :/.
Here are the three cash flows in a list as well as discount rate.
cfList = [20, 50, 90]
r = 0.05
Here's the function i've written so far. f = 0 because I want to start with the first cash flow (in this case 20). i = 1 because for the first flow its raised to the 1st power and the second flow (50) will be squared and so on.
def npv(cfList, r):
f = 0
i = 1
pv = cfList[f] / ((1 + r) ** i)
while i < len(cfList):
f += 1
i += 1
return pv
print(npv(cfList, r))
However, this output only gives me the PV of the first cashflow, and not the sum of all three from the list. If you can help i appreciate it so much thanks !
You need to sum the individual cashflows within your function and return that. At the moment you are returning the value of pv of the first cashflow as you have a return statement in your for loop.
Also, I think the way you check your while loop against i will mean that you'll miss the last payment value. Usually you don't need to instantiate counter variables yourself (see my examples below):
def npv(cfList, r):
f = 0
i = 1
pv = cfList[f] / ((1 + r) ** i) # <-- this needs to be in the loop
while i < len(cfList): # <-- i will break loop before last payment is calculated.
f += 1
i += 1
return pv # <-- this return here is the issue
print(npv(cfList, r))
NPV being the sum of PV of all future cashflows, that is what you need to calculate. E.g.:
def npv(cfList, r):
sum_pv = 0 # <-- variable used to sum result
for i, pmt in enumerate(cfList, start=1): # <-- use of enumerate allows you to do away with the counter variables.
sum_pv += pmt / ((1 + r) ** i) # <-- add pv of one of the cash flows to the sum variable
return sum_pv # <-- only return the sum after your loop has completed.
Always remember that a return statement in a for-loop will break out of the loop the first time the return is encountered.
An alternate implementation would be to yield individual PVs from a PV generator and sum the results:
def pv_gen(cfList, r):
for i, pmt in enumerate(cfList, start=1):
yield pmt / ((1 + r) ** i)
print(sum(pv_gen(cfList, r)))
Returning the NPV of a list of cash flows would look like:
def npv(cfList, r):
return sum(f / ((1 + r) ** i) for i, f in enumerate(cfList, 1))
In []:
cfList = [20, 50, 90]
r = 0.05
npv(cfList, r)
Out[]:
142.14447683835436
If you're iterating across the list using the while loop, then you should have the action taking line of code within the while loop.
It also looks like your loop will be cutting early as i = 2 = len(cflist) on the second iteration (don't forget that python uses 0 based indexing) and because the return call is within the while loop.
This should work:
def npv(cfList, r):
f = 0
i = 1
pv = 0
while f <= len(cfList):
pv += (cfList[f] / ((1 + r) ** i))
f += 1
i += 1
return pv
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...
I need to calculate the arcsine function of small values that are under the form of mpmath's "mpf" floating-point bignums.
What I call a "small" value is for example e/4/(10**7) = 0.000000067957045711476130884...
Here is a result of a test on my machine with mpmath's built-in asin function:
import gmpy2
from mpmath import *
from time import time
mp.dps = 10**6
val=e/4/(10**7)
print "ready"
start=time()
temp=asin(val)
print "mpmath asin: "+str(time()-start)+" seconds"
>>> 155.108999968 seconds
This is a particular case: I work with somewhat small numbers, so I'm asking myself if there is a way to calculate it in python that actually beats mpmath for this particular case (= for small values).
Taylor series are actually a good choice here because they converge very fast for small arguments. But I still need to accelerate the calculations further somehow.
Actually there are some problems:
1) Binary splitting is ineffective here because it shines only when you can write the argument as a small fraction. A full-precision float is given here.
2) arcsin is a non-alternating series, thus Van Wijngaarden or sumalt transformations are ineffective too (unless there is a way I'm not aware of to generalize them to non-alternating series).
https://en.wikipedia.org/wiki/Van_Wijngaarden_transformation
The only acceleration left I can think of is Chebyshev polynomials. Can Chebyshev polynomials be applied on the arcsin function? How to?
Can you use the mpfr type that is included in gmpy2?
>>> import gmpy2
>>> gmpy2.get_context().precision = 3100000
>>> val = gmpy2.exp(1)/4/10**7
>>> from time import time
>>> start=time();r=gmpy2.asin(val);print time()-start
3.36188197136
In addition to supporting the GMP library, gmpy2 also supports the MPFR and MPC multiple-precision libraries.
Disclaimer: I maintain gmpy2.
Actually binary splitting does work very well, if combined with iterated argument reduction to balance the number of terms against the size of the numerators and denominators (this is known as the bit-burst algorithm).
Here is a binary splitting implementation for mpmath based on repeated application of the formula atan(t) = atan(p/2^q) + atan((t*2^q-p) / (2^q+p*t)). This formula was suggested recently by Richard Brent (in fact mpmath's atan already uses a single invocation of this formula at low precision, in order to look up atan(p/2^q) from a cache). If I remember correctly, MPFR also uses the bit-burst algorithm to evaluate atan, but it uses a slightly different formula, which possibly is more efficient (instead of evaluating several different arctangent values, it does analytic continuation using the arctangent differential equation).
from mpmath.libmp import MPZ, bitcount
from mpmath import mp
def bsplit(p, q, a, b):
if b - a == 1:
if a == 0:
P = p
Q = q
else:
P = p * p
Q = q * 2
B = MPZ(1 + 2 * a)
if a % 2 == 1:
B = -B
T = P
return P, Q, B, T
else:
m = a + (b - a) // 2
P1, Q1, B1, T1 = bsplit(p, q, a, m)
P2, Q2, B2, T2 = bsplit(p, q, m, b)
T = ((T1 * B2) << Q2) + T2 * B1 * P1
P = P1 * P2
B = B1 * B2
Q = Q1 + Q2
return P, Q, B, T
def atan_bsplit(p, q, prec):
"""computes atan(p/2^q) as a fixed-point number"""
if p == 0:
return MPZ(0)
# FIXME
nterms = (-prec / (bitcount(p) - q) - 1) * 0.5
nterms = int(nterms) + 1
if nterms < 1:
return MPZ(0)
P, Q, B, T = bsplit(p, q, 0, nterms)
if prec >= Q:
return (T << (prec - Q)) // B
else:
return T // (B << (Q - prec))
def atan_fixed(x, prec):
t = MPZ(x)
s = MPZ(0)
q = 1
while t:
q = min(q, prec)
p = t >> (prec - q)
if p:
s += atan_bsplit(p, q, prec)
u = (t << q) - (p << prec)
v = (MPZ(1) << (q + prec)) + p * t
t = (u << prec) // v
q *= 2
return s
def atan1(x):
prec = mp.prec
man = x.to_fixed(prec)
return mp.mpf((atan_fixed(man, prec), -prec))
def asin1(x):
x = mpf(x)
return atan1(x/sqrt(1-x**2))
With this code, I get:
>>> from mpmath import *
>>> mp.dps = 1000000
>>> val=e/4/(10**7)
>>> from time import time
>>> start = time(); y1 = asin(x); print time() - start
58.8485069275
>>> start = time(); y2 = asin1(x); print time() - start
8.26498985291
>>> nprint(y2 - y1)
-2.31674e-1000000
Warning: atan1 assumes 0 <= x < 1/2, and the determination of the number of terms might not be optimal or correct (fixing these issues is left as an exercise to the reader).
A fast way is to use a pre-calculated look-up table.
But if you look at e.g. a Taylor series for asin;
def asin(x):
rv = (x + 1/3.0*x**3 + 7/30.0*x**5 + 64/315.0*x**7 + 4477/22680.0*x**9 +
28447/138600.0*x**11 + 23029/102960.0*x**13 +
17905882/70945875.0*x**15 + 1158176431/3958416000.0*x**17 +
9149187845813/26398676304000.0*x**19)
return rv
You'll see that for small values of x, asin(x) ≈ x.
In [19]: asin(1e-7)
Out[19]: 1.0000000000000033e-07
In [20]: asin(1e-9)
Out[20]: 1e-09
In [21]: asin(1e-11)
Out[21]: 1e-11
In [22]: asin(1e-12)
Out[22]: 1e-12
E.g. for the value us used:
In [23]: asin(0.000000067957045711476130884)
Out[23]: 6.795704571147624e-08
In [24]: asin(0.000000067957045711476130884)/0.000000067957045711476130884
Out[24]: 1.0000000000000016
Of course it depends on whether this difference is relevant to you.