[PATCH, help!] introduce Matrix constructor with symbolic entries

6 views
Skip to first unread message

Benjamin Goodrich

unread,
Jun 14, 2009, 3:24:25 PM6/14/09
to sympy-...@googlegroups.com
I started to work on this patch to the Matrix constructor that would allow the Matrix to be filled with symbols that are indexed by row and column. But I wonder if anyone has general comments on a better way to do it and / or make it print and latex better.

For example, this works (once the patch is applied)

beta = Matrix(3, 2, "beta")
beta
⎡β₁₁  β₁₂⎤
⎢           ⎥
⎢β₂₁  β₂₂⎥
⎢           ⎥
⎣β₃₁  β₃₂⎦

So,  then things like this work as expected (which was my goal)

beta.transpose() * beta
⎡       2      2      2                                                   ⎤
⎢    β₁₁  + β₂₁  + β₃₁        β₁₁⋅β₁₂ + β₂₁⋅β₂₂ + β₃₁⋅β₃₂⎥
⎢                                                                            ⎥
⎢                                                 2        2       2      ⎥
⎣β₁₁⋅β₁₂ + β₂₁⋅β₂₂ + β₃₁⋅β₃₂      β₁₂  + β₂₂  + β₃₂      ⎦

However, this does not work (presumably because beta_11 is only registered locally within the beta Matrix)

beta.subs(beta_11, 1)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)

/media/sda4/sympy/<ipython console> in <module>()

NameError: name 'beta_11' is not defined

So, apparently I have to do this to make it work (which I was hoping to avoid)

beta_11 = Symbol("beta_11")
beta.subs(beta_11, 1)
⎡ 1   β₁₂⎤
⎢           ⎥
⎢β₂₁  β₂₂⎥
⎢           ⎥
⎣β₃₁  β₃₂⎦

Does anyone have a way to register the symbols globally automatically from inside this Matrix constructor?

Also, there is a potential collision in the case where the Matrix has more than 9 rows and / or columns because, for example, "beta_112" could refer to the 11th row, 2nd column or the 1st row, 12th column. The new constructor still "works" in this case, but only by adding an extra underscore between the row and column indexes. For example,

Matrix(12, 3, "gamma")
⎡γ_1_1   γ_1_2   γ_1_3 ⎤
⎢                                     ⎥
⎢γ_2_1   γ_2_2   γ_2_3 ⎥
⎢                                     ⎥
⎢γ_3_1   γ_3_2   γ_3_3 ⎥
⎢                                     ⎥
⎢γ_4_1   γ_4_2   γ_4_3 ⎥
⎢                                     ⎥
⎢γ_5_1   γ_5_2   γ_5_3 ⎥
⎢                                     ⎥
⎢γ_6_1   γ_6_2   γ_6_3 ⎥
⎢                                     ⎥
⎢γ_7_1   γ_7_2   γ_7_3 ⎥
⎢                                     ⎥
⎢γ_8_1   γ_8_2   γ_8_3 ⎥
⎢                                     ⎥
⎢γ_9_1   γ_9_2   γ_9_3 ⎥
⎢                                     ⎥
⎢γ_10_1  γ_10_2  γ_10_3⎥
⎢                                        ⎥
⎢γ_11_1  γ_11_2  γ_11_3⎥
⎢                                        ⎥
⎣γ_12_1  γ_12_2  γ_12_3⎦

And thus pretty print and latex do not handle this very well, but I think this a general issue with symbols that happens to arise in this case. For example,

rho_13_14 = Symbol("rho_13_14")
rho_13_14
ρ_13_14

is not so great either. Does anyone who understands printing in Python better than me (i.e. at all) have an idea or patch to handle this better? In my opinion, I would like beta_13_2 to print with a comma as

β₁₃,₂

and latex with a comma as

\beta_{13,2}

Thank you,
Ben

0001-Matrices-make-symbolic-constructor.patch

Ondrej Certik

unread,
Jun 16, 2009, 12:35:04 PM6/16/09
to sympy-...@googlegroups.com

