Visible Deprecation Warning Python - python

I am trying to make a model in python for an economics dissertation and in calculating a function:
elif wage_online == max(wages):
# after going to online you get the highest wage after cost of education
learning_benefit = int(np.int((1 + gamma_online_learning) * x[0]) * exp(np.int(bivariate_distribution[x[0] - 1, x[1] - 1])))
social_benefit = int(((1 + gamma_online_social) * np.int(x[1])) * exp(np.int(bivariate_distribution[x[0] - 1, x[1] - 1])))
sigma_social.append(social_benefit)
sigma_learning.append(learning_benefit)
I get the following error
/Users/sa/Documents/Dissertation/first_defiation.py:160: VisibleDeprecationWarning: using a non-integer number instead of an integer will result in an error in the future
learning_benefit = int(np.int((1 + gamma_online_learning) * x[0]) * exp(np.int(bivariate_distribution[x[0] - 1, x[1] - 1])))
I tried to fix this by including the value in the exp function as np.int, but to no avail. does anyone know which variable the warning is coming from?

Looks like you missed the one place where int was needed, inside the square brackets:
social_benefit = (1 + gamma_online_social) * x[1] * exp(
bivariate_distribution[int(x[0] - 1), int(x[1] - 1)] # needed here for indexing
)
In future, you can use warnings.filterwarnings('error') to find the exact traceback of the warning, which would have pointed you to __getitem__

Related

How to get a value of function corresponding to certain coordinates without actually replacing the values in code?

I have an array of values x and y and have a function f(x,y). I want to get the value of f(x1,y1) corresponding to (x1,y1). How can we get it?
khmax = np.arange(0,0.5,0.001)
Ncmax = np.arange(0,0.5,0.001)
[X, Y] = np.meshgrid(Ncmax,khmax)
sum_real = 0
sum_imag = 0
for l in range (0,N): # C_jl * P_lj
sum_imag = sum_imag + (matrix_C[j_node-1][l])*(np.sin(Y*(x_j(l+1)-x_j(j_node)) / hmax))
sum_real = sum_real + (matrix_C[j_node-1][l])*(np.cos(Y*(x_j(l+1)-x_j(j_node)) / hmax))
Aj_real = (X * sum_real)
Aj_imag = (X * sum_imag)
G_imag = -Aj_imag + (2 * (Aj_real) * (Aj_imag)) / 2 - ((3 * ((Aj_real)**2) * (Aj_imag)) -((Aj_imag)**3)) + ((4*(Aj_real)*(Aj_imag))*((Aj_real)**2 - (Aj_imag)**2))/24
G_real = 1 - (Aj_real) + (((Aj_real)**2 - (Aj_imag)**2)/2) - ((((Aj_real)**3 - 3*(Aj_real)*((Aj_imag)**2)))/6) + ((((((Aj_real)**2 - (Aj_imag)**2 )**2- 4*((Aj_real)**2)*((Aj_imag)**2))))/ 24)
mod_G = (((G_real)**2) + ((G_imag)**2))**(0.5)
In this code mod_G is a function of (khmax, Ncmax). I want to get the value of mod_G corresponding to (khmax,Ncmax) suppose(0.1,0.1). I don't want to put the value of (khmax, Ncmax) into the function directly(i.e not replacing khmax with 0.1 and Ncmax with 0.1). How can I get mod_G without doing this?
Could you try defining it as an actual python function, i.e. using the def keyword and then calling it with the two parameters? This way you could just easily call it as mod_G(0.1,0.1) without changing anything else.

Replacing Sympy indexed symbols with numeric values

