I am trying to use SymPy to solve for the variable p by defining the function as shown.
On execution, an error " can't convert expression to float" is being raised. I have just started learning Python so I will really appreciate if someone can help me understand what's causing the error and suggest a way to fix it and solve for p.
Note- For the assigned vales of G, F and h, p= 91.65
Thanks!
G=0.05
F=0.32
h=231 # these values should yield p = 91.65
def get_p (G,F,h):
p = symbols('p')
C2 = 3.14 * h * F*F
C1= 3.14 * G *h
eq_p=Eq(p *(1/math.cosh(p/C1))**2 - C1* (math.tanh(p/C1))+C2==0) #raises the error "cant convert expression to float"
sol_p=solve(eq_p)
return sol_p
p= get_p (G, F, h)
print(p)
When you get an error like this and have no idea why it is happening use an interactive session to work with smaller and smaller parts of the offending line until the problem is located. In your case the issue is that math.cosh and math.tanh expect numeric arguments and you are giving it something with a SymPy symbol p. Fortunately, Sympy has its own hyperbolic functions. So, remove the 'math.' and then at the top use:
>>> from sympy import cosh, tanh
But another problem will become apparent: the Eq argument looks like 'expr==0' and it should be 'expr, 0' since args of Eq are the L and R in L == R: it should be in the form of Eq(L, R).
Finally, check your expression with print(eq_p.subs(p, 91.65))...it doesn't appear to be close to zero (and a plot of the function confirms that it does not go through 0). So you have perhaps interpreted the original expression you are trying to solve incorrectly in writing it here.
Once you have the right equation then I would recommend using nsolve(eq_p, guess) where guess is an approximate value of the solution for p. You can import that with from sympy import nsolve.
Related
when I'm running the following code in python and entering "x^2y^2", "xy" and so on, I'm getting an empty set:
from sympy import *
x, y, u = symbols('x y u',positive=True)
utility = sympify(input())
utility_function = Eq(u,utility)
solve(utility_function, y)
When I remove the positive = True, I'm getting solutions. How can I change my code that I only get the positive solution?
I don't have the same issue, but you should really pass the symbols defined as positive to the sympify function; if you don't, then symbols without assumptions will be created.
sympify('v',locals={'v':var('v',positive=True)}).is_positive
u = var('u', positive=True) # now part of locals()
sympify('u',locals=locals()).is_positive
I've got this equation from mathematical model to know the thermal behavior of a battery.
dTsdt = Ts * a+ Ta * b + dTadt * c + d
However, i can't get to solve it due to the nested derivatives.
I need to solve the equation for Ts and Ta.
I tried to define it as follows, but python does not like it and several eŕrors show up.
Im using scipy.integrate and the solver ODEint
Since the model takes data from vectors, it has to be solved for every time step and record the output accordingly.
I also tried assinging the derivatives to a variable v1,v2, and then put everything in an equation without derivatives like the second approach shown as follows.
def Tmodel(z,t,a,b,c,d):
Ts,Ta= z
dTsdt = Ts*a+ Ta*b + dTadt*c+ d
dzdt=[dTsdt]
return dzdt
z0=[0,0]
# solve ODE
for i in range(0,n-1):
tspan = [t[i],t[i+1]]
# solve for next step
z = odeint(Tmodel,z0,tspan,arg=(a[i],b[i],c[i],d[i],))
# store solution for plotting
Ts[i] = z[1][0]
Ta[i] = z[1][1]
# next initial condition
z0 = z[1]
def Tmodel(z,t,a,b,c,d):
Ts,v1,Ta,v2= z
# v1= dTsdt
# v2= dTadt
v1 = Ts*a+ Ta*b + v2*c+ d
dzdt=[v1,v2]
return dzdt
That did not work either.I believe there might be a solver capable of solving that equation or the equation must be decouple in a way and solve accordingly.
Any advice on how to solve such eqtn with python would be appreciate it.
Best regards,
MM
Your difficulty seems to be that you are given Ta in a form with no easy derivative, so you do not know where to take it from. One solution is to avoid this derivative completely and solve the system for y=Ts-c*Ta. Substitute Ts=y+c*Ta in the right side to get
dy/dt = y*a + Ta*(b+c*a) + d
Of course, this requires then a post-processing step Ts=y+c*Ta to get to the requested variable.
If Ta is given as function table, use an interpolation function to get values at any odd time t that is demanded by the ODE solver.
Ta_func = interp1d(Ta_times,Ta_values)
def Tmodel(y,t,a,b,c,d):
Ta= Ta_func(t)
dydt = y*a+ Ta*(b+c*a) + d
return dydt
y[0] = Ts0-c*Ta_func(t[0])
for i in range(len(t)-1):
y[i+1] = odeint(Tmodel,y[i],t[i:i+2],arg=(a[i],b[i],c[i],d[i],))[-1,0]
Ts = y + c*Ta_func(t)
from sympy import *
s = Symbol("s")
y = Symbol("y")
raw_function = 1/(150.0-0.5*y)
result = integrate(raw_function, (y, 0, s)
The above snippet gets a wrong result: -2.0*log(0.5*s - 150.0) + 10.0212705881925 + 2.0*I*pi,
but we can know the right result is -2.0*log(-0.5*s + 150.0) + 10.0212705881925, so what's wrong?
Are you sure about the correct result, WolframAlpha says it is the same as Sympy here.
Edit:
This function diverges (and the integral too) around y=300, see its plot here (it diverges the same way as 1/x does but offset to y=300)
Meaning that you are constrained to s < 300 to have a well defined (and finite) integrale. In that range, the value of the integral is equal to what sympy is providing you.
These 2 variations of n choose r code got different answer although followed the correct definition
I saw that this code works,
import math
def nCr(n,r):
f = math.factorial
return f(n) // f(r) // f(n-r)
But mine did not:
import math
def nCr(n,r):
f = math.factorial
return int(f(n) / (f(r) * f(n-r)))
Use test case nCr(80,20) will show the difference in result. Please advise why are they different in Python 3, thank you!
No error message. The right answer should be 3535316142212174320, but mine got 3535316142212174336.
That's because int(a / b) isn't the same as a // b.
int(a / b) evaluates a / b first, which is floating-point division. And floating-point numbers are prone to inaccuracies, roundoff errors and the like, as .1 + .2 == 0.30000000000000004. So, at some point, your code attempts to divide really big numbers, which causes roundoff errors since floating-point numbers are of fixed size, and thus cannot be infinitely precise.
a // b is integer division, which is a different thing. Python's integers can be arbitrarily huge, and their division doesn't cause roundoff errors, so you get the correct result.
Speaking about floating-point numbers being of fixed size. Take a look at this:
>>> import math
>>> f = math.factorial
>>> f(20) * f(80-20)
20244146256600469630315959326642192021057078172611285900283370710785170642770591744000000000000000000
>>> f(80) / _
3.5353161422121743e+18
The number 3.5353161422121743e+18 is represented exactly as shown here: there is no information about the digits after the last 3 in 53...43 because there's nowhere to store it. But int(3.5353161422121743e+18) must put something there! Yet it doesn't have enough information. So it puts whatever it wants to so that float(int(3.5353161422121743e+18)) == 3.5353161422121743e+18.
I am trying to find the integration of Sin^2(x)/x^2 using trapezoidal rule but while running it is saying x id not defined. Can anyone suggest me what is wrong?
import math
c=math.sin`
def trapezoidal(f, a, b, N):
if x!=0:
h=(b-a)/N
s=0.0
s+=f(a)/2.0
for i in range (1,N):
s+=f(a+i*h)
s+=f(b)/2.0
Y=s*h
else:
y=1
return Y`
for n in range (1,11):
N=2**n
result=trapezoidal(lambda x:((c(x)*c(x))/(x**2)), 0, 1000, N)
print(repr(n).rjust(10), repr(result).rjust(30))`
You're not calling the x in the function. In your case you want to loop over every element in the function f.
If you don't want to use the pythonic way, you can have a look at numpy and scipy. These packages offer optimised functions for basic operation such as integrations and matrix calculations. Have a look at np.trapz (https://docs.scipy.org/doc/numpy/reference/generated/numpy.trapz.html), sp.integrate (https://docs.scipy.org/doc/scipy-0.18.1/reference/tutorial/integrate.html)