Issue with differentiation using sympy - python

I am trying to differentiate this equation using SymPy:
What I wanted to achieve is this result:
But when I type this code into to execute, it gives me this result:
Here is my current code:
import sympy as sp
# declare symbols
t = sp.Symbol('t')
deriv = sp.diff((t*(sp.cos(t)))/(1-t)**2)
# Find the derivative
sp.simplify(deriv)
Is there a way to achieve the desired result?

That is the same result. Break the result you get on the "+" and you get the same thing
Looking for the "simplest" form is not a well-defined problem and sympy can't guess which form you are looking for. You can always call sp.simplify on both the result you get and the desired answer. sympy will derive the same expression for both. In your case
result = sp.simplify(deriv)
desired = sp.simplify((-2 * t * sp.cos(t))/(t - 1)**3 + (-t * sp.sin(t) + sp.cos(t))/(t - 1)**2)
# result == desired

Related

How do I evaluate a Sympy function in Python?

I am facing a major issues in python using sympy. I didn't find any solutions to my problem or at least, I couldn't apply the solutions I found on my problem.
import sympy as sp
import math as ma
import numpy as np
E1=72500
A1=15
U01,s,C1,U02 = sp.symbols("U01,s,C1,U02")
u1 = sp.symbols("u1", cls=sp.Function)
eqs=sp.Eq(E1*A1*u1(s).diff(s)+180+U02,0)
sol=sp.dsolve(eqs,dict=True)
expr=sol.args[1]
u1=sp.lambdify(s,expr.subs(C1,U01))
print(u1(s))
#gives me : U01 - 9.19540229885057e-7*U02*s - 0.00016551724137931*s
expression1=u1(10)-54
expression2=u1(7)-99
eq1=sp.Eq(expression1,0)
eq2=sp.Eq(expression2,0)
solution = sp.solve([eq1,eq2],[U01,U02])
U01=float(solution[U01])
U02=float(solution[U02])
print(u1(55))
# gives me : U01 - 5.05747126436782e-5*U02 - 0.00910344827586207
I want to evaluate u1(55), but I still get the expression.
Thank you very much in advance.
I expect to get :
-621.0000000000018
Don't override U01 and U02 by numerical values, use intermediate variables. You have to evaluate your lambda function with solution previously found:
...
solution = sp.solve([eq1, eq2], [U01, U02])
U01_val = float(solution[U01])
U02_val = float(solution[U02])
result = u1(55).evalf(subs={U01: U01_val, U02: U02_val})
print(result)
# Output
-621.000000000001
Or simply:
...
solution = sp.solve([eq1, eq2], [U01, U02])
result = u1(55).evalf(subs=solution)
print(result)
# Output
-621.000000000001

Sympy: How to get simplified commutators using the second quantization module?

