Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force sympy to extract specific subexpressions?

Tags:

python

sympy

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.

like image 468
Omegaman Avatar asked Oct 16 '25 03:10

Omegaman


1 Answers

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)}]
like image 50
chthonicdaemon Avatar answered Oct 17 '25 17:10

chthonicdaemon