Yes, use "var()", resp. see how it is done in there. I however don't
recommend this approach, as it is messy.

Why not something like:

In [2]: Matrix(2, 2, lambda i, j: Symbol("a_%d%d" % (i, j)))
Out[2]:
⎡a₀₀ a₀₁⎤
⎢ ⎥
⎣a₁₀ a₁₁⎦

or if you want to keep track of the symbols:

In [3]: a = [Symbol("a_%d%d" % (i, j)) for i in range(2) for j in range(2)]

In [5]: Matrix(2, 2, lambda i, j: a[i*2+j])
Out[5]:
⎡a₀₀ a₀₁⎤
⎢ ⎥
⎣a₁₀ a₁₁⎦

maybe you want to create a 2D array of the symbols instead, but you
get the idea how to do it.

Yeah, that's a problem. We should improve it, so that it works the way
you proposed, e.g. beta_13_2 should work both in latex and in unicode.

Ondrej

Ben Goodrich

unread,
Jun 16, 2009, 7:48:07 PM6/16/09
to sympy-patches
On Jun 16, 12:35 pm, Ondrej Certik <ond...@certik.cz> wrote:
> On Sun, Jun 14, 2009 at 1:24 PM, Benjamin
> Yes, use "var()", resp. see how it is done in there. I however don't
> recommend this approach, as it is messy.
>
> Why not something like:
>
> In [2]: Matrix(2, 2, lambda i, j: Symbol("a_%d%d" % (i, j)))
> Out[2]:
> ⎡a₀₀  a₀₁⎤
> ⎢        ⎥
> ⎣a₁₀  a₁₁⎦
>
> or if you want to keep track of the symbols:

Ah, your way is much better for the typical case. The only other
reason I can see to possibly hack the constructor is that I was
thinking I could subsequently also add a fourth argument like
structure="none" that could be specified differently to construct a
"diagonal", "symmetric", "lowertriangular", etc. Matrix with symbolic
entries and the specified structure. But maybe that is not worth the
complexity or the messiness with var(). Opinions?

> Yeah, that's a problem. We should improve it, so that it works the way
> you proposed, e.g. beta_13_2 should work both in latex and in unicode.

This is now issue 1477

http://code.google.com/p/sympy/issues/detail?id=1477

which has an initial patch that fixes latex() and thus preview(), but
I don't know how to fix prettyprint or the other printing functions.

Ondrej Certik

unread,
Jun 16, 2009, 11:47:20 PM6/16/09
to sympy-...@googlegroups.com
On Tue, Jun 16, 2009 at 5:48 PM, Ben Goodrich<goodri...@gmail.com> wrote:
>
> On Jun 16, 12:35 pm, Ondrej Certik <ond...@certik.cz> wrote:
>> On Sun, Jun 14, 2009 at 1:24 PM, Benjamin
>> Yes, use "var()", resp. see how it is done in there. I however don't
>> recommend this approach, as it is messy.
>>
>> Why not something like:
>>
>> In [2]: Matrix(2, 2, lambda i, j: Symbol("a_%d%d" % (i, j)))
>> Out[2]:
>> ⎡a₀₀  a₀₁⎤
>> ⎢        ⎥
>> ⎣a₁₀  a₁₁⎦
>>
>> or if you want to keep track of the symbols:
>
> Ah, your way is much better for the typical case. The only other
> reason I can see to possibly hack the constructor is that I was
> thinking I could subsequently also add a fourth argument like
> structure="none" that could be specified differently to construct a
> "diagonal", "symmetric", "lowertriangular", etc. Matrix with symbolic
> entries and the specified structure. But maybe that is not worth the
> complexity or the messiness with var(). Opinions?

I think this seems reasonable to me. Another option is to create a new
classmethod, that would construct what you want, e.g.

a = Matrix.construct_diagonal(<..>)

and

a = Matrix.construct_upper_triangular(<..>)

Ondrej

Reply all
Reply to author
Forward
0 new messages