Alan Bromborsky wrote:
[email protected] wrote:
Hi Ondrej,

This code is taken from something you put together which was called
tensors.py in 0.6.3, at least that is where I found it on my system,
since I still have 0.6.3 on my disk.  I am currently using 0.6.6.6. I
extracted the imports and the class defs from there and put it in a
file certekten.py so I could isolate the defs.  It is not clear to me
all your experiment had in mind.  What I need to do first is to:

1. figure out how to design classes which allow the definition of
arbitrary mixed rank tensors:  TensorDefine(tensorname,rankindices)
where tensorname is just a desired symbol name and rankindices is
something like [pcovariant,qcontravariant] or
[icov1,icov2,...,icontra1,icontra2,...].  The resulting object should
be a symbol decorated with the collection of p contravariant and q
covariant indices.
2. the rendering (prettyprinting) should produce these with latex type
upper and lower indices...like g^{ij} and g_{kl} for example.
3. Rules need to be introduced so that contraction (==sum over
repeated contravariant and covariant indices) should be handled
correctly.
4. derivative operations should be handled e.g. by distribution over
sums, Leibniz product rule symbolically handled, e.g. \partial
( tensor1 * tensor2) ) = (\partial tensor1) * tensor2 + tensor1 *
(\partial tensor2), etc, etc.

plus probably many others.  I have looked at scheme implementations
and while I am not very conversant with scheme, it does appear that
Sussman and coworker(s) at MIT have done the differential geometry
stuff.  I don't think it focuses on indicial gymnastics but it does
seem to define generic objects which are "up" and "down" as well as
covariant derivative, Ricci tensor, Riemann tensor, the components of
the symmetric connection, etc.  I was looking at the scheme way
because I am interested in what kind of data structures they end up
defining for tensor kinds of objects with an eye of maybe using those
as a guide/suggestion as to how tensor objects may be adequately
'classed' in python/sympy.

I have also spent some time recently looking over the sympy core code
trying to get better educated with a hope to see what might be good
ways to go in defining tensor objects... but due to my relative
inexperience I can not seem to see how to translate the properties I
think I want into correctly defined python/sympy.

I am fully aware of your relativity.py example code, which is fine for
what it does. However, there the indices are all integers and the
differentiation is explicit diff, not what is needed in the much more
formal expression handling of tensor algebra and calculus.

I would appreciate help from the sympy community on how to do these
things.

Comer

On May 26, 6:18 pm, Ondrej Certik <[email protected]> wrote:
On Wed, May 26, 2010 at 12:43 PM, [email protected]

<[email protected]> wrote:
Hi,
I am trying to understand some apparently old code written by Ondrej
trying to implement what I think are indicial tensor expressions.  I
list below the class definitions and then try to give an example. The
example results in an error.  I believe I recall that Ondrej says that
these definitions don't work, but I am trying to understand them and
want to try to create some appropriate classes which can contain
indicial tensors.
Where is this code from? I think I wrote something like this, but it's
quite some time ago, so I forgot which issue it is.

It'd be awesome if you wanted to do some support for tensors in sympy.
The only example, that is known to work is the

python examples/advanced/relativity.py

and I just tried it and it seems to work. So that shows how to get
something working, and what we need now is some general support for
tensors.

Ondrej

Below is the very beginnings of a abstract tensor class with test output. Input is via a string
as follows (say for the Riemann tensor) -

code R = BasicTensor('R_ijk__l')

'R' is the base name
'ijk' are the first three indices with the '_' indicating they are covariant
'l' is the last index with '__' indicating it is contravariant.
You could define mixed tensors such as 'M__i_j__k_l' etc.
When the tensor is instantciated the string '_ijk__l' generates the list
self.index=[-1,-2,-3,4] indicating there are 4 tensor slots and whether the
slot is co or contravariant.

Additionally the BasicTensor instantciation stores symmetry information about the tensor. See code below and output where the symmetries of the metric and Riemann tensor (only simple symmetries in the case of the Riemann tensor, no Bianchi identity).

The Tensor class would then be composed of a list of lists of basic tensor with the inner lists representing different types of tensor products of basic tensors and the outer list sums of tensor
products (with scalar multipliers for each product).

Where sympy would come into play is to simplify the general tensor by assigning suitable indices to all the basic tensors in the general tensor. Convert all the basic tensors to sympy scalars. Perform all multiplications and additions of these scalars to symplify (including symmetry simplifications) convert the sympy scalar expression back to a string and the string back to a tensor.

Code:

#!/bin/python

from sympy import Symbol

index_pool = 'abcdefhijklmnopquvwxyz'
index_index = 0

class BasicTensor:
   def __init__(self,Tstr,syms=None,sgns=None):
       self.Tstr = Tstr
       Tstr_lst = Tstr.split('_')
       self.base = Tstr_lst[0]
       self.index = []
       self.up_dn = []
       self.syms = []
       self.sgns = []
       self.up_rank = 0
       self.dn_rank = 0
       i = 1
       sgn = -1
       for chstr in Tstr_lst[1:]:
           if chstr == '':
               sgn = -sgn
           else:
               for ch in chstr:
                   self.index.append(i)
                   i += 1
                   self.up_dn.append(sgn)
                   if sgn == -1:
                       self.dn_rank += 1
                   else:
                       self.up_rank += 1

               sgn = -1
       if syms != None:
           self.add_symmetries(syms,sgns)

   def __str__(self):
       global index_pool,index_index
       tstr = self.base+'_'
       old_up_dn = self.up_dn[0]
       if  old_up_dn == 1:
           tstr += '_'
       for i,j in zip(self.index,self.up_dn):
           if j != old_up_dn:
               tstr += '_'
               if j == 1:
                   tstr += '_'
               old_up_dn = j
           tstr += index_pool[index_index+i-1]
       index_index = 0
       return(tstr)

   def symmetries(self):
       return(self.syms,self.sgns)

   def add_symmetries(self,sym_lst,sgn_lst=None):
       self.syms += sym_lst
       if sgn_lst == None:
           sgn_lst = len(sym_lst)*[1]
       self.sgns += sgn_lst
       return

   def symbol(self):
       Tstr = str(self)
       Tsym = Symbol(Tstr)
       return(Tsym)

if __name__ == '__main__':

   g = BasicTensor('g_ij',[[2,1]])
   R = BasicTensor('R_ijk__l',[[2,1,3,4],[1,2,4,3]],[-1,-1])

   print g,R

   print g.symmetries()
   print R.symmetries()

Output:

g_ab R_abc__d
([[2, 1]], [1])
([[2, 1, 3, 4], [1, 2, 4, 3]], [-1, -1])

The following link looks to be a good reference on abstract index notation for tensors. The problem is that you cannot copy the text (but maybe you have library access to the book) -

http://books.google.com/books?id=YA8rxOn9H1sC&pg=PA56&lpg=PA56&dq=penrose+abstract+index+notation&source=bl&ots=EZQNV3TUkQ&sig=rqs7l8DGuUTl6CDMkG67HyUoPQY&hl=en&ei=nHT-S9jLL4K88gaakqnxDQ&sa=X&oi=book_result&ct=result&resnum=5&ved=0CDAQ6AEwBA#v=onepage&q=penrose%20abstract%20index%20notation&f=false
--
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to