I have a sympy expression I want to put numerical values in after differentiating it. The variables I want to replace are all the x[i], y[i] and R_abs[i] in the last expression and are numpy arrays a la
rx=np.array([-0.357, -0.742, -1.078, 0.206])
But trying subs or replace either doesn't do anything or raises the error that Symbols dont allow indexation for for example e1.subs(x[1],rx[0]). I pretty much went through every iteration I could think of to no avail.
import sympy as sp
r0,ge_x,ge_y,bx,by = sp.symbols('r0,ge_x,ge_y,bx,by', real=True) #Main symbols
i,x,y,R_abs = sp.symbols('i,x,y,R_abs', real=True) #Helper symbols
n=4
s2=sp.Sum((bx+r0*sp.Indexed('x',i)/sp.Indexed('R_abs',i)+ge_x*sp.Indexed('x',i)+ge_y*sp.Indexed('y',i)-sp.Indexed('x',i))**2+(by+r0*sp.Indexed('y',i)/sp.Indexed('R_abs',i)-ge_x*sp.Indexed('y',i)+ge_y*sp.Indexed('x',i)-sp.Indexed('y',i))**2,(i,1,n))
e1=sp.Eq(sp.diff(s2,bx).doit(),0)
With e1 then being
Eq(8*bx + 2*ge_x*x[1] + 2*ge_x*x[2] + 2*ge_x*x[3] + 2*ge_x*x[4] + 2*ge_y*y[1] + 2*ge_y*y[2] + 2*ge_y*y[3] + 2*ge_y*y[4] + 2*r0*x[4]/R_abs[4] + 2*r0*x[3]/R_abs[3] + 2*r0*x[2]/R_abs[2] + 2*r0*x[1]/R_abs[1] - 2*x[1] - 2*x[2] - 2*x[3] - 2*x[4], 0)
In here I would like to replace all the x, y, and R_abs with their numerical values.
I've always struggled with indexing in SymPy. Turns out, making Function instances are way easier than indexing instances of Symbol. It also makes notation simpler.
Also note that by using strings in your expression, I think SymPy makes its own symbols with those same string names but they can't be accessed with yours since your symbols are different. At least that's what happens sometimes to me.
Here is a working sample:
import sympy as sp
r0, ge_x, ge_y, bx, by = sp.symbols("r0 ge_x ge_y bx by", real=True) # main symbols
# define functions that will take the role of indexed symbols
x = sp.Function("x")
y = sp.Function("y")
R_abs = sp.Function("R_abs")
i = sp.Symbol("i", positive=True, integer=True)
n = 4
s2 = sp.Sum((bx + r0 * x(i) / R_abs(i) + ge_x * x(i) + ge_y * y(i) - x(i)) ** 2 +
(by + r0 * y(i) / R_abs(i) - ge_x * y(i) + ge_y * x(i) - y(i)) ** 2, (i, 1, n))
s2_prime = sp.diff(s2, bx).doit().simplify()
print(s2_prime)
# whatever lists you want. Can even be an instance of `np.ndarray`
# note that you summed from 1 to n so the 0th element will not be used
x_array = [0, 1, 2, 3, 4]
y_array = [4, 3, 2, 1, 0]
R_abs_array = [-10, 10, 5, 4, 3]
# define a function to access these array elements
x_function = lambda index: x_array[index]
y_function = lambda index: y_array[index]
R_abs_function = lambda index: R_abs_array[index]
# no idea why subs does not work and you MUST keep the same name for the variable.
# you can't have for example `evaluated_s2_prime = ...`.
# Probably something to do with forcing sp to remove references to `x`?
s2_prime = s2_prime.replace(x, x_function).replace(y, y_function).replace(R_abs, R_abs_function)
print(s2_prime)
Producing:
8*bx + 2*ge_x*x(1) + 2*ge_x*x(2) + 2*ge_x*x(3) + 2*ge_x*x(4) + 2*ge_y*y(1) + 2*ge_y*y(2) + 2*ge_y*y(3) + 2*ge_y*y(4) + 2*r0*x(4)/R_abs(4) + 2*r0*x(3)/R_abs(3) + 2*r0*x(2)/R_abs(2) + 2*r0*x(1)/R_abs(1) - 2*x(1) - 2*x(2) - 2*x(3) - 2*x(4)
8*bx + 20*ge_x + 12*ge_y + 31*r0/6 - 20

sympy.subs - wrong substitution

I have this equation:
(1 - tau2)**3 + (tau2-tau1)**5
And I want to substitute (1-tau2) by (1-tau3). However, I get the wrong result.
This is my code:
tau1,tau2,tau3= symbols('tau1,tau2,tau3')
exp= (1-tau2)**3+(tau2-tau1)**5
res=exp.subs((1-tau2),(1-tau3))
print('exp:',exp)
print('res:',res)
And the result is:
exp= (1 - tau2)**3 + (-tau1 + tau2)**5
res= (1 - tau3)**3 + (-tau1 + tau3)**5
But it should be:
res= (1 - tau3)**3 + (-tau1 + tau2)**5
How can I solve this?
Sometimes you want a smart substitution -- in this case, recognizing that your substitution is equivalent to replacing tau2 with tau3 -- and sometimes you want an exact substitution. In case of the latter, use xreplace:
>>> from sympy.abc import x, y
>>> (1-x)**3+(x-y)**5
(1 - x)**3 + (x - y)**5
>>> _.xreplace({1-x: z})
z**3 + (x - y)**5

TypeError: unhashable type: 'dict' in python

