简体   繁体   中英

SymPy with advanced rewrite and simplification

For instance, I want to expand the following simultaneous equations in first order difference with respect to x, y and z1:

$$x^\alpha y^(1-\alpha) = z_1$$
$$x^\beta y^(1-\beta) = z_2$$

It is obviously that

$$\alpha \hat{x} + (1-\alpha) \hat{y} = \hat{z_1}$$
$$\beta \hat{x} + (1-\beta) \hat{y} = 0$$

where $\hat{variable}$ means the elasticity of the variable, namely, $\frac{d varibale}{variable}$. We have:

$$\hat{x} = \frac{1-\beta}{\alpha - \beta} \hat{z_1}$$
$$\hat{y} = -\frac{\beta}{\alpha - \beta} \hat{z_1}$$

The corresponding code for python using SymPy will be:

import sympy as sp
x,y,z1,z2,alpha,beta = sp.symbols('x,y,z_1,z_2,alpha,beta',positive=True)
eq1 = x**alpha*y**(1-alpha) - z1
eq2 = x**beta*y**(1-beta) - z2
hat_x,hat_y,hat_z1 = sp.symbols('\hat{x},\hat{y},\hat{z_1})
diff_eq1 = eq1.diff(x)*hat_x*x + eq1.diff(y)*hat_y*y + eq1.diff(z1)*hat_z1*z1
diff_eq2 = eq2.diff(x)*hat_x*x + eq2.diff(y)*hat_y*y + eq2.diff(z1)*hat_z1*z1
root = sp.solve([diff_eq1,diff_eq2],[hat_x,hat_y])

which gives the result在此处输入图像描述

As you can see, the expression is right, but without further simplification. The reason is that it does not take the advantage of eq1 = 0 and eq2 = 0. My question is, how to make further simplifications using the information given by the original equations? Thanks!!

BTW, how can I declare variables with ranges? For instance, I want to declare $\alpha \in (0,1)$ and the $1-\alpha$ will also be positive and facilitate the following manipulation.

My question is, how to make further simplifications using the information given by the original equations?

In general, the solution to a simultaneous equation will not have one side of the equation in the solution. So I can only answer your question in this specific case. root is a dictionary and we will loop through all the values and substitute the RHS of the equations with the LHS.

import sympy as sp
x,y,z1,z2,alpha,beta = sp.symbols('x,y,z_1,z_2,alpha,beta',positive=True)
eq1 = x**alpha*y**(1-alpha) - z1
eq2 = x**beta*y**(1-beta) - z2
hat_x,hat_y,hat_z1 = sp.symbols('\hat{x},\hat{y},\hat{z_1}')
diff_eq1 = eq1.diff(x)*hat_x*x + eq1.diff(y)*hat_y*y + eq1.diff(z1)*hat_z1*z1
diff_eq2 = eq2.diff(x)*hat_x*x + eq2.diff(y)*hat_y*y + eq2.diff(z1)*hat_z1*z1
root = sp.solve([diff_eq1,diff_eq2],[hat_x,hat_y])

for key, value in root.items():
    root[key] = value.subs({z1: x**alpha*y**(1-alpha), z2: x**beta*y**(1-beta)}).simplify()

BTW, how can I declare variables with ranges? For instance, I want to declare $\alpha \in (0,1)$ and the $1-\alpha$ will also be positive and facilitate the following manipulation.

There is no explicit way to do so in SymPy. There are a few work-arounds. See this Stack Overflow question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM