# Symbolic linear algebra

Most of my research is in numerical methods/numerical analysis. I need to perform derivations using arbitrary matrices. Currently, when using sage, I have to declare all the elements of a symbolic matrix:

var('p00 p01 p02 p03 p10 p11 p12 p13 p20 p21 p22 p23 p30 p31 p32 p33') Pmat=matrix([[p00,p01,p02,p03],[p10,p11,p12,p13],[p20,p21,p22,p23],[p30,p31,p32,p33]])

Clearly for large matrices this is prohibitively tedious. In Mathematica, I simply use:

pmat=Array[p,{4,4}]

I am then able to put constraints on the elements of p and solve for the values for the given method I am trying to derive. I prefer to use sage over Mathematica, so if someone can enlighten me how to accomplish this task in sage, I would appreciate it.

edit retag close merge delete

Sort by » oldest newest most voted

Hi tcfisher,

Here's one less-tedious way, using Python's list comprehension, string formatting, and an alternate format for the matrix command:

sage: plist = ['p%s%s'%(i,j) for i in range(4) for j in range(4)]
sage: plist
['p00', 'p01', 'p02', 'p03', 'p10', 'p11', 'p12', 'p13', 'p20', 'p21', 'p22', 'p23', 'p30', 'p31', 'p32', 'p33']

sage: m = matrix(SR,4,4,plist); m
[p00 p01 p02 p03]
[p10 p11 p12 p13]
[p20 p21 p22 p23]
[p30 p31 p32 p33]


Note that this does not inject the variables 'pij' into the global namespace, so trying to write them directly will result in an error:

sage: p00
Traceback (most recent call last):
...
NameError: name 'p00' is not defined


But if all you want to do is manipulate these matrices, that will work fine:

sage: m^2
[  p00^2 + p01*p10 + p02*p20 + p03*p30 p00*p01 + p01*p11 + p02*p21 + p03*p31 p00*p02 + p01*p12 + p02*p22 + p03*p32 p00*p03 + p01*p13 + p02*p23 + p03*p33]
[p00*p10 + p10*p11 + p12*p20 + p13*p30   p01*p10 + p11^2 + p12*p21 + p13*p31 p02*p10 + p11*p12 + p12*p22 + p13*p32 p03*p10 + p11*p13 + p12*p23 + p13*p33]
[p00*p20 + p10*p21 + p20*p22 + p23*p30 p01*p20 + p11*p21 + p21*p22 + p23*p31   p02*p20 + p12*p21 + p22^2 + p23*p32 p03*p20 + p13*p21 + p22*p23 + p23*p33]
[p00*p30 + p10*p31 + p20*p32 + p30*p33 p01*p30 + p11*p31 + p21*p32 + p31*p33 p02*p30 + p12*p31 + p22*p32 + p32*p33   p03*p30 + p13*p31 + p23*p32 + p33^2]


And of course if you need the 'pij' in the global namespace, you can always declare the variables by looping over plist (or maybe something more clever, if you give it some thought, but I haven't really :)

sage: for p in plist:
....:     var(p)
....:
p00
p01
p02
p03
p10
p11
p12
p13
p20
p21
p22
p23
p30
p31
p32
p33
sage: p00
p00
sage: p00 + 2*p13
p00 + 2*p13

more

Thanks for your help niles. Here is the function I came up with to do this automatically from now on.

 def symbolic_matrix(root,m,n):
mlist=[];
for i in range(m):
for j in range(n):
mlist.append(root+'_'+str(i)+'_'+str(j));
var(root+'_'+str(i)+'_'+str(j));
return matrix(SR,m,n,mlist);


Note that root must be a string.

sage: pmat=symbolic_matrix('p',5,4)
sage: pmat
[p_0_0 p_0_1 p_0_2 p_0_3]
[p_1_0 p_1_1 p_1_2 p_1_3]
[p_2_0 p_2_1 p_2_2 p_2_3]
[p_3_0 p_3_1 p_3_2 p_3_3]
[p_4_0 p_4_1 p_4_2 p_4_3]

more