I'm getting an error message about dictionaries despite having never used a dictionary anywhere in my code
Here is my code:
mm=[]
soln=[]
for i in range(len(momvec)):
string = str(momvec[i])
num = string[2:]
mm.append(Symbol('x'+num))
print num
print mm
soln.append(solve(mom[i]-momvec[i],mm))
print type(MFK[0])
for m in range(0,len(MFK)):
for i in range(0,len(mm)):
print MFK[m]
MFK[m]= Subs(MFK[m],mm[i], soln[i]).doit()
What I am trying to do is replace some items in the list MFK with what is indicated by mm with the contents of soln iteratively.
The traceback:
Traceback (most recent call last):
File "MEA.py", line 313, in <module>
MFK_final(numMoments)
File "MEA.py", line 242, in MFK_final
MFK[m]= Subs(MFK[m],mm[i], soln[i]).doit()
File "/cluster/soft/linux64/epd/lib/python2.7/site-packages/sympy/core/function.py", line 1270, in __new__
pts = sorted(set(point), key=default_sort_key)
TypeError: unhashable type: 'dict'
values for mom, momvec and MFK respectively:
[x2 - y_0**2]
[ym2]
[-2*c_0*y_0*(y_0 - 1) - 2*c_0*(-y_0**2 + yx1*(y_0**2/yx1 + 1)) + 2*c_1*(0.5*c_2 - 0.5*y_0), 4.0*c_0*y_0**2 - 4.0*c_0*y_0 + 2.0*c_1*c_2 - 2.0*c_1*y_0 - (-y_0**2 + yx1*(y_0**2/yx1 + 1))*(8.0*c_0*y_0 - 8.0*c_0 + 2.0*c_1)]
Printing output to screen it appears as though the first loop goes fine, then it throws the error in the title. Does anyone know how I could solve this?
Many thanks
Your soln[i] is a dictionary, but it needs to be a SymPy expression (the one you plan to substitute into MFK[m] for mm[i]).
From your description, I can't reproduce your error. That is, I made a Python file:
from sympy import *
x2 = Symbol("x2")
y_0 = Symbol("y_0")
ym2 = Symbol("ym2")
c_0 = Symbol("c_0")
c_1 = Symbol("c_1")
c_2 = Symbol("c_2")
yx1 = Symbol("yx1")
mom = [x2 - y_0**2]
momvec = [ym2]
MFK = [-2*c_0*y_0*(y_0 - 1) - 2*c_0*(-y_0**2 + yx1*(y_0**2/yx1 + 1)) + 2*c_1*(0.5*c_2 - 0.5*y_0), 4.0*c_0*y_0**2 - 4.0*c_0*y_0 + 2.0*c_1*c_2 - 2.0*c_1*y_0 - (-y_0**2 + yx1*(y_0**2/yx1 + 1))*(8.0*c_0*y_0 - 8.0*c_0 + 2.0*c_1)]
mm=[]
soln=[]
for i in range(len(momvec)):
string = str(momvec[i])
num = string[2:]
mm.append(Symbol('x'+num))
print num
print mm
soln.append(solve(mom[i]-momvec[i],mm))
print type(MFK[0])
for m in range(0,len(MFK)):
for i in range(0,len(mm)):
print MFK[m]
MFK[m]= Subs(MFK[m],mm[i], soln[i]).doit()
and it simply outputs
2
[x2]
<class 'sympy.core.add.Add'>
-2*c_0*y_0*(y_0 - 1) - 2*c_0*(-y_0**2 + yx1*(y_0**2/yx1 + 1)) + 2*c_1*(0.5*c_2 - 0.5*y_0)
4.0*c_0*y_0**2 - 4.0*c_0*y_0 + 2.0*c_1*c_2 - 2.0*c_1*y_0 - (-y_0**2 + yx1*(y_0**2/yx1 + 1))*(8.0*c_0*y_0 - 8.0*c_0 + 2.0*c_1)
without any errors or tracebacks.
However, if you do find the point in the code where the hidden dictionary appears, the reason dictionaries shouldn't be hashable (and therefore usable as keys in other dictionaries) is because they're mutable. If you use one as a key and then later change a value somewhere deep in its structure, you could get weird x != x style errors. You could fix such an error with a hashable frozen dictionary...

Python: "long int too large to convert to float" when calculating pi

