Using sympy to rearrange equation? - python

Im trying to rearrange a supply curve equation for calculation the price elasticy.
The equation is log P = -2 + 1.7 * log Q.
Im trying to rearrange the equation so that log Q is in terms of log P. Is there a way sympy can handle these rearrangements?
p, q = sp.symbols('p, q', real=True, positive=True)
eq = sp.Eq(-2+1.7*sp.log(q))
sp.solve(eq,sp.log(p))

Using sympy solve will take care of the arrangements. The equations just must be set up properly and the function parameters must be correct.
import sympy as sp
p, q = sp.symbols('p, q', real=True, positive=True)
eq = sp.Eq(-2+1.7*sp.log(q), p) # set equation = to p
ans = sp.solve(eq,q) #solve equation for q in terms of p
This solution simply saves your equation to eq and solves eq for q so the answer is in terms of only p. In the end ans holds the value:
[3.24290842192454*exp(0.588235294117647*p)]
I highly reccomend reading this website before coming to SO.

Although you showed log P in the written text, you did not include it in the code. If you do so, you can then request that solve isolate log(q) for you:
>>> eq = Eq(log(p), -2 + 10*log(q)/17)
>>> solve(eq, log(q))
[17*log(p)/10 + 17/5]

Related

Solving ODEs with SymPy

I've just started trying out SymPy. Unfortunately, I am already stumped. Behold this:
from sympy import *
t, G, M = symbols('t G M', real = True)
x = Function('x')
y = Function('y')
print(Eq(Derivative(x, t, 2), G * M * x(t) / (x(t) * x(t) + y(t) * y(t))**1.5))
...it simply prints False. The documentation says that this means the relationship can be proven to be false.
I know that I can prevent evaluation by using evaluation = False, but eventually I want to solve my system of differential equations, and then this assumption will come into play again.
So, can anyone see what I did wrong here?
Addendum:
What I am trying to do is play around with the two-body-problem and orbital mechanics. With the gravitational constant G and the mass of the primary M at the origin, this and the symmetric equation for y(t) describe the gravitational acceleration on the secondary.
The solution, Kepler tells us, should be an ellipse for reasonable starting conditions.
I found it now, the solution is rather simple: SymPy needs to be told the x is a function of t, so
print(Eq(Derivative(x(t), t, 2), G * M * x(t) / (x(t) * x(t) + y(t) * y(t))**1.5))
does the trick.

How to solve this equation with sympy?

Recently I got a long equation to solve that looks like that.
I've tried to solve this using sympy.solveset(), but it returned ConditionSet which means it couldn't handle this equation. How can I solve this equation using simpy library and if not at least in python? The code that I used:
import sympy as sp
t = sp.symbols('t')
a = 1.46
b = 1.2042 * 10**-4 * ((1.2275 * 10**-5 + t) * sp.ln(1.2275 * 10**-5 + t) - t)
result = sp.solveset(sp.Eq(a, b), t)
print(result)
This is a transcendental equation. It possibly has an analytic solution in terms of the Lambert W function but I'm not sure. I'll assume that you just want a numerical solution which you can get using nsolve:
In [42]: nsolve(a - b, t, 1)
Out[42]: 1857.54700584719

Block LMI in CVXPY

I want to translate a LMI-constrained optimization problem from Matlab to Python. While reading the CVXPY documentation, I found that I can define an LMI-constrained problem by creating a matrix variable and adding the corresponding constraint. However, instead of constraining the problem by a simple LMI, I need to use the following block LMI:
Where P, L are matrix variables and gamma is a scalar. The other symbols are state space matrices of a dynamic system.
Is it possible to use this kind of LMI as a constraint in CVXPY? If not, is there any other tool that would allow me to solve this problem in Python?
I followed the example posted by Rodrigo de Azevedo and I managed to write the given LMI in cvxpy.
For reference, the code I wrote, It may be helpful for someone:
n = A.shape[0]
L = Variable((B2.shape[1], n))
P = Variable((n, n), PSD=True)
gamma2 = Variable()
LMI1 = bmat([
[P, A*P + B2*L, B1, np.zeros((B1.shape[0], D11.shape[0]))],
[P*A.T + L.T * B2.T, P, np.zeros((P.shape[0], B1.shape[1])), P*C1.T + L.T*D12.T],
[B1.T, np.zeros((B1.shape[1], P.shape[1])), np.eye(B1.shape[1]), D11.T],
[np.zeros((C1.shape[0], B1.shape[0])), C1*P + D12*L, D11, gamma2*np.eye(D11.shape[0])]
])
cons1 = LMI1 >> 0
cons2 = P == P.T
cons3 = gamma2 >= 0
And then, to solve the problem:
optprob = Problem(Minimize(gamma2), constraints=[cons1, cons2, cons3])
optprob.solve()
norm = np.sqrt(gamma2.value)
Pop = P.value
Lop = L.value

Partial symbolic derivative in Python

