ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Wed, 20 Apr 2011 00:48:35 +0200Symbolic matriceshttps://ask.sagemath.org/question/8074/symbolic-matrices/Hi,
is it possible to define totally symbolic matrices.
Something like
N,M = var('N,M')
a = matrix(SR, N, M)
b = matrix(SR, M, N)
c = a.dot(b)
So that c[i,j] = sum(a[i,k]*b[k,i],k,1,M) or do you really always need an non-symblic matrix size?
If you really always need a non-symblic matrix type, is it possible to define the symbolic variables automatically? Something like
a = matrix(SR, 2, 3)
print a[i,j]
output:
a_(i,j)
Thanks!
ManuelTue, 12 Apr 2011 08:01:26 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/Answer by cswiercz for <p>Hi,</p>
<p>is it possible to define totally symbolic matrices.
Something like</p>
<pre><code>N,M = var('N,M')
a = matrix(SR, N, M)
b = matrix(SR, M, N)
c = a.dot(b)
</code></pre>
<p>So that c[i,j] = sum(a[i,k]*b[k,i],k,1,M) or do you really always need an non-symblic matrix size?</p>
<p>If you really always need a non-symblic matrix type, is it possible to define the symbolic variables automatically? Something like</p>
<pre><code>a = matrix(SR, 2, 3)
print a[i,j]
output:
a_(i,j)
</code></pre>
<p>Thanks!</p>
<p>Manuel</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?answer=12288#post-id-12288I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:
sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:
sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
It's not completely automatic, and perhaps not pretty, but I hope it helps.Tue, 12 Apr 2011 13:04:35 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?answer=12288#post-id-12288Comment by Kelvin Li for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21855#post-id-21855This isn't a very "beautiful" method, but I can't think of anything better. :-) Anybody know of a cleaner approach? By the way, I would put an underscore between the indices, so the variables would read: "a_1_0", "b_3_5", and "c_23_829" (just an example). And would this method work for sparse matrices?Tue, 12 Apr 2011 13:46:33 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21855#post-id-21855Comment by cswiercz for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21819#post-id-21819I don't assume that I know all of the nooks and crannies of Sage. My pass at the Sage documentation didn't show any constructors for such a "symbolic matrix" and I guess I just always assume that there's a more elegant approach. My approach felt somewhat hackish, though certainly effective.Tue, 19 Apr 2011 14:51:44 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21819#post-id-21819Comment by cswiercz for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21854#post-id-21854I agree that it's not pretty, but even if Sage had the ability to define these "purely symbolic" matrices one would have to call the elements _something_. Perhaps this sort fo thing would happen in the __init__() method. Also, I use the notation "a_ij" instead of "a_i_j" because when you execute "show(a_ij)", or enable typesetting in the Sage Notebook, it looks prettier. :)Tue, 12 Apr 2011 14:29:03 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21854#post-id-21854Comment by Kelvin Li for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21852#post-id-21852Ignoring all else, I would like to reference and name the elements consistently: a[1,2] being printed exactly as "a[1,2]". Then again, I can't ignore the facts. :-)Tue, 12 Apr 2011 15:17:42 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21852#post-id-21852Comment by cswiercz for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21818#post-id-21818Also, I added the phrase "though supposedly not the quickest" to my response because Simon suggested in his comment the equivalent Sympy object.Tue, 19 Apr 2011 14:52:43 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21818#post-id-21818Comment by cswiercz for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21816#post-id-21816Heh heh. If I knew a faster method then of course I would share! Also, I imagine that adding the above functionality to var would be a good project for someone who wants to get into Sage development.Wed, 20 Apr 2011 00:48:35 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21816#post-id-21816Comment by benjaminfjones for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21820#post-id-21820You say it's not the quickest way to do this (*this* being define lots of symbolic variables and populate a matrix with them), so what is the quickest way? Tue, 19 Apr 2011 12:34:06 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21820#post-id-21820Comment by benjaminfjones for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21817#post-id-21817Ok, I thought you meant that you knew of a more complicated but faster method. Your method works well in any case. I wish there was an option in `var` to return a list of arbitrarily many variables with systematic labels, e.g. `b = var('b', num=N)` would return variables b0, b1, ..., b(N-1) and maybe `b = var('b', num=N^2, square=True)` would return b00, b01, ..., b10, b11, ...Tue, 19 Apr 2011 15:11:35 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21817#post-id-21817Comment by Simon for <p>I'm not sure if there's a way to define a symbolic matrix the way you describe above. However, one could create a matrix populated only by distinct symbolic variables. Here's a quick, though supposedly not quickest, way to do so:</p>
<pre><code>sage: N = 3
sage: s = join(['a_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: a = var(s)
sage: A = matrix(SR,N,N,a)
sage: print A[1,2]
a_12
</code></pre>
<p>The second line just creates a string with the variable names $a_{ij}$ for $i,j \in \mathbb{Z}_n$ and the third parses the string and creates a list of the symbolic variables. I can now create another matrix $B$ and multiply them:</p>
<pre><code>sage: s = join(['b_%d%d' %(i,j) for (i,j) in CartesianProduct(range(N),range(N))])
sage: b = var(s)
sage: B = matrix(SR,N,N,b)
sage: C = A*B
sage: print C[1,2]
a_10*b_02 + a_11*b_12 + a_12*b_22
</code></pre>
<p>It's not completely automatic, and perhaps not pretty, but I hope it helps.</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21851#post-id-21851@cswiercz: This is basically how you have to do things in Mathematica - you then check results for a range of `N` and hope that that's enough. I was sure that sympy used to have an abstract matrix module... but I couldn't find it when I looked just now.Tue, 12 Apr 2011 20:30:23 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21851#post-id-21851Answer by Simon for <p>Hi,</p>
<p>is it possible to define totally symbolic matrices.
Something like</p>
<pre><code>N,M = var('N,M')
a = matrix(SR, N, M)
b = matrix(SR, M, N)
c = a.dot(b)
</code></pre>
<p>So that c[i,j] = sum(a[i,k]*b[k,i],k,1,M) or do you really always need an non-symblic matrix size?</p>
<p>If you really always need a non-symblic matrix type, is it possible to define the symbolic variables automatically? Something like</p>
<pre><code>a = matrix(SR, 2, 3)
print a[i,j]
output:
a_(i,j)
</code></pre>
<p>Thanks!</p>
<p>Manuel</p>
https://ask.sagemath.org/question/8074/symbolic-matrices/?answer=12289#post-id-12289There is the [Tensor module](http://docs.sympy.org/dev/modules/tensor/) in sympy. If that is the type of thing that you're looking for (ie explicit indices).
The was some code put on the sage devel group last year: [abstract matrices](http://groups.google.com/d/topic/sage-devel/yvtIbHmi6zw/discussion),
which allows basic manipulation of abstract matrices and vectors.
It's not complete, but it does the basics and should be easy to extend if you need more. As far as I can tell, it hasn't been worked on since the original postings.
I hope it's ok if I post the code here:
from sage.structure.element import Element
from sage.combinat.free_module import CombinatorialFreeModule
# TODO: doc and tests for all of those
class SymbolicMatrix(SageObject):
def __init__(self, name, nrows, ncols, inverted = False, transposed = False):
#Element.__init__(self, parent)
self._name = name
self._nrows = nrows
self._ncols = ncols
self._inverted = inverted
self._transposed = transposed
def _repr_(self):
result = self._name
if self._inverted:
result += "^-1"
if self._transposed:
result += "^t"
return result
def transpose(self):
result = copy(self)
result._transposed = not self._transposed
(result._nrows, result._ncols) = (self._ncols, self._nrows)
return result
def __invert__(self):
assert self._nrows == self._ncols, "Can't inverse non square matrix"
result = copy(self)
result._inverted = not self._inverted
return result
class SymbolicMatrixAlgebra(CombinatorialFreeModule):
r"""
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: A = Alg.matrix("A",3,2)
sage: B = Alg.matrix("B",2,3)
sage: C = Alg.matrix("C",2,3)
sage: D = Alg.matrix("D",3,3)
Example 1: Adding/Multiplying matrices of correct size::
sage: A * (B + C)
A B + A C
Example 2: Transposing a sum of matrices::
sage: (B + C).transpose()
C^t + B^t
Example 3: Transposing a product of matrices::
sage: (A * B).transpose()
B^t A^t
Example 4: Inverting a product of matrices::
sage: (A * B)^-1
B^-1 A^-1
Example 5: Multiplying by its inverse::
sage: D * D^-1 # todo: not implemented
I
TODO: decide on the best output; do we want to be able to
copy-paste back? do we prefer short notations?
.. warnings::
The identity does not know it is size, so the following should
complain, but does not::
sage: D * D^-1 * A
TODO: describe all the abuses
"""
def __init__(self, R):
"""
EXAMPLES::
sage: A = AlgebrasWithBasis(QQ).example(); A
An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field
sage: TestSuite(A).run()
"""
CombinatorialFreeModule.__init__(self, R, Words(), category = AlgebrasWithBasis(R))
def matrix(self, name, nrows, ncols):
""" TODO: doctest"""
return self.monomial(Word([SymbolicMatrix(name, nrows, ncols)]))
def _repr_(self):
"""
EXAMPLES::
sage: SymbolicMatrixAlgebra(QQ)
The symbolic matrix algebra over Rational Field
"""
return "The symbolic matrix algebra over %s"%(self.base_ring())
@cached_method
def one_basis(self):
"""
Returns the empty word, which index the one of this algebra,
as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: Alg.one_basis()
word:
sage: A.one()
I
"""
return self.basis().keys()([])
def product_on_basis(self, w1, w2):
r"""
Product of basis elements, as per :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis`.
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: P = Alg.matrix("P", 3, 2)
sage: Q = Alg.matrix("Q", 3, 2)
sage: R = Alg.matrix("R", 2, 2)
sage: S = Alg.matrix("S", 2, 3)
sage: P * P
Traceback (most recent call last):
...
AssertionError: Non-conformable matrices: matrix sizes are incompatible for multiplication
sage: P * R * S
P*R*S
sage: (P+Q) * R
P*R + Q*R
sage: (P+Q) * R * S
P*R*S + Q*R*S
sage: S * (P+Q) * R
"""
if len(w1) == 0:
return self.monomial(w2)
if len(w2) == 0:
return self.monomial(w1)
assert w1[-1]._ncols == w2[0]._nrows, "Non-conformable matrices: matrix sizes are incompatible for multiplication"
# TODO: handle cancelations between w1[-1] and w2[0]
return self.monomial(w1 + w2)
# TODO: define an_element
def _repr_term(self, t):
"""
EXAMPLES::
sage: Alg.one() # indirect doctest
I
sage: Alg.an_element() # todo: not implemented
"""
if len(t) == 0:
return 'I'
else:
return ' '.join(repr(m) for m in t)
class Element(CombinatorialFreeModule.Element):
def transpose(self):
"""
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: A = Alg.matrix("A", 3, 2)
sage: B = Alg.matrix("B", 3, 2)
sage: C = Alg.matrix("C", 2, 2)
sage: D = Alg.matrix("D", 2, 3)
sage: x = D * (A+B) * C
sage: x
D B C + D A C
sage: x.transpose()
C^t B^t D^t + C^t A^t D^t
"""
return self.map_support(lambda w: Word(m.transpose() for m in reversed(w)))
def __invert__(self):
"""
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: A = Alg.matrix("A", 2, 2)
sage: B = Alg.matrix("B", 2, 2)
sage: C = Alg.matrix("C", 2, 2)
sage: D = Alg.matrix("D", 3, 2)
sage: E = Alg.matrix("E", 2, 3)
sage: ~(A*B*C)
C^-1 B^-1 A^-1
sage: ~(A*B^-1*C^-1)
C B A^-1
sage: ~(D*C*E)
Traceback (most recent call last):
...
AssertionError: Can't inverse non square matrix
sage: ~(A+B)
Traceback (most recent call last):
...
AssertionError: Can't inverse non trivial linear combinations of matrices
"""
assert len(self) == 1, "Can't inverse non trivial linear combinations of matrices"
(w, c) = self.leading_item()
return self.parent().term(Word(~m for m in reversed(w)), c) Tue, 12 Apr 2011 20:28:29 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?answer=12289#post-id-12289Comment by kcrisman for <div class="snippet"><p>There is the <a href="http://docs.sympy.org/dev/modules/tensor/">Tensor module</a> in sympy. If that is the type of thing that you're looking for (ie explicit indices).</p>
<p>The was some code put on the sage devel group last year: <a href="http://groups.google.com/d/topic/sage-devel/yvtIbHmi6zw/discussion">abstract matrices</a>,
which allows basic manipulation of abstract matrices and vectors.
It's not complete, but it does the basics and should be easy to extend if you need more. As far as I can tell, it hasn't been worked on since the original postings.
I hope it's ok if I post the code here:</p>
<pre><code>from sage.structure.element import Element
from sage.combinat.free_module import CombinatorialFreeModule
# TODO: doc and tests for all of those
class SymbolicMatrix(SageObject):
def __init__(self, name, nrows, ncols, inverted = False, transposed = False):
#Element.__init__(self, parent)
self._name = name
self._nrows = nrows
self._ncols = ncols
self._inverted = inverted
self._transposed = transposed
def _repr_(self):
result = self._name
if self._inverted:
result += "^-1"
if self._transposed:
result += "^t"
return result
def transpose(self):
result = copy(self)
result._transposed = not self._transposed
(result._nrows, result._ncols) = (self._ncols, self._nrows)
return result
def __invert__(self):
assert self._nrows == self._ncols, "Can't inverse non square matrix"
result = copy(self)
result._inverted = not self._inverted
return result
class SymbolicMatrixAlgebra(CombinatorialFreeModule):
r"""
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: A = Alg.matrix("A",3,2)
sage: B = Alg.matrix("B",2,3)
sage: C = Alg.matrix("C",2,3)
sage: D = Alg.matrix("D",3,3)
Example 1: Adding/Multiplying matrices of correct size::
sage: A * (B + C)
A B + A C
Example 2: Transposing a sum of matrices::
sage: (B + C).transpose()
C^t + B^t
Example 3: Transposing a product of matrices::
sage: (A * B).transpose()
B^t A^t
Example 4: Inverting a product of matrices::
sage: (A * B)^-1
B^-1 A^-1
Example 5: Multiplying by its inverse::
sage: D * D^-1 # todo: not implemented
I
TODO: decide on the best output; do we want to be able to
copy-paste back? do we prefer short notations?
.. warnings::
The identity does not know it is size, so the following should
complain, but does not::
sage: D * D^-1 * A
TODO: describe all the abuses
"""
def __init__(self, R):
"""
EXAMPLES::
sage: A = AlgebrasWithBasis(QQ).example(); A
An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field
sage: TestSuite(A).run()
"""
CombinatorialFreeModule.__init__(self, R, Words(), category = AlgebrasWithBasis(R))
def matrix(self, name, nrows, ncols):
""" TODO: doctest"""
return self.monomial(Word([SymbolicMatrix(name, nrows, ncols)]))
def _repr_(self):
"""
EXAMPLES::
sage: SymbolicMatrixAlgebra(QQ)
The symbolic matrix algebra over Rational Field
"""
return "The symbolic matrix algebra over %s"%(self.base_ring())
@cached_method
def one_basis(self):
"""
Returns the empty word, which index the one of this algebra,
as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: Alg.one_basis()
word:
sage: A.one()
I
"""
return self.basis().keys()([])
def product_on_basis(self, w1, w2):
r"""
Product of basis elements, as per :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis ...</code></pre><span class="expander"> <a>(more)</a></span></div>https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21850#post-id-21850That's an interesting thread, which I had forgotten. Did it ever turn into a ticket?Tue, 12 Apr 2011 23:46:18 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21850#post-id-21850Comment by kcrisman for <div class="snippet"><p>There is the <a href="http://docs.sympy.org/dev/modules/tensor/">Tensor module</a> in sympy. If that is the type of thing that you're looking for (ie explicit indices).</p>
<p>The was some code put on the sage devel group last year: <a href="http://groups.google.com/d/topic/sage-devel/yvtIbHmi6zw/discussion">abstract matrices</a>,
which allows basic manipulation of abstract matrices and vectors.
It's not complete, but it does the basics and should be easy to extend if you need more. As far as I can tell, it hasn't been worked on since the original postings.
I hope it's ok if I post the code here:</p>
<pre><code>from sage.structure.element import Element
from sage.combinat.free_module import CombinatorialFreeModule
# TODO: doc and tests for all of those
class SymbolicMatrix(SageObject):
def __init__(self, name, nrows, ncols, inverted = False, transposed = False):
#Element.__init__(self, parent)
self._name = name
self._nrows = nrows
self._ncols = ncols
self._inverted = inverted
self._transposed = transposed
def _repr_(self):
result = self._name
if self._inverted:
result += "^-1"
if self._transposed:
result += "^t"
return result
def transpose(self):
result = copy(self)
result._transposed = not self._transposed
(result._nrows, result._ncols) = (self._ncols, self._nrows)
return result
def __invert__(self):
assert self._nrows == self._ncols, "Can't inverse non square matrix"
result = copy(self)
result._inverted = not self._inverted
return result
class SymbolicMatrixAlgebra(CombinatorialFreeModule):
r"""
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: A = Alg.matrix("A",3,2)
sage: B = Alg.matrix("B",2,3)
sage: C = Alg.matrix("C",2,3)
sage: D = Alg.matrix("D",3,3)
Example 1: Adding/Multiplying matrices of correct size::
sage: A * (B + C)
A B + A C
Example 2: Transposing a sum of matrices::
sage: (B + C).transpose()
C^t + B^t
Example 3: Transposing a product of matrices::
sage: (A * B).transpose()
B^t A^t
Example 4: Inverting a product of matrices::
sage: (A * B)^-1
B^-1 A^-1
Example 5: Multiplying by its inverse::
sage: D * D^-1 # todo: not implemented
I
TODO: decide on the best output; do we want to be able to
copy-paste back? do we prefer short notations?
.. warnings::
The identity does not know it is size, so the following should
complain, but does not::
sage: D * D^-1 * A
TODO: describe all the abuses
"""
def __init__(self, R):
"""
EXAMPLES::
sage: A = AlgebrasWithBasis(QQ).example(); A
An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field
sage: TestSuite(A).run()
"""
CombinatorialFreeModule.__init__(self, R, Words(), category = AlgebrasWithBasis(R))
def matrix(self, name, nrows, ncols):
""" TODO: doctest"""
return self.monomial(Word([SymbolicMatrix(name, nrows, ncols)]))
def _repr_(self):
"""
EXAMPLES::
sage: SymbolicMatrixAlgebra(QQ)
The symbolic matrix algebra over Rational Field
"""
return "The symbolic matrix algebra over %s"%(self.base_ring())
@cached_method
def one_basis(self):
"""
Returns the empty word, which index the one of this algebra,
as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: Alg.one_basis()
word:
sage: A.one()
I
"""
return self.basis().keys()([])
def product_on_basis(self, w1, w2):
r"""
Product of basis elements, as per :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis ...</code></pre><span class="expander"> <a>(more)</a></span></div>https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21844#post-id-21844Then open one and post the code :)Thu, 14 Apr 2011 10:45:30 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21844#post-id-21844Comment by Simon for <div class="snippet"><p>There is the <a href="http://docs.sympy.org/dev/modules/tensor/">Tensor module</a> in sympy. If that is the type of thing that you're looking for (ie explicit indices).</p>
<p>The was some code put on the sage devel group last year: <a href="http://groups.google.com/d/topic/sage-devel/yvtIbHmi6zw/discussion">abstract matrices</a>,
which allows basic manipulation of abstract matrices and vectors.
It's not complete, but it does the basics and should be easy to extend if you need more. As far as I can tell, it hasn't been worked on since the original postings.
I hope it's ok if I post the code here:</p>
<pre><code>from sage.structure.element import Element
from sage.combinat.free_module import CombinatorialFreeModule
# TODO: doc and tests for all of those
class SymbolicMatrix(SageObject):
def __init__(self, name, nrows, ncols, inverted = False, transposed = False):
#Element.__init__(self, parent)
self._name = name
self._nrows = nrows
self._ncols = ncols
self._inverted = inverted
self._transposed = transposed
def _repr_(self):
result = self._name
if self._inverted:
result += "^-1"
if self._transposed:
result += "^t"
return result
def transpose(self):
result = copy(self)
result._transposed = not self._transposed
(result._nrows, result._ncols) = (self._ncols, self._nrows)
return result
def __invert__(self):
assert self._nrows == self._ncols, "Can't inverse non square matrix"
result = copy(self)
result._inverted = not self._inverted
return result
class SymbolicMatrixAlgebra(CombinatorialFreeModule):
r"""
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: A = Alg.matrix("A",3,2)
sage: B = Alg.matrix("B",2,3)
sage: C = Alg.matrix("C",2,3)
sage: D = Alg.matrix("D",3,3)
Example 1: Adding/Multiplying matrices of correct size::
sage: A * (B + C)
A B + A C
Example 2: Transposing a sum of matrices::
sage: (B + C).transpose()
C^t + B^t
Example 3: Transposing a product of matrices::
sage: (A * B).transpose()
B^t A^t
Example 4: Inverting a product of matrices::
sage: (A * B)^-1
B^-1 A^-1
Example 5: Multiplying by its inverse::
sage: D * D^-1 # todo: not implemented
I
TODO: decide on the best output; do we want to be able to
copy-paste back? do we prefer short notations?
.. warnings::
The identity does not know it is size, so the following should
complain, but does not::
sage: D * D^-1 * A
TODO: describe all the abuses
"""
def __init__(self, R):
"""
EXAMPLES::
sage: A = AlgebrasWithBasis(QQ).example(); A
An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field
sage: TestSuite(A).run()
"""
CombinatorialFreeModule.__init__(self, R, Words(), category = AlgebrasWithBasis(R))
def matrix(self, name, nrows, ncols):
""" TODO: doctest"""
return self.monomial(Word([SymbolicMatrix(name, nrows, ncols)]))
def _repr_(self):
"""
EXAMPLES::
sage: SymbolicMatrixAlgebra(QQ)
The symbolic matrix algebra over Rational Field
"""
return "The symbolic matrix algebra over %s"%(self.base_ring())
@cached_method
def one_basis(self):
"""
Returns the empty word, which index the one of this algebra,
as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: Alg.one_basis()
word:
sage: A.one()
I
"""
return self.basis().keys()([])
def product_on_basis(self, w1, w2):
r"""
Product of basis elements, as per :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis ...</code></pre><span class="expander"> <a>(more)</a></span></div>https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21845#post-id-21845@kcrisman - I had a quick look, but couldn't find anything.Wed, 13 Apr 2011 22:20:01 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21845#post-id-21845Comment by Simon for <div class="snippet"><p>There is the <a href="http://docs.sympy.org/dev/modules/tensor/">Tensor module</a> in sympy. If that is the type of thing that you're looking for (ie explicit indices).</p>
<p>The was some code put on the sage devel group last year: <a href="http://groups.google.com/d/topic/sage-devel/yvtIbHmi6zw/discussion">abstract matrices</a>,
which allows basic manipulation of abstract matrices and vectors.
It's not complete, but it does the basics and should be easy to extend if you need more. As far as I can tell, it hasn't been worked on since the original postings.
I hope it's ok if I post the code here:</p>
<pre><code>from sage.structure.element import Element
from sage.combinat.free_module import CombinatorialFreeModule
# TODO: doc and tests for all of those
class SymbolicMatrix(SageObject):
def __init__(self, name, nrows, ncols, inverted = False, transposed = False):
#Element.__init__(self, parent)
self._name = name
self._nrows = nrows
self._ncols = ncols
self._inverted = inverted
self._transposed = transposed
def _repr_(self):
result = self._name
if self._inverted:
result += "^-1"
if self._transposed:
result += "^t"
return result
def transpose(self):
result = copy(self)
result._transposed = not self._transposed
(result._nrows, result._ncols) = (self._ncols, self._nrows)
return result
def __invert__(self):
assert self._nrows == self._ncols, "Can't inverse non square matrix"
result = copy(self)
result._inverted = not self._inverted
return result
class SymbolicMatrixAlgebra(CombinatorialFreeModule):
r"""
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: A = Alg.matrix("A",3,2)
sage: B = Alg.matrix("B",2,3)
sage: C = Alg.matrix("C",2,3)
sage: D = Alg.matrix("D",3,3)
Example 1: Adding/Multiplying matrices of correct size::
sage: A * (B + C)
A B + A C
Example 2: Transposing a sum of matrices::
sage: (B + C).transpose()
C^t + B^t
Example 3: Transposing a product of matrices::
sage: (A * B).transpose()
B^t A^t
Example 4: Inverting a product of matrices::
sage: (A * B)^-1
B^-1 A^-1
Example 5: Multiplying by its inverse::
sage: D * D^-1 # todo: not implemented
I
TODO: decide on the best output; do we want to be able to
copy-paste back? do we prefer short notations?
.. warnings::
The identity does not know it is size, so the following should
complain, but does not::
sage: D * D^-1 * A
TODO: describe all the abuses
"""
def __init__(self, R):
"""
EXAMPLES::
sage: A = AlgebrasWithBasis(QQ).example(); A
An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field
sage: TestSuite(A).run()
"""
CombinatorialFreeModule.__init__(self, R, Words(), category = AlgebrasWithBasis(R))
def matrix(self, name, nrows, ncols):
""" TODO: doctest"""
return self.monomial(Word([SymbolicMatrix(name, nrows, ncols)]))
def _repr_(self):
"""
EXAMPLES::
sage: SymbolicMatrixAlgebra(QQ)
The symbolic matrix algebra over Rational Field
"""
return "The symbolic matrix algebra over %s"%(self.base_ring())
@cached_method
def one_basis(self):
"""
Returns the empty word, which index the one of this algebra,
as per :meth:`AlgebrasWithBasis.ParentMethods.one_basis`.
EXAMPLES::
sage: Alg = SymbolicMatrixAlgebra(QQ)
sage: Alg.one_basis()
word:
sage: A.one()
I
"""
return self.basis().keys()([])
def product_on_basis(self, w1, w2):
r"""
Product of basis elements, as per :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis ...</code></pre><span class="expander"> <a>(more)</a></span></div>https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21834#post-id-21834@kcrisman: Remind me again in a couple of months after I've written my thesis - then I'll have a go at completing and posting the code...Fri, 15 Apr 2011 20:32:21 +0200https://ask.sagemath.org/question/8074/symbolic-matrices/?comment=21834#post-id-21834