I get this error when using a python script that calculates pi using the Gauss-Legendre algorithm. You can only use up to 1024 iterations before getting this:
C:\Users\myUsernameHere>python Desktop/piWriter.py
End iteration: 1025
Traceback (most recent call last):
File "Desktop/piWriter.py", line 15, in <module>
vars()['t' + str(sub)] = vars()['t' + str(i)] - vars()['p' + str(i)] * math.
pow((vars()['a' + str(i)] - vars()['a' + str(sub)]), 2)
OverflowError: long int too large to convert to float
Here is my code:
import math
a0 = 1
b0 = 1/math.sqrt(2)
t0 = .25
p0 = 1
finalIter = input('End iteration: ')
finalIter = int(finalIter)
for i in range(0, finalIter):
sub = i + 1
vars()['a' + str(sub)] = (vars()['a' + str(i)] + vars()['b' + str(i)])/ 2
vars()['b' + str(sub)] = math.sqrt((vars()['a' + str(i)] * vars()['b' + str(i)]))
vars()['t' + str(sub)] = vars()['t' + str(i)] - vars()['p' + str(i)] * math.pow((vars()['a' + str(i)] - vars()['a' + str(sub)]), 2)
vars()['p' + str(sub)] = 2 * vars()['p' + str(i)]
n = i
pi = math.pow((vars()['a' + str(n)] + vars()['b' + str(n)]), 2) / (4 * vars()['t' + str(n)])
print(pi)
Ideally, I want to be able to plug in a very large number as the iteration value and come back a while later to see the result.
Any help appreciated!
Thanks!
Floats can only represent numbers up to sys.float_info.max, or 1.7976931348623157e+308. Once you have an int with more than 308 digits (or so), you are stuck. Your iteration fails when p1024 has 309 digits:
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216L
You'll have to find a different algorithm for pi, one that doesn't require such large values.
Actually, you'll have to be careful with floats all around, since they are only approximations. If you modify your program to print the successive approximations of pi, it looks like this:
2.914213562373094923430016933707520365715026855468750000000000
3.140579250522168575088244324433617293834686279296875000000000
3.141592646213542838751209274050779640674591064453125000000000
3.141592653589794004176383168669417500495910644531250000000000
3.141592653589794004176383168669417500495910644531250000000000
3.141592653589794004176383168669417500495910644531250000000000
3.141592653589794004176383168669417500495910644531250000000000
In other words, after only 4 iterations, your approximation has stopped getting better. This is due to inaccuracies in the floats you are using, perhaps starting with 1/math.sqrt(2). Computing many digits of pi requires a very careful understanding of the numeric representation.
As noted in previous answer, the float type has an upper bound on number size. In typical implementations, sys.float_info.max is 1.7976931348623157e+308, which reflects the use of 10 bits plus sign for the exponent field in a 64-bit floating point number. (Note that 1024*math.log(2)/math.log(10) is about 308.2547155599.)
You can add another half dozen decades to the exponent size by using the Decimal number type. Here is an example (snipped from an ipython interpreter session):
In [48]: import decimal, math
In [49]: g=decimal.Decimal('1e12345')
In [50]: g.sqrt()
Out[50]: Decimal('3.162277660168379331998893544E+6172')
In [51]: math.sqrt(g)
Out[51]: inf
This illustrates that decimal's sqrt() function performs correctly with larger numbers than does math.sqrt().
As noted above, getting lots of digits is going to be tricky, but looking at all those vars hurts my eyes. So here's a version of your code after (1) replacing your use of vars with dictionaries, and (2) using ** instead of the math functions:
a, b, t, p = {}, {}, {}, {}
a[0] = 1
b[0] = 2**-0.5
t[0] = 0.25
p[0] = 1
finalIter = 4
for i in range(finalIter):
sub = i + 1
a[sub] = (a[i] + b[i]) / 2
b[sub] = (a[i] * b[i])**0.5
t[sub] = t[i] - p[i] * (a[i] - a[sub])**2
p[sub] = 2 * p[i]
n = i
pi_approx = (a[n] + b[n])**2 / (4 * t[n])
Instead of playing games with vars, I've used dictionaries to store the values (the link there is to the official Python tutorial) which makes your code much more readable. You can probably even see an optimization or two now.
As noted in the comments, you really don't need to store all the values, only the last, but I think it's more important that you see how to do things without dynamically creating variables. Instead of a dict, you could also have simply appended the values to a list, but lists are always zero-indexed and you can't easily "skip ahead" and set values at arbitrary indices. That can occasionally be confusing when working with algorithms, so let's start simple.
Anyway, the above gives me
>>> print(pi_approx)
3.141592653589794
>>> print(pi_approx-math.pi)
8.881784197001252e-16
A simple solution is to install and use the arbitrary-precisionmpmath module which now supports Python 3. However, since I completely agree with DSM that your use ofvars()to create variables on the fly is an undesirable way to implement the algorithm, I've based my answer on his rewrite of your code and [trivially] modified it to make use ofmpmath to do the calculations.
If you insist on usingvars(), you could probably do something similar -- although I suspect it might be more difficult and the result would definitely harder to read, understand, and modify.
from mpmath import mpf # arbitrary-precision float type
a, b, t, p = {}, {}, {}, {}
a[0] = mpf(1)
b[0] = mpf(2**-0.5)
t[0] = mpf(0.25)
p[0] = mpf(1)
finalIter = 10000
for i in range(finalIter):
sub = i + 1
a[sub] = (a[i] + b[i]) / 2
b[sub] = (a[i] * b[i])**0.5
t[sub] = t[i] - p[i] * (a[i] - a[sub])**2
p[sub] = 2 * p[i]
n = i
pi_approx = (a[n] + b[n])**2 / (4 * t[n])
print(pi_approx) # 3.14159265358979

Categories