I need to partially derivate my equation and form a matrix out of the derivatives. My equation is:
While this conditions must be met:
For doing this I've used the sympy module and its diff() function. My code so far is:
from sympy import*
import numpy as np
init_printing() #delete if you dont have LaTeX installed
logt_r, logt_a, T, T_a, a_0, a_1, a_2, logS, Taa_0, Taa_1, Taa_2 = symbols('logt_r, logt_a, T, T_a, a_0, a_1, a_2, logS, Taa_0, Taa_1, Taa_2')
A = (logt_r - logt_a - (T - T_a) * (a_0 + a_1 * logS + a_2 * logS**2) )**2
parametri = [logt_a, a_0, Taa_0, a_1, Taa_1, a_2, Taa_2]
M = expand(A)
M = M.subs(T_a*a_0, Taa_0)
M = M.subs(T_a*a_1, Taa_1)
M = M.subs(T_a*a_2, Taa_2)
K = zeros(len(parametri), len(parametri))
O = []
def odv(par):
for j in range(len(par)):
for i in range(len(par)):
P = diff(M, par[i])/2
B = P.coeff(par[j])
K[i,j] = B
return K
odv(parametri)
My result:
My problem
The problem that I'm having is in the partial derivatives of products (T_aa_0, T_aa_1 and T_a*a_2), because by using the diff() function, you cannot derivate a function with a product (obviously), else you get an error:
ValueError:
Can't calculate 1-th derivative wrt T_a*a_0.
To solve this I substitued this products with coefficients, like:
M = M.subs(T_a*a_0, Taa_0)
M = M.subs(T_a*a_1, Taa_1)
M = M.subs(T_a*a_2, Taa_2)
But as you can see in the final result, this works only in some cases. I would like to know if there is a better way of doing this where I wouldn't need to substitude the products and that it would work in all cases.
ADDITIONAL INFORMATION
Let me rephrase my question. Is it possible to symbolically derive an equation with a function by using python or in that matter, to use the sympy module?
So I've managed to solve my problem on my own. The main question was how to symbolically derive a function or equation with another function. As I've gone again slowly over the sympy documentation, I saw a little detail, that I've missed before.
In order to derive a function with a function you need to change the settings of the function, that will be used to derive. For example:
x, y, z = symbols('x, y, z')
A = x*y*z
B = x*y
# This is the detail:
type(B)._diff_wrt = True
diff(A, B)
Or in my case, the code looks like:
koef = [logt_a, a_0, T_a*a_0, a_1, T_a*a_1, a_2, T_a*a_2]
M = expand(A)
K = zeros(len(koef), len(koef))
def odvod_mat(par):
for j in range(len(par)):
for i in range(len(par)):
type(par[i])._diff_wrt = True
P = diff(M, par[i])/2
B = P.coeff(par[j])
K[i,j] = B
#Removal of T_a
K[i,j] = K[i,j].subs(T_a, 0)
return K
odvod_mat(koef)
Thanks again to all that were taking their time to read this. I hope this helps to anyone, who will have the same problem as I did.

Rewrite equation as polynomial

from sympy import *
K, T, s = symbols('K T s')
G = K/(1+s*T)
Eq1 =Eq(G+1,0)
I want to rewrite equation Eq1 with sympy as polynomial: 1+K+T*s==0
How would I do this?
I spent some hours of searching and trying simplifications methods but could not find a elegant, short solution.
The actual problem in SymPy:
from IPython.display import display
import sympy as sp
sp.init_printing(use_unicode=True,use_latex=True,euler=True)
Kf,Td0s,Ke,Te,Tv,Kv,s= sp.symbols("K_f,T_d0^',K_e,T_e,T_v,K_v,s")
Ga= Kf/(1+s*Tv)
Gb= Ke/(1+s*Te)
Gc= Kf/(1+s*Td0s)
G0=Ga*Gb*Gc
G1=sp.Eq(G0+1,0)
display(G1)
How to tell Sympy to rewrite equation G1 as polynomial in shape s^3*(...)+s^2*(...)+s*(...)+(...)=... ?
The actual problem from textbook: http://i.imgur.com/J1MYo9H.png
How it should look like: http://i.imgur.com/RqEDo7H.png
The two equations are equivalent.
Here's what you can do.
import sympy as sp
Kf,Td0s,Ke,Te,Tv,Kv,s= sp.symbols("K_f,T_d0^',K_e,T_e,T_v,K_v,s")
Ga= Kf/(1+s*Tv)
Gb= Ke/(1+s*Te)
Gc= Kf/(1+s*Td0s)
G0=Ga*Gb*Gc
Throw away the denominator
eq = (G0 + 1).as_numer_denom()[0]
Expand the equation and collect terms with powers of s.
eq = eq.expand().collect(s)
Final Equation
Eq(eq, 0)
Eq(K_e*K_f**2 + T_d0^'*T_e*T_v*s**3 + s**2*(T_d0^'*T_e + T_d0^'*T_v + T_e*T_v) + s*(T_d0^' + T_e + T_v) + 1, 0)

Categories