Differentiation in python using Sympy - python

How do i implement this kind of equation in python dC/dt = r + kI - dC where the left hand side are constants and the right hand side are varibles?
i am relatively new to python and as such can't really do much.
from sympy.solvers import ode
r=float(input("enter r:"))
k=float(input("enter k:"))
I=float(input("enter I:"))
d=float(input("enter d:"))
C=float(input("enter C:"))
dC/dt=x
x=r + kI-dC
print(x)
what it just does equate the values of x and not any differential, would like help getting this to work.
if possible i would like to get answer specifying the using of sympy,
but all answers are truly appreciated.

You asigned values to all the variables that are on the rhs of x so when you show x you see the value that it took on with the variables that you defined. Rather than input values, why not try solve the ode symbolically if possible?
>>> from sympy import *
>>> var('r k I d C t')
(r, k, I, d, C, t)
>>> eq = Eq(C(t).diff(t), r + k*I + d*C(t)) # note d*C(t) not d*C
>>> ans = dsolve(eq); ans
C(t) == (-I*k - r + exp(d*(C1 + t)))/d
Now you can substitute in values for the variables to see the result:
>>> ans.subs({k: 0})
C(t) == (-r + exp(d*(C1 + t)))/d

Related

Using sympy to solve an equation, python

I want to solve the below using Pythons sympy module instead of adapting what if have hand written. The result is x=26.8.
Any help appreciated.
Tks
EDIT:
my equation without sympy:
def cal_equ(total_vel=1.23, vel_vent_mg=17.74, vel_vent_tg=28.45, const=105):
a = (const / vel_vent_tg / const) + (1 / vel_vent_mg)
b = (total_vel - const / vel_vent_tg)
return b / a
from sympy import *
# create a symbol: it represents your unkown
x = symbols("x")
# create your constants
total_vel=1.23
vel_vent_mg=17.74
vel_vent_tg=28.45
const=105
# there are many ways to create an equation.
# here we create an equality, something that states that
# the left hand side is equal to the right hand side
eq = Eq((const - x) / vel_vent_tg - x / vel_vent_mg, total_vel)
# finally, we use the solve function to solve for the equation for x
sol = solve(eq, x)
sol[0].n()
# out: 26.8871034856029

Sympy - got two solutions from trigonometric equation, I was expecting only one

I'm trying to solve a trigonometric equation with sympy. I'm having issues understanding what sympy is doing: I was expecting only one solution, instead I got two. Here is the code:
import sympy as sp
sp.var("a, b, c, d, z")
myeq = sp.Eq(c * sp.sin(a * (b / 2 - z)) + d * sp.cos(a * (b / 2 - z)), 0)
sol = sp.solve(myeq, z)
print(sol)
Output: [(a*b - 4*atan((c - sqrt(c**2 + d**2))/d))/(2*a), (a*b - 4*atan((c + sqrt(c**2 + d**2))/d))/(2*a)]
The solution I was expecting is: [b / 2 + atan(c / d) / a]
What am I missing? For this specific case, is it possible to obtain a single solution?
If you rearrange your equation to combine the sin and cos into tan you will get what you are looking for:
>>> solve(c/d*tan(a*(b/2-z))-1,z)
[b/2 - atan(d/c)/a]
If you don't, SymPy will rewrite and solve in terms of exp...and in that case, as you can verify, it will be quadratic in exp(l*a*z).
An attempt at rewriting a two-arg sum as a ratio could be done like this:
>>> def ratio(eq):
... if isinstance(eq, Eq):
... eq=eq.rewrite(Add)
... A, B = eq.as_two_terms()
... if not A.is_Add and not B.is_Add:
... return Eq(A/B, 1)
>>> trigsimp(ratio(eq))
Eq(c*tan(a*b/2 - a*z)/d, 1)
(The function returns None if there aren't two terms to work with.) As you can see, in this case you get a new equation which will solve as you desired.

Sympy simplification of polynomial with complex coefficients

Working on a problem with polynomials with complex coefficients,
I am stuck with the following problem:
Let's say I have a polynomial P = λ^16*z + λ^15*z^2, where λ is complex.
I want to simplify having the following constraint: λ^14 = 1.
So, plugging in, we should get:
P = λ^2*z + λ*z^2.
I have tried P.subs(λ**14,1) but it doesn't work, because it assumes λ is real I guess. So it returns the original expression: P = λ^16*z + λ^15*z^2, without factoring out λ^14...
I don't know any simple way to achieve what you want in sympy, but you could substitute each value explicitly:
p = (λ**16)*z + (λ**15)*(z**2)
p = p.subs(λ**16, λ**2).subs(λ**15, λ**1)
>>> z**2*λ + z*λ**2
Why subs fails to work here:
subs only substitutes an expression x**m in x**n when m is a factor of n, e.g.:
p.subs(λ, 1)
>>> z**2 + z
p.subs(λ**2, 1)
>>> z**2*λ**15 + z
p.subs(λ**3, 1)
>>> z**2 + z*λ**16
p.subs(λ**6, 1)
>>> z**2*λ**15 + z*λ**16
etc.
If you assume that λ is real, this works:
lambda_, z = sym.symbols('lambda z', real=True)
print((lambda_**16*z + lambda_**15*z**2).subs(lambda_**14, 1))
z**2 + z
Edit:
It shouldn't actually work anyway because λ may be negative. What you want is only true if λ is a positive number.
You can use the ratsimpmodprime() function to reduce a polynomial modulo a set of other polynomials. There is also the reduce() function, which does something similar.
>>> P = λ**16*z + λ**15*z**2
>>> ratsimpmodprime(P, [λ**14 - 1])
z**2*λ + z*λ**2
This works:
P.simplify().subs(λ**15,1).expand()

python: changing symbol variable and assign numerical value

In order to calculate derivatives and other expressions I used the sympy package and said that T = sy.Symbol('T') now that I have calculated the right expression:
E= -T**2*F_deriv_T(T,rho)
where
def F_deriv_rho(T,rho):
ret = 0
for n in range(5):
for m in range(4):
inner= c[n,m]*g_rho_deriv_rho_np*g_T_np
ret += inner
return ret
that looks like this:
F_deriv_rho: [0.0 7.76971e-5*T 0.0001553942*T**2*rho
T*(-5.14488e-5*log(rho) - 5.14488e-5)*log(T) + T*(1.22574e-5*log(rho)+1.22574e-5)*log(T) + T*(1.89488e-5*log(rho) + 1.89488e-5)*log(T) + T(2.29441e-5*log(rho) + 2.29441e-5)*log(T) + T*(7.49956e-5*log(rho) + 7.49956e-5)*log(T)
T**2*(-0.0001028976*rho*log(rho) - 5.14488e-5*rho)*log(T) + T**2*(2.45148e-5*rho*log(rho) + 1.22574e-5*rho)*log(T) + T**2*(3.78976e-5*rho*log(rho) + 1.89488e-5*rho)*log(T) + T**2*(4.58882e-5*rho*log(rho) + 2.29441e-5*rho)*log(T) + T**2*(0.0001499912*rho*log(rho) + 7.49956e 5*rho)*log(T)]
with python I would like to change T (and rho) as a symbol to a value. How could I do that?
So, I would like to create 10 numbers like T_def = np.arange(2000, 10000, 800)and exchange all my sy.symbol(T) by iterating through the 10 values I created in the array.
Thanks for your help
I have found the solution according to this post:
How to substitute multiple symbols in an expression in sympy?
by usings "subs":
>>> from sympy import Symbol
>>> x, y = Symbol('x y')
>>> f = x + y
>>> f.subs({x:10, y: 20})
>>> f
30
There's more for this kinda thing here: http://docs.sympy.org/latest/tutorial/basic_operations.html
EDIT: A faster way would be by using "lamdify" as suggested by #Bjoern Dahlgren

Isolate all variables to LHS in sympy?

I am using sympy to process some equations. I want to write the equations in a canonical form such that variables of interest are all on LHS. For eg. if I have,
lhs = sympify("e*x +f")`
rhs = sympify("g*y + t*x +h")`
eq = Eq(lhs,rhs)
e*x + f == g*y + h + t*x
I need a function which can isolate a list of given variables (my so called canonical form), like
IsolateVariablesToLHS(eq,[x,y]) # desired function
(e-t)*x - g*y == h-f # now x and y are on LHS and remaining are on RHS
I have the assurance that I will only get linear equations, so this is always possible.
>>> import sympy as sm
>>> lhs = sm.sympify('e*x + f')
>>> rhs = sm.sympify('g*y + t*x + h')
>>> eq = sm.Eq(lhs, rhs)
Here's a simple construct
def isolateVariablesToLHS(eq, syms):
l = sm.S.Zero
eq = eq.args[0] - eq.args[1]
for e in syms:
ind = eq.as_independent(e)[1]
l += ind
eq -= ind
return sm.Eq(l, eq)
>>> isolateVariablesToLHS(eq, [x, y])
Eq(e*x - g*y - t*x, f - h)
With the equation as provided in the question combine all the terms and construct a filter for discovering the required variables.
>>> from itertools import filterfalse
>>> terms = eq.lhs - eq.rhs
>>> vars = ['x', 'y']
>>> filt = lambda t: any(t.has(v) for v in vars)
>>> result = Eq(sum(filter(filt, terms.args)), - sum(filterfalse(filt, terms.args))
>>> result
e*x - g*y - t*x == -f + h
I'm not familiar with sympy but I think this will work for equations consisting of proper atoms such as Symbols. Make sure you replace the vars list with the actual instantiated Symbols x, y instead of the 'ascii' representations. This is probably required to combine terms that have variables in common.
filter and filterfalse might have different names in python 2.x, but this functionality is probably still in the itertools package.

Categories