Ask Your Question

Revision history [back]

There is the Tensor module 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 matrics, 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)

There is the Tensor module 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 matrics, 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)
click to hide/show revision 3
Fix link for "Tensor module". Typo matrics > matrices.

There is the Tensor module 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 matricsmatrices, 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)