Last active
November 1, 2019 05:43
-
-
Save moorepants/aec439a0383ed387f7ebb7693a9927f3 to your computer and use it in GitHub Desktop.
Example showing that subs doesn't work as you might expect with derivatives.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Be careful about substituting for derivatives!" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import sympy as sm\n", | |
"import sympy.physics.mechanics as me" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"q1, q2 = me.dynamicsymbols('q1, q2')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"a, b, c = sm.symbols('a, b, c')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle \\operatorname{q_{1}}{\\left(t \\right)} \\left(\\frac{d^{2}}{d t^{2}} \\operatorname{q_{1}}{\\left(t \\right)}\\right)^{2} + \\frac{d}{d t} \\operatorname{q_{1}}{\\left(t \\right)} \\frac{d}{d t} \\operatorname{q_{2}}{\\left(t \\right)}$" | |
], | |
"text/plain": [ | |
"q1(t)*Derivative(q1(t), (t, 2))**2 + Derivative(q1(t), t)*Derivative(q2(t), t)" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"expr = q1.diff().diff()**2*q1 + q1.diff()*q2.diff()\n", | |
"expr" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"It is worth looking at the raw form (the non-rendered form) to see what is going on:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'q1(t)*Derivative(q1(t), (t, 2))**2 + Derivative(q1(t), t)*Derivative(q2(t), t)'" | |
] | |
}, | |
"execution_count": 5, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"repr(expr)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We are going to be substiting expressions for $q$'s, $\\dot{q}$'s, and $\\dot{u}$'s. There are a couple of key things to be aware of:\n", | |
"\n", | |
"- `subs()` and `xreplace()` do not substitute the expression in a fixed order (i.e. Python dictionaries are not ordered), so if you pass in more than one item in a single `subs()` call, things might get substituted in an unexpected order.\n", | |
"- If you have a `dynamicsymbol` and its deritivate in an expression and substitute something for the symbol, it will get replaced inside the derivative too." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Notice how $c$ is not replaced first below and thus derivatives are left in the expression:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle a b c \\frac{d}{d t} \\operatorname{q_{2}}{\\left(t \\right)} + a \\left(\\frac{\\partial}{\\partial t} a b c\\right)^{2}$" | |
], | |
"text/plain": [ | |
"a*b*c*Derivative(q2(t), t) + a*Derivative(a*b*c, t)**2" | |
] | |
}, | |
"execution_count": 6, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"expr.subs({q1: a, q1.diff(): a*b*c, q1.diff().diff(): c})" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'a*b*c*Derivative(q2(t), t) + a*Derivative(a*b*c, t)**2'" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"repr(expr.subs({q1: a, q1.diff(): a*b*c, q1.diff().diff(): c}))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Notice how all the $q_1$ are replaced with $a$, even \"inside\" the derivatives:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle a \\left(\\frac{d^{2}}{d t^{2}} a\\right)^{2} + \\frac{d}{d t} a \\frac{d}{d t} \\operatorname{q_{2}}{\\left(t \\right)}$" | |
], | |
"text/plain": [ | |
"a*Derivative(a, (t, 2))**2 + Derivative(a, t)*Derivative(q2(t), t)" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"expr.subs({q1: a})" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'a*Derivative(a, (t, 2))**2 + Derivative(a, t)*Derivative(q2(t), t)'" | |
] | |
}, | |
"execution_count": 9, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"repr(expr.subs({q1: a}))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"To ensure proper substitution make sure to substitute the highest order deriavtives first in a chain of `subs()` calls:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/latex": [ | |
"$\\displaystyle a c^{2} + b \\frac{d}{d t} \\operatorname{q_{2}}{\\left(t \\right)}$" | |
], | |
"text/plain": [ | |
"a*c**2 + b*Derivative(q2(t), t)" | |
] | |
}, | |
"execution_count": 10, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"expr.subs({q1.diff().diff(): c}).subs({q1.diff(): b}).subs({q1: a})" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'a*c**2 + b*Derivative(q2(t), t)'" | |
] | |
}, | |
"execution_count": 11, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"repr(expr.subs({q1.diff().diff(): c}).subs({q1.diff(): b}).subs({q1: a}))" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.7" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment