Tensor¶
-
class
sympy.tensor.tensor.
TIDS
(components, free, dum)[source]¶ Tensor internal data structure. This contains internal data about components of a tensor expression, its free and dummy indices.
To create a \(TIDS\) object via the standard constructor, the required arguments are
components
\(TensorHead\) objects representing the components- of the tensor expression.
free
Free indices in their internal representation.dum
Dummy indices in their internal representation.Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TIDS, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz) >>> T = tensorhead('T', [Lorentz]*4, [[1]*4]) >>> TIDS([T], [(m0, 0, 0), (m3, 3, 0)], [(1, 2, 0, 0)]) TIDS([T(Lorentz,Lorentz,Lorentz,Lorentz)], [(m0, 0, 0), (m3, 3, 0)], [(1, 2, 0, 0)])
Details
In short, this has created the components, free and dummy indices for the internal representation of a tensor T(m0, m1, -m1, m3).
Free indices are represented as a list of triplets. The elements of each triplet identify a single free index and are
- TensorIndex object
- position inside the component
- component number
Dummy indices are represented as a list of 4-plets. Each 4-plet stands for couple for contracted indices, their original TensorIndex is not stored as it is no longer required. The four elements of the 4-plet are
- position inside the component of the first index.
- position inside the component of the second index.
- component number of the first index.
- component number of the second index.
-
canon_args
()[source]¶ Returns
(g, dummies, msym, v)
, the entries ofcanonicalize
see
canonicalize
intensor_can.py
-
static
free_dum_from_indices
(*indices)[source]¶ Convert
indices
intofree
,dum
for single component tensorfree
list of tuples(index, pos, 0)
,- where
pos
is the position of index in the list of indices formed by the component tensors
dum
list of tuples(pos_contr, pos_cov, 0, 0)
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TIDS >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz) >>> TIDS.free_dum_from_indices(m0, m1, -m1, m3) ([(m0, 0, 0), (m3, 3, 0)], [(1, 2, 0, 0)])
-
static
from_components_and_indices
(components, indices)[source]¶ Create a new \(TIDS\) object from \(components\) and \(indices\)
components
\(TensorHead\) objects representing the components- of the tensor expression.
indices
\(TensorIndex\) objects, the indices. Contractions are- detected upon construction.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TIDS, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz) >>> T = tensorhead('T', [Lorentz]*4, [[1]*4]) >>> TIDS.from_components_and_indices([T], [m0, m1, -m1, m3]) TIDS([T(Lorentz,Lorentz,Lorentz,Lorentz)], [(m0, 0, 0), (m3, 3, 0)], [(1, 2, 0, 0)])
In case of many components the same indices have slightly different indexes:
>>> A = tensorhead('A', [Lorentz], [[1]]) >>> TIDS.from_components_and_indices([A]*4, [m0, m1, -m1, m3]) TIDS([A(Lorentz), A(Lorentz), A(Lorentz), A(Lorentz)], [(m0, 0, 0), (m3, 0, 3)], [(0, 0, 1, 2)])
-
get_components_with_free_indices
()[source]¶ Get a list of components with their associated indices.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TIDS, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz) >>> T = tensorhead('T', [Lorentz]*4, [[1]*4]) >>> A = tensorhead('A', [Lorentz], [[1]]) >>> t = TIDS.from_components_and_indices([T], [m0, m1, -m1, m3]) >>> t.get_components_with_free_indices() [(T(Lorentz,Lorentz,Lorentz,Lorentz), [(m0, 0, 0), (m3, 3, 0)])] >>> t2 = (A(m0)*A(-m0))._tids >>> t2.get_components_with_free_indices() [(A(Lorentz), []), (A(Lorentz), [])] >>> t3 = (A(m0)*A(-m1)*A(-m0)*A(m1))._tids >>> t3.get_components_with_free_indices() [(A(Lorentz), []), (A(Lorentz), []), (A(Lorentz), []), (A(Lorentz), [])] >>> t4 = (A(m0)*A(m1)*A(-m0))._tids >>> t4.get_components_with_free_indices() [(A(Lorentz), []), (A(Lorentz), [(m1, 0, 1)]), (A(Lorentz), [])] >>> t5 = (A(m0)*A(m1)*A(m2))._tids >>> t5.get_components_with_free_indices() [(A(Lorentz), [(m0, 0, 0)]), (A(Lorentz), [(m1, 0, 1)]), (A(Lorentz), [(m2, 0, 2)])]
-
static
mul
(f, g)[source]¶ The algorithms performing the multiplication of two TIDS instances.
In short, it forms a new TIDS object, joining components and indices, checking that abstract indices are compatible, and possibly contracting them.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TIDS, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz) >>> T = tensorhead('T', [Lorentz]*4, [[1]*4]) >>> A = tensorhead('A', [Lorentz], [[1]]) >>> tids_1 = TIDS.from_components_and_indices([T], [m0, m1, -m1, m3]) >>> tids_2 = TIDS.from_components_and_indices([A], [m2]) >>> tids_1 * tids_2 TIDS([T(Lorentz,Lorentz,Lorentz,Lorentz), A(Lorentz)], [(m0, 0, 0), (m3, 3, 0), (m2, 0, 1)], [(1, 2, 0, 0)])
In this case no contraction has been performed.
>>> tids_3 = TIDS.from_components_and_indices([A], [-m3]) >>> tids_1 * tids_3 TIDS([T(Lorentz,Lorentz,Lorentz,Lorentz), A(Lorentz)], [(m0, 0, 0)], [(1, 2, 0, 0), (3, 0, 0, 1)])
Free indices m3 and -m3 are identified as a contracted couple, and are therefore transformed into dummy indices.
A wrong index construction (for example, trying to contract two contravariant indices or using indices multiple times) would result in an exception:
>>> tids_4 = TIDS.from_components_and_indices([A], [m3]) >>> # This raises an exception: >>> # tids_1 * tids_4
-
perm2tensor
(g, canon_bp=False)[source]¶ Returns a \(TIDS\) instance corresponding to the permutation
g
g
permutation corresponding to the tensor in the representation used in canonicalizationcanon_bp
if True, theng
is the permutation corresponding to the canonical form of the tensor
-
class
sympy.tensor.tensor.
VTIDS
(components, free, dum, data)[source]¶ This class handles a
VTIDS
object, which is aTIDS
object with an attachednumpy
ndarray
.To create a \(TIDS\) object via the standard constructor, the required arguments are
components
\(TensorHead\) objects representing the components- of the tensor expression.
free
Free indices in their internal representation.dum
Dummy indices in their internal representation.data
Data as anumpy
ndarray
.Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, VTIDS, tensorhead >>> import numpy >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2, m3 = tensor_indices('m0,m1,m2,m3', Lorentz) >>> T = tensorhead('T', [Lorentz]*4, [[1]*4]) >>> data = numpy.array([2,9,6,-5]).reshape(2, 2) >>> VTIDS([T], [(m0, 0, 0), (m3, 3, 0)], [(1, 2, 0, 0)], data) VTIDS([T(Lorentz,Lorentz,Lorentz,Lorentz)], [(m0, 0, 0), (m3, 3, 0)], [(1, 2, 0, 0)], [[ 2 9] [ 6 -5]])
-
correct_signature_from_indices
(data, indices, free, dum)[source]¶ Utility function to correct the values inside the data ndarray according to whether indices are covariant or contravariant.
It uses the metric matrix to lower values of covariant indices.
-
class
sympy.tensor.tensor.
_TensorManager
[source]¶ Class to manage tensor properties.
Notes
Tensors belong to tensor commutation groups; each group has a label
comm
; there are predefined labels:0
tensors commuting with any other tensor1
tensors anticommuting among themselves2
tensors not commuting, apart with those withcomm=0
Other groups can be defined using
set_comm
; tensors in those groups commute with those withcomm=0
; by default they do not commute with any other group.-
comm_symbols2i
(i)[source]¶ get the commutation group number corresponding to
i
i
can be a symbol or a number or a stringIf
i
is not already defined its commutation group number is set.
-
get_comm
(i, j)[source]¶ Return the commutation parameter for commutation group numbers
i, j
see
_TensorManager.set_comm
-
set_comm
(i, j, c)[source]¶ set the commutation parameter
c
for commutation groupsi, j
Parameters: i, j : symbols representing commutation groups
c : group commutation number
Notes
i, j
can be symbols, strings or numbers, apart from0, 1
and2
which are reserved respectively for commuting, anticommuting tensors and tensors not commuting with any other group apart with the commuting tensors. For the remaining cases, use this method to set the commutation rules; by defaultc=None
.The group commutation number
c
is assigned in correspondence to the group commutation symbols; it can be0 commuting
1 anticommuting
None no commutation property
Examples
G
andGH
do not commute with themselves and commute with each other; A is commuting.>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead, TensorManager >>> Lorentz = TensorIndexType('Lorentz') >>> i0,i1,i2,i3,i4 = tensor_indices('i0:5', Lorentz) >>> A = tensorhead('A', [Lorentz], [[1]]) >>> G = tensorhead('G', [Lorentz], [[1]], 'Gcomm') >>> GH = tensorhead('GH', [Lorentz], [[1]], 'GHcomm') >>> TensorManager.set_comm('Gcomm', 'GHcomm', 0) >>> (GH(i1)*G(i0)).canon_bp() G(i0)*GH(i1) >>> (G(i1)*G(i0)).canon_bp() G(i1)*G(i0) >>> (G(i1)*A(i0)).canon_bp() A(i0)*G(i1)
-
-
class
sympy.tensor.tensor.
TensorIndexType
[source]¶ A TensorIndexType is characterized by its name and its metric.
Parameters: name : name of the tensor type
metric : metric symmetry or metric object or
None
dim : dimension, it can be a symbol or an integer or
None
eps_dim : dimension of the epsilon tensor
dummy_fmt : name of the head of dummy indices
Notes
The
metric
parameter can be:metric = False
symmetric metric (in Riemannian geometry)metric = True
antisymmetric metric (for spinor calculus)metric = None
there is no metricmetric
can be an object havingname
andantisym
attributes.If there is a metric the metric is used to raise and lower indices.
In the case of antisymmetric metric, the following raising and lowering conventions will be adopted:
psi(a) = g(a, b)*psi(-b); chi(-a) = chi(b)*g(-b, -a)
g(-a, b) = delta(-a, b); g(b, -a) = -delta(a, -b)
where
delta(-a, b) = delta(b, -a)
is theKronecker delta
(seeTensorIndex
for the conventions on indices).If there is no metric it is not possible to raise or lower indices; e.g. the index of the defining representation of
SU(N)
is ‘covariant’ and the conjugate representation is ‘contravariant’; forN > 2
they are linearly independent.eps_dim
is by default equal todim
, if the latter is an integer; else it can be assigned (for use in naive dimensional regularization); ifeps_dim
is not an integerepsilon
isNone
.Examples
>>> from sympy.tensor.tensor import TensorIndexType >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> Lorentz.metric metric(Lorentz,Lorentz)
Examples with metric data added, this means it is working on a fixed basis:
>>> Lorentz.data = [1, -1, -1, -1] >>> Lorentz TensorIndexType(Lorentz, 0) >>> Lorentz.data [[1 0 0 0] [0 -1 0 0] [0 0 -1 0] [0 0 0 -1]]
Attributes
name
metric_name
it is ‘metric’ or metric.name metric_antisym
metric
the metric tensor delta
Kronecker delta
epsilon
the Levi-Civita epsilon
tensordim
dim_eps
dummy_fmt
data
a property to add ndarray
values, to work in a specified basis.
-
class
sympy.tensor.tensor.
TensorIndex
[source]¶ Represents an abstract tensor index.
Parameters: name : name of the index, or
True
if you want it to be automatically assignedtensortype :
TensorIndexType
of the indexis_up : flag for contravariant index
Notes
Tensor indices are contracted with the Einstein summation convention.
An index can be in contravariant or in covariant form; in the latter case it is represented prepending a
-
to the index name.Dummy indices have a name with head given by
tensortype._dummy_fmt
Examples
>>> from sympy.tensor.tensor import TensorIndexType, TensorIndex, TensorSymmetry, TensorType, get_symmetric_group_sgs >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> i = TensorIndex('i', Lorentz); i i >>> sym1 = TensorSymmetry(*get_symmetric_group_sgs(1)) >>> S1 = TensorType([Lorentz], sym1) >>> A, B = S1('A,B') >>> A(i)*B(-i) A(L_0)*B(-L_0)
If you want the index name to be automatically assigned, just put
True
in thename
field, it will be generated using the reserved character_
in front of its name, in order to avoid conflicts with possible existing indices:>>> i0 = TensorIndex(True, Lorentz) >>> i0 _i0 >>> i1 = TensorIndex(True, Lorentz) >>> i1 _i1 >>> A(i0)*B(-i1) A(_i0)*B(-_i1) >>> A(i0)*B(-i0) A(L_0)*B(-L_0)
Attributes
name
tensortype
is_up
-
sympy.tensor.tensor.
tensor_indices
(s, typ)[source]¶ Returns list of tensor indices given their names and their types
Parameters: s : string of comma separated names of indices
typ : list of
TensorIndexType
of the indicesExamples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> a, b, c, d = tensor_indices('a,b,c,d', Lorentz)
-
class
sympy.tensor.tensor.
TensorSymmetry
[source]¶ Monoterm symmetry of a tensor
Parameters: bsgs : tuple (base, sgs)
BSGS of the symmetry of the tensorNotes
A tensor can have an arbitrary monoterm symmetry provided by its BSGS. Multiterm symmetries, like the cyclic symmetry of the Riemann tensor, are not covered.
Examples
Define a symmetric tensor
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, TensorSymmetry, TensorType, get_symmetric_group_sgs >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> sym2 = TensorSymmetry(get_symmetric_group_sgs(2)) >>> S2 = TensorType([Lorentz]*2, sym2) >>> V = S2('V')
Attributes
base
base of the BSGS generators
generators of the BSGS rank
rank of the tensor
-
class
sympy.tensor.tensor.
TensorType
[source]¶ Class of tensor types.
Parameters: index_types : list of
TensorIndexType
of the tensor indicessymmetry :
TensorSymmetry
of the tensorExamples
Define a symmetric tensor
>>> from sympy.tensor.tensor import TensorIndexType, tensorsymmetry, TensorType >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> sym2 = tensorsymmetry([1, 1]) >>> S2 = TensorType([Lorentz]*2, sym2) >>> V = S2('V')
Attributes
index_types
symmetry
types
list of TensorIndexType
without repetitions
-
class
sympy.tensor.tensor.
TensorHead
[source]¶ Tensor head of the tensor
Parameters: name : name of the tensor
typ : list of TensorIndexType
comm : commutation group number
Notes
A
TensorHead
belongs to a commutation group, defined by a symbol on numbercomm
(see_TensorManager.set_comm
); tensors in a commutation group have the same commutation properties; by defaultcomm
is0
, the group of the commuting tensors.Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensorsymmetry, TensorType >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> sym2 = tensorsymmetry([1]*2) >>> S2 = TensorType([Lorentz]*2, sym2) >>> A = S2('A')
Examples with ndarray values:
>>> from sympy.tensor.tensor import tensor_indices, tensorhead >>> Lorentz.data = [1, -1, -1, -1] >>> i0, i1 = tensor_indices('i0:2', Lorentz) >>> A.data = [[j+2*i for j in range(4)] for i in range(4)]
in order to retrieve data, it is also necessary to specify abstract indices enclosed by round brackets, then numerical indices inside square brackets.
>>> A(i0, i1)[0, 0] 0 >>> A(i0, i1)[2, 3] == 3+2*2 True
Notice that square brackets create a valued tensor expression instance:
>>> A(i0, i1) A(i0, i1)
To view the data, just type:
>>> A.data [[0 1 2 3] [2 3 4 5] [4 5 6 7] [6 7 8 9]]
Turning to a tensor expression, covariant indices get the corresponding data corrected by the metric:
>>> A(i0, -i1).data [[0 -1 -2 -3] [2 -3 -4 -5] [4 -5 -6 -7] [6 -7 -8 -9]]
>>> A(-i0, -i1).data [[0 -1 -2 -3] [-2 3 4 5] [-4 5 6 7] [-6 7 8 9]]
while if all indices are contravariant, the
ndarray
remains the same>>> A(i0, i1).data [[0 1 2 3] [2 3 4 5] [4 5 6 7] [6 7 8 9]]
When all indices are contracted and data are added to the tensor, it will return a scalar resulting from all contractions:
>>> A(i0, -i0) -18
Attributes
name
index_types
rank
types
equal to typ.types
symmetry
equal to typ.symmetry
comm
commutation group
-
class
sympy.tensor.tensor.
TensExpr
[source]¶ Abstract base class for tensor expressions
Notes
A tensor expression is an expression formed by tensors; currently the sums of tensors are distributed.
A
TensExpr
can be aTensAdd
or aTensMul
.TensAdd
objects are put in canonical form using the Butler-Portugal algorithm for canonicalization under monoterm symmetries.TensMul
objects are formed by products of component tensors, and include a coefficient, which is a SymPy expression.In the internal representation contracted indices are represented by
(ipos1, ipos2, icomp1, icomp2)
, whereicomp1
is the position of the component tensor with contravariant index,ipos1
is the slot which the index occupies in that component tensor.Contracted indices are therefore nameless in the internal representation.
-
get_matrix
()[source]¶ Returns ndarray data as a matrix, if data are available and ndarray dimension does not exceed 2.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensorsymmetry, TensorType >>> from sympy import ones >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> sym2 = tensorsymmetry([1]*2) >>> S2 = TensorType([Lorentz]*2, sym2) >>> A = S2('A')
>>> from sympy.tensor.tensor import tensor_indices, tensorhead >>> Lorentz.data = [1, -1, -1, -1] >>> i0, i1 = tensor_indices('i0:2', Lorentz) >>> A.data = [[j+2*i for j in range(4)] for i in range(4)] >>> A(i0, i1).get_matrix() Matrix([ [0, 1, 2, 3], [2, 3, 4, 5], [4, 5, 6, 7], [6, 7, 8, 9]])
It is possible to perform usual operation on matrices, such as the matrix multiplication:
>>> A(i0, i1).get_matrix()*ones(4, 1) Matrix([ [ 6], [14], [22], [30]])
-
-
class
sympy.tensor.tensor.
TensAdd
[source]¶ Sum of tensors
Parameters: free_args : list of the free indices Notes
Sum of more than one tensor are put automatically in canonical form.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensorhead, tensor_indices >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> a, b = tensor_indices('a,b', Lorentz) >>> p, q = tensorhead('p,q', [Lorentz], [[1]]) >>> t = p(a) + q(a); t p(a) + q(a) >>> t(b) p(b) + q(b)
Examples with data added to the tensor expression:
>>> from sympy import eye >>> Lorentz.data = [1, -1, -1, -1] >>> a, b = tensor_indices('a, b', Lorentz) >>> p.data = [2, 3, -2, 7] >>> q.data = [2, 3, -2, 7] >>> t = p(a) + q(a); t p(a) + q(a)
>>> t(b) p(b) + q(b)
The following are: 2**2 - 3**2 - 2**2 - 7**2 ==> -58
>>> p(a)*p(-a) -58
>>> p(a)**2 -58
Attributes
args
tuple of addends rank
rank of the tensor free_args
list of the free indices in sorted order -
applyfunc
(func)[source]¶ Return a new
TensAdd
object, whose data ndarray will be the elementwise map of the current data ndarray by functionfunc
.
-
canon_bp
()[source]¶ canonicalize using the Butler-Portugal algorithm for canonicalization under monoterm symmetries.
-
contract_metric
(g)[source]¶ Raise or lower indices with the metric
g
Parameters: g : metric
contract_all : if True, eliminate all
g
which are contractedNotes
see the
TensorIndexType
docstring for the contraction conventions
-
static
from_TIDS_list
(coeff, tids_list)[source]¶ Given a list of coefficients and a list of \(TIDS\) objects, construct a \(TensAdd\) instance, equivalent to the one that would result from creating single instances of \(TensMul\) and then adding them.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead, TensAdd >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> i, j = tensor_indices('i,j', Lorentz) >>> A, B = tensorhead('A,B', [Lorentz]*2, [[1]*2]) >>> eA = 3*A(i, j) >>> eB = 2*B(j, i) >>> t1 = eA._tids >>> t2 = eB._tids >>> c1 = eA.coeff >>> c2 = eB.coeff >>> TensAdd.from_TIDS_list([c1, c2], [t1, t2]) 2*B(i, j) + 3*A(i, j)
If the coefficient parameter is a scalar, then it will be applied as a coefficient on all \(TIDS\) objects.
>>> TensAdd.from_TIDS_list(4, [t1, t2]) 4*A(i, j) + 4*B(i, j)
-
fun_eval
(*index_tuples)[source]¶ Return a tensor with free indices substituted according to
index_tuples
Parameters: index_types : list of tuples (old_index, new_index)
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz) >>> A, B = tensorhead('A,B', [Lorentz]*2, [[1]*2]) >>> t = A(i, k)*B(-k, -j) + A(i, -j) >>> t.fun_eval((i, k),(-j, l)) A(k, L_0)*B(l, -L_0) + A(k, l)
-
substitute_indices
(*index_tuples)[source]¶ Return a tensor with free indices substituted according to
index_tuples
Parameters: index_types : list of tuples (old_index, new_index)
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz) >>> A, B = tensorhead('A,B', [Lorentz]*2, [[1]*2]) >>> t = A(i, k)*B(-k, -j); t A(i, L_0)*B(-L_0, -j) >>> t.substitute_indices((i,j), (j, k)) A(j, L_0)*B(-L_0, -k)
-
-
class
sympy.tensor.tensor.
TensMul
[source]¶ Product of tensors
Parameters: coeff : SymPy coefficient of the tensor
args :
Notes
args[0]
list ofTensorHead
of the component tensors.args[1]
list of(ind, ipos, icomp)
whereind
is a free index,ipos
is the slot position ofind
in theicomp
-th component tensor.args[2]
list of tuples representing dummy indices.(ipos1, ipos2, icomp1, icomp2)
indicates that the contravariant dummy index is theipos1
-th slot position in theicomp1
-th component tensor; the corresponding covariant index is in theipos2
slot position in theicomp2
-th component tensor.Attributes
components
list of TensorHead
of the component tensorstypes
list of nonrepeated TensorIndexType
free
list of (ind, ipos, icomp)
, see Notesdum
list of (ipos1, ipos2, icomp1, icomp2)
, see Notesext_rank
rank of the tensor counting the dummy indices rank
rank of the tensor coeff
SymPy coefficient of the tensor free_args
list of the free indices in sorted order is_canon_bp
True
if the tensor in in canonical form-
applyfunc
(func)[source]¶ Return a new
TensAdd
object, whose data ndarray will be the elementwise map of the current data ndarray by functionfunc
.
-
canon_bp
()[source]¶ Canonicalize using the Butler-Portugal algorithm for canonicalization under monoterm symmetries.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz) >>> A = tensorhead('A', [Lorentz]*2, [[2]]) >>> t = A(m0,-m1)*A(m1,-m0) >>> t.canon_bp() -A(L_0, L_1)*A(-L_0, -L_1) >>> t = A(m0,-m1)*A(m1,-m2)*A(m2,-m0) >>> t.canon_bp() 0
-
contract_metric
(g)[source]¶ Raise or lower indices with the metric
g
g
metricNotes
see the
TensorIndexType
docstring for the contraction conventionsExamples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz) >>> g = Lorentz.metric >>> p, q = tensorhead('p,q', [Lorentz], [[1]]) >>> t = p(m0)*q(m1)*g(-m0, -m1) >>> t.canon_bp() metric(L_0, L_1)*p(-L_0)*q(-L_1) >>> t.contract_metric(g).canon_bp() p(L_0)*q(-L_0)
-
fun_eval
(*index_tuples)[source]¶ Return a tensor with free indices substituted according to
index_tuples
index_types
list of tuples(old_index, new_index)
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz) >>> A, B = tensorhead('A,B', [Lorentz]*2, [[1]*2]) >>> t = A(i, k)*B(-k, -j); t A(i, L_0)*B(-L_0, -j) >>> t.fun_eval((i, k),(-j, l)) A(k, L_0)*B(-L_0, l)
-
get_indices
()[source]¶ Returns the list of indices of the tensor
The indices are listed in the order in which they appear in the component tensors. The dummy indices are given a name which does not collide with the names of the free indices.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> m0, m1, m2 = tensor_indices('m0,m1,m2', Lorentz) >>> g = Lorentz.metric >>> p, q = tensorhead('p,q', [Lorentz], [[1]]) >>> t = p(m1)*g(m0,m2) >>> t.get_indices() [m1, m0, m2]
-
perm2tensor
(g, canon_bp=False)[source]¶ Returns the tensor corresponding to the permutation
g
For further details, see the method in \(TIDS\) with the same name.
-
sorted_components
()[source]¶ Returns a tensor with sorted components calling the corresponding method in a \(TIDS\) object.
-
split
()[source]¶ Returns a list of tensors, whose product is
self
Dummy indices contracted among different tensor components become free indices with the same name as the one used to represent the dummy indices.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> a, b, c, d = tensor_indices('a,b,c,d', Lorentz) >>> A, B = tensorhead('A,B', [Lorentz]*2, [[1]*2]) >>> t = A(a,b)*B(-b,c) >>> t A(a, L_0)*B(-L_0, c) >>> t.split() [A(a, L_0), B(-L_0, c)]
-
substitute_indices
(*index_tuples)[source]¶ Return a tensor with free indices substituted according to
index_tuples
index_types
list of tuples(old_index, new_index)
Note: this method will neither raise or lower the indices, it will just replace their symbol.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz) >>> A, B = tensorhead('A,B', [Lorentz]*2, [[1]*2]) >>> t = A(i, k)*B(-k, -j); t A(i, L_0)*B(-L_0, -j) >>> t.substitute_indices((i,j), (j, k)) A(j, L_0)*B(-L_0, -k)
-
-
sympy.tensor.tensor.
riemann_cyclic_replace
(t_r)[source]¶ replace Riemann tensor with an equivalent expression
R(m,n,p,q) -> 2/3*R(m,n,p,q) - 1/3*R(m,q,n,p) + 1/3*R(m,p,n,q)
-
sympy.tensor.tensor.
riemann_cyclic
(t2)[source]¶ replace each Riemann tensor with an equivalent expression satisfying the cyclic identity.
This trick is discussed in the reference guide to Cadabra.
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead, riemann_cyclic >>> Lorentz = TensorIndexType('Lorentz', dummy_fmt='L') >>> i, j, k, l = tensor_indices('i,j,k,l', Lorentz) >>> R = tensorhead('R', [Lorentz]*4, [[2, 2]]) >>> t = R(i,j,k,l)*(R(-i,-j,-k,-l) - 2*R(-i,-k,-j,-l)) >>> riemann_cyclic(t) 0