So I want to use the fact that [b,bd]=1, where [] is the commutator, to get some commutators of more complicated expressions using sympy instead of doing it by hand, but instead, I get huge expressions that contain the commutator but it is not replaced for 1, here's the code
from sympy import *
from sympy.physics.secondquant import *
comm1=simplify(Commutator(B(0),Bd(0)).doit())
comm1
the output in this case is 1 , it corresponds to the [b,bd]=1 case, but if I input a more complicated expression such as
w1,w2,g=symbols('w1 w1 g')
H=w1*B(0)*Bd(0)+w2*B(1)*Bd(1)+g*Bd(0)*B(1)+conjugate(g)*Bd(1)*B(0)
comm2=simplify(Commutator(H,B(0)))
print(simplify(comm2))
I get
-g*(AnnihilateBoson(0)*CreateBoson(0)*AnnihilateBoson(1) - CreateBoson(0)*AnnihilateBoson(1)*AnnihilateBoson(0)) - w1*(AnnihilateBoson(0)*AnnihilateBoson(1)*CreateBoson(1) - AnnihilateBoson(1)*CreateBoson(1)*AnnihilateBoson(0)) + w1*(AnnihilateBoson(0)*CreateBoson(0)*AnnihilateBoson(0) - AnnihilateBoson(0)**2*CreateBoson(0)) - conjugate(g)*(AnnihilateBoson(0)*CreateBoson(1)*AnnihilateBoson(0) - CreateBoson(1)*AnnihilateBoson(0)**2)
Which clearly would be simplified quite a lot if [b,bd]=1 was substituted, Does anyone know how to this ? or could anyone point me to another tool capable of doing this?
The key trick is always to use the commutation relation to move either 'a' or 'a^\dagger' to the left, until you cannot do that anymore.
I don't have a good Sympy answer, but since you asked about other tools, here's a shameless plug about how you do it in Cadabra (https://cadabra.science) (which uses Sympy for various things, though not this particular computation). First setup the two sets of creation/annihilation operators using:
{a_{0}, ad_{0}}::NonCommuting;
{a_{1}, ad_{1}}::NonCommuting;
{a_{0}, ad_{0}, a_{1}, ad_{1}}::SortOrder.
They'll print nicer with
\bar{#}::Accent;
ad_{n?}::LaTeXForm("a^\dagger",n?,"").
Your Hamiltonian:
H:= w_{1} a_{0} ad_{0} + w_{2} a_{1} ad_{1} + g ad_{0} a_{1} + \bar{g} ad_{1} a_{1};
The commutator you want to compute:
ex:= #(H) a_{0} - a_{0} #(H);
Just expanding this (without simplification using the [a,ad]=1 commutator) is done with
distribute(ex);
sort_product(ex);
where the 2nd line moves operators with different subscripts through each other, but keeps the order of operators with the same subscripts. Applying the commutator until the expression no longer changes:
converge(ex):
substitute(ex, $a_{n?} ad_{n?} = ad_{n?} a_{n?} + 1$)
distribute(ex)
;
to finally give '-a_0 w_1 - a_1 g'.

Subs object still remains after calling doit method in sympy

I am trying to calculate general composite function derivative using sympy. In my specific case script is the following:
from sympy import *
t=symbols('t')
p=Function('p')
x=Function('x')
v=diff(x(p(t)),t)
a=diff(v,t)
for variable a it yields:
Derivative(p(t), t)**2*Derivative(x(p(t)), p(t), p(t)) + Derivative(p(t), t, t)*Subs(Derivative(x(_xi_1), _xi_1), (_xi_1,), (p(t),))
If I call doit(), answer still contains subs object
a.doit() #answer: Derivative(p(t), t)**2*Subs(Derivative(x(_xi_3), _xi_3, _xi_3), (_xi_3,), (p(t),)) + Derivative(x(p(t)), p(t))*Derivative(p(t), t, t)
Mathematically the answer is correct but I still need output in following format (without Subs objects):
Derivative(p(t), t)**2*Derivative(x(p(t)), p(t), p(t)) + Derivative(x(p(t)), p(t))*Derivative(p(t), t, t)
Is there any way to achieve desired result? To be clear this example is very simplified compared to my original expression so I need general way to get desired output.
Indeed, repeated applications of doit() in this case result in flip-flopping between two forms of the expression: half the time the first addend has Subs, half the time it's the second.
But you can deal with the issue as follows:
for b in a.atoms(Subs):
a = a.xreplace({b: b.doit()})
This returns Derivative(p(t), t)**2*Derivative(x(p(t)), p(t), p(t)) + Derivative(x(p(t)), p(t))*Derivative(p(t), t, t) as desired.
The trick is that atoms(Subs) is the set of all Subs objects in the expression, and doit is applied only to them, not to Derivative objects where it only messes things up. (Ideally, doit would not mess Derivative objects up in the first place...)

Sympy coeff not consistent with as_independent

I have the following snippet of code
import sympy
a = sympy.symbols('a')
b = sympy.symbols('b')
c = sympy.symbols('c')
print((a*b).coeff(c,0))
print((a*b).as_independent(c)[0])
I don't understand why the two print statements print different output. According to the documentation of coeff:
You can select terms independent of x by making n=0; in this case
expr.as_independent(x)[0] is returned (and 0 will be returned instead
of None):
>>> (3 + 2*x + 4*x**2).coeff(x, 0)
3
Is this a bug in sympy, or do I miss something?
It's a bug. I have a pull request fixing it here.

How to force sympy to extract specific subexpressions?

I have a sympy result that winds up like this:
from sympy import *
Vin,Vc,C1,Cs,R1,Rs,t=symbols(r'V_{in},V_{C},C_1,C_S,R_1,R_S,t')
k1=Symbol('k_1')
eqVc=Eq(Vc(t),(Rs*(exp(t*(R1+Rs)/(R1*Rs*(C1+Cs))) - 1)*Heaviside(t) +
k1*(R1+Rs))*exp(-t*(R1+Rs)/(R1*Rs*(C1+Cs)))/(R1+Rs))
The expression eqVc comes out like this:
I know this function to be of the form:
My goal is to get the values of Vcinit, Vcfinal, and tau, but particularly tau.
Is there a way to get Sympy to extract these values? cse() doesn't quite do what I want-- I can get it to replace C1+Cs, for example by using cse([C1+Cs,eqVc]), and it does recognize that the exponent to e is a common subexpression, but it tends to include the t in the subexpression.
A simple way is to solve for parameters which will cause the expressions to be equal at a number of points in time. Given that the forms are in fact the same, this will work fine:
V_Ci, tau, V_Cf = symbols('V_Ci, tau, V_Cf')
target = V_Ci*exp(-t/tau) + Heaviside(t)*V_Cf*(1 - exp(-t/tau))
solve([(eqVc.rhs - target).subs(t, ti) for ti in [0, 1, 2]],
[V_Ci, tau, V_Cf], dict=True)
The answer I get is
[{V_Cf: R_S/(R_1 + R_S),
tau: 1/log(exp((1/R_S + 1/R_1)/(C_1 + C_S))),
V_Ci: k_1}]
That log(exp()) is not simplified away because of the way the variables are defined. Defining everything as real (V_Ci, tau, V_Cf = symbols('V_Ci, tau, V_Cf', real=True) and similar modification in your code) simplifies the soluion to
[{V_Ci: k_1,
V_Cf: R_S/(R_1 + R_S),
tau: R_1*R_S*(C_1 + C_S)/(R_1 + R_S)}]

Categories

Resources