Reputation: 1029
I am attempting to use Sympy to decompose estimation procedures within the IPython Notebook. It would be very useful to be able to accompany data manipulations with the full linear equation display at each step. To take a simple regression example, I have the following setup:
from sympy import *
from sympy.abc import epsilon
y=MatrixSymbol('y',5,1)
x=MatrixSymbol('x',5,2)
b=MatrixSymbol('b',2,1)
e=MatrixSymbol('epsilon',5,1)
I can print each of the components...
y.as_explicit()
(b*x).as_explicit()
e.as_explicit()
...but I have not been able to find, however, a method in Sympy that allows for the full equation to be displayed (the following was rendered with an online latex editor):
Basically any time I use an equals operator it is reasonably taken as assignment, and addition operators convert the MatrixSymbol into a MatAdd object, which does not support the as_explict()
method. Any thoughts on this issue would be appreciated.
Upvotes: 4
Views: 2970
Reputation: 91580
If you call the MatAdd
constructor explicitly, it doesn't evaluate. To create an equality, use Eq
. It seems there is a rendering but with the plus sign in the Unicode pretty printing, which I opened https://github.com/sympy/sympy/issues/2747 for.
In [14]: Eq(y.as_explicit(), MatAdd((x*b).as_explicit(), (e).as_explicit()))
Out[14]:
⎡y₀₀⎤ = ⎡x₀₀⋅b₀₀ + x₀₁⋅b₁₀⎤ + ⎡ε₀₀⎤
⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎢y₁₀⎥ ⎢x₁₀⋅b₀₀ + x₁₁⋅b₁₀⎥ ⎢ε₁₀⎥
⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎢y₂₀⎥ ⎢x₂₀⋅b₀₀ + x₂₁⋅b₁₀⎥ ⎢ε₂₀⎥
⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎢y₃₀⎥ ⎢x₃₀⋅b₀₀ + x₃₁⋅b₁₀⎥ ⎢ε₃₀⎥
⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎣y₄₀⎦ ⎣x₄₀⋅b₀₀ + x₄₁⋅b₁₀⎦ ⎣ε₄₀⎦
It seems the LaTeX printing is correct, though:
In [16]: print(latex(Eq(y.as_explicit(), MatAdd((x*b).as_explicit(), (e).as_explicit()))))
\left[\begin{matrix}y_{0, 0}\\y_{1, 0}\\y_{2, 0}\\y_{3, 0}\\y_{4, 0}\end{matrix}\right] = \left[\begin{matrix}x_{0, 0} b_{0, 0} + x_{0, 1} b_{1, 0}\\x_{1, 0} b_{0, 0} + x_{1, 1} b_{1, 0}\\x_{2, 0} b_{0, 0} + x_{2, 1} b_{1, 0}\\x_{3, 0} b_{0, 0} + x_{3, 1} b_{1, 0}\\x_{4, 0} b_{0, 0} + x_{4, 1} b_{1, 0}\end{matrix}\right] + \left[\begin{matrix}\epsilon_{0, 0}\\\epsilon_{1, 0}\\\epsilon_{2, 0}\\\epsilon_{3, 0}\\\epsilon_{4, 0}\end{matrix}\right]
You can use MatMul
if you don't want to evaluate the x*b
:
In [18]: Eq(y.as_explicit(), MatAdd(MatMul(x.as_explicit(),b.as_explicit()), (e).as_explicit()))
Out[18]:
⎡y₀₀⎤ = ⎡x₀₀ x₀₁⎤⋅⎡b₀₀⎤ + ⎡ε₀₀⎤
⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎢y₁₀⎥ ⎢x₁₀ x₁₁⎥ ⎣b₁₀⎦ ⎢ε₁₀⎥
⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎢y₂₀⎥ ⎢x₂₀ x₂₁⎥ ⎢ε₂₀⎥
⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎢y₃₀⎥ ⎢x₃₀ x₃₁⎥ ⎢ε₃₀⎥
⎢ ⎥ ⎢ ⎥ ⎢ ⎥
⎣y₄₀⎦ ⎣x₄₀ x₄₁⎦ ⎣ε₄₀⎦
In [19]: print(latex(Eq(y.as_explicit(), MatAdd(MatMul(x.as_explicit(),b.as_explicit()), (e).as_explicit()))))
\left\[\begin{matrix}y_{0, 0}\\y_{1, 0}\\y_{2, 0}\\y_{3, 0}\\y_{4, 0}\end{matrix}\right\] = \left\[\begin{matrix}x_{0, 0} & x_{0, 1}\\x_{1, 0} & x_{1, 1}\\x_{2, 0} & x_{2, 1}\\x_{3, 0} & x_{3, 1}\\x_{4, 0} & x_{4, 1}\end{matrix}\right\] \left\[\begin{matrix}b_{0, 0}\\b_{1, 0}\end{matrix}\right\] + \left\[\begin{matrix}\epsilon_{0, 0}\\\epsilon_{1, 0}\\\epsilon_{2, 0}\\\epsilon_{3, 0}\\\epsilon_{4, 0}\end{matrix}\right\]
Upvotes: 2