In sympys Eq(lhs,rhs) one can instantiate an equation. However I am really really wonderin about it's behaviour and would like to ask how this equation
type is intended to be used!
The reason I'm asking is that in Maple one uses Equations (lhs == rhs) there as the standard tool. However, I've seen many scripts in sympy using x= y+z where x is a python variable and thus code, and only the expression y+z is actual mathematics to sympy. This has consequences for the following examples:
MWE:
t = S('t')
f = Function('f')(t)
g = Function('g')(t)
equation = Eq(f,g+1)
equation2 = equation-1
equation3 = equation.diff(t)
equation4 = equation.subs(equation) # this I can do with subs(*equation.args)
All of the above yield unexpected results: The first one gives an equation in brackets minus 1, which is really weird. The differentiation only acts on the lhs, which is quite misleading imho. The subsitution yields an error, only the commented line works. This last one is ok for me, knowing that I can make it work. However, are there any more useful notations for 1 and 2 other than doing everything manually, like:
eq2 = Eq( equation.lhs.difft(t), equation.rhs.diff(t) )
In comparison Maple can substitute, derive and add equations in a mathematical sense (both sides need to be addressed).
I would be glad for any input on how to work "properly" in sympy. For the time being it seems like working with rhs-expressions only seems to be the way to go and Eq is a "sideproject". Thanks for every input on this one!
In an isympy session:
In [3]: t = S('t')
...: f = Function('f')(t)
...: g = Function('g')(t)
In [4]: equation = Eq(f, g+1)
In [5]: equation
Out[5]: f(t) = g(t) + 1
The type(equation) is sympy.core.relational.Equality.
The = in the Out[5] is not related to the python = in In[4] line.
In [6]: equation2 = equation-1
In [7]: equation2
Out[7]: -1 + (f(t) = g(t) + 1)
Here the type is different: sympy.core.add.Add
In [8]: equation3 = equation.diff(t)
In [9]: equation3
Out[9]:
d
──(f(t) = g(t) + 1)
dt
This is a sympy.core.function.Derivative. It looks like an unevaluated derivative, applying to the whole equation object.
The error in the subs expression is just a misuse of subs. Why are you trying to use equation as the argument to the method?
In [10]: equation4 = equation.subs(equation)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-b6a4334b7078> in <module>
----> 1 equation4 = equation.subs(equation)
/usr/local/lib/python3.6/dist-packages/sympy/core/basic.py in subs(self, *args, **kwargs)
865 When a single argument is passed to subs
866 it should be a dictionary of old: new pairs or an iterable
--> 867 of (old, new) tuples."""))
868 elif len(args) == 2:
869 sequence = [args]
ValueError:
When a single argument is passed to subs it should be a dictionary of
old: new pairs or an iterable of (old, new) tuples.
Proper use of subs:
In [15]: equation4 = equation.subs([(t,t*2)])
In [16]: equation4
Out[16]: f(2⋅t) = g(2⋅t) + 1
====
Reference for Eq:
https://docs.sympy.org/latest/modules/core.html?highlight=eq#sympy.core.relational.Equality
I'm still working my way through sympy documentation, but it doesn't look to me like Eq creates an equation in the usual algebraic sense. It's more of a test between two objects, that evaluates to True or False, or remains unevaluated.
By replacing f with g, we get relation that can be evaluated:
In [26]: equation.subs([(f,g)]) # or subs(f,g)
Out[26]: False
The same subs in equation2 and equation3 produces an error (can't add number and False) or the derivative of False. That is the substitution is done in the equation part, evaluating to False, and the reset of the expression acts (or doesn't).
Your use of *equation.args fits this pattern:
In [43]: equation.args
Out[43]: (f(t), g(t) + 1)
In [44]: equation.subs(*equation.args)
Out[44]: True
===
https://docs.sympy.org/latest/gotchas.html
suggests an alternative to Eq(x,y) is x-y:
In [31]: eq1 = f - (g+1)
In [32]: eq1-1
Out[32]: f(t) - g(t) - 2
In [33]: eq1.diff(t)
Out[33]:
d d
──(f(t)) - ──(g(t))
dt dt
In [41]: equation.subs([(f,g)])
Out[41]: False
In [42]: equation.subs([(f,g+1)])
Out[42]: True
Sadly by the time of writing (Sympy 1.10.1) there seems to be no equation class or function that represents an equation as used in mathematics. Tutorials and the documentation work with the hack x=y to be x-y=0 and always use 0 as the left-hand-side. Eq() is equality, I get that, but a functioning equation is missing.
The problem with equating everything to zero is that you cannot divide easily, also if you want to substitute equations you need to manually assure, that you reformulate the variable correctly so that the "to be replaced" variable is expressed and does not appear in the python variable anymore. Even the documentation of subs does not mention the standard case of substituting a mathematical expression (or simpler yet variable) from another equation that contains (expresses) this variable.
I am pretty sure that everybody learned the manipulation of equations at school and university and I am aware that all mathematical papers are written this way. Therefore I would much prefer having this widely accepted approach available in a computer algebra system. After all I have experienced algebra as the manipulation of equations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With