Marvin Ward Jr
Marvin Ward Jr

Reputation: 1029

Sympy - Display Full Equation in Dense Matrix Form

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()

enter image description here

(b*x).as_explicit()

enter image description here

e.as_explicit()

enter image description here

...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):

enter image description here

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

Answers (1)

asmeurer
asmeurer

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]

enter image description here

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\]

image

Upvotes: 2

Related Questions