# GenerateTensor

### Description

• GenerateTensor(indices, samples) generates tensor of the most general form from a given samples.
• The indices of tensor produced by GenerateTensor(indices, samples) are indices.
• The symmetries of tensor produced by GenerateTensor(indices, samples) will be equal to symmetries of specified SimpleIndices indices .
• GenerateTensor(indices, samples, options) allows to pass additional options.

### Examples

The most general tensor with 3 indices that can be assembled from metric tensor $g_{mn}$ and vector $k_m$ is $$c_1 k_a k_b k_c + c_2 g_{ac} k_b + c_3 g_{ab} k_c + c_4 g_{bc} k_a$$ With Redberry one can do the following

def t = GenerateTensor('_abc'.si, ['g_mn', 'k_a'])
println t

   > C[0]*k_{a}*k_{b}*k_{c}+C[1]*g_{ac}*k_{b}+C[2]*g_{ab}*k_{c}+C[4]*g_{bc}*k_{a}


Generate tensor with 4 indices with particular symmetries:

def indices = '_{abcd}'.si //parse SimpleIndices
t = GenerateTensor(indices, ['g_ab', 'k_a'])
println Collect['C[x]'.t] >> t

   > C[0]*(g_{ab}*k_{c}*k_{d}-g_{cd}*k_{a}*k_{b})
+g_{bd}*k_{a}*k_{c}+g_{ac}*k_{b}*k_{d})


Generate fully antisymmetric tensor with 5 indices from samples t_mn and f_abc:

def indices = '_abcde'.si
indices.symmetries.setAntiSymmetric()
def r = Collect['C[x]'] >> GenerateTensor(indices, ['t_mn', 'f_abe'].t)
println r

   > C[0]*(-t_{be}*f_{dca}+t_{da}*f_{ecb}-t_{ba}*f_{ecd}+t_{bc}*f_{ade}
+t_{eb}*f_{dca}-t_{ce}*f_{abd}-t_{ea}*f_{cbd}-t_{da}*f_{ceb}
+t_{ca}*f_{ebd}+t_{ba}*f_{edc}+t_{ed}*f_{acb}-t_{ca}*f_{dbe}
-t_{da}*f_{ebc}+t_{ea}*f_{cdb}+t_{be}*f_{dac}-t_{dc}*f_{abe}
-t_{eb}*f_{dac}+t_{ae}*f_{dcb}-t_{bd}*f_{cea}-t_{ae}*f_{dbc}
-t_{ea}*f_{bdc}+t_{dc}*f_{bae}-t_{db}*f_{cae}-t_{dc}*f_{bea}
+t_{da}*f_{cbe}-t_{ce}*f_{bda}+t_{ec}*f_{abd}+t_{ac}*f_{bed}
-t_{da}*f_{bce}+t_{bd}*f_{aec}-t_{de}*f_{acb}+t_{ab}*f_{ecd}
+t_{ce}*f_{dba}+t_{ae}*f_{cbd}-t_{bd}*f_{ace}-t_{ab}*f_{edc}
+t_{dc}*f_{aeb}-t_{bc}*f_{eda}-t_{bd}*f_{eac}+t_{ab}*f_{dec}
+t_{ca}*f_{deb}+t_{be}*f_{acd}-t_{ca}*f_{bed}-t_{ae}*f_{cdb}
-t_{eb}*f_{acd}-t_{ac}*f_{bde}+t_{cb}*f_{aed}-t_{ca}*f_{edb}
-t_{cd}*f_{eba}+t_{ae}*f_{bdc}+t_{db}*f_{cea}-t_{ed}*f_{abc}
-t_{ce}*f_{dab}+t_{cd}*f_{abe}+t_{ed}*f_{bac}-t_{bc}*f_{dae}
-t_{ec}*f_{dba}-t_{cd}*f_{bae}+t_{cd}*f_{bea}-t_{db}*f_{aec}
-t_{ae}*f_{bcd}+t_{db}*f_{eac}-t_{eb}*f_{cda}-t_{ed}*f_{bca}
+t_{da}*f_{bec}+t_{ea}*f_{dbc}+t_{bd}*f_{cae}+t_{ac}*f_{dbe}
+t_{de}*f_{abc}-t_{cd}*f_{aeb}-t_{ba}*f_{cde}+t_{ec}*f_{dab}
+t_{de}*f_{cab}-t_{db}*f_{eca}-t_{de}*f_{bac}+t_{ba}*f_{dce})

Check its antisymmetry property:
def expr = "F_abcde = $r".t println expr >> 'F_abcde + F_abdce'.t   > 0  println expr >> 'F_abcde + F_decba'.t   > 0  ### Options • SymmetricForm: produces completely symmetric tensor: println GenerateTensor('_{abc}'.si, ['g_mn', 'k_m'], [SymmetricForm: true])   > (1/3)*C[0]*(g_{bc}*k_{a}+g_{ac}*k_{b}+g_{ab}*k_{c})+C[1]*k_{a}*k_{b}*k_{c}  • GeneratedParameters: Allows to control how free parameters are generated: println GenerateTensor('_{ab}'.si, ['g_mn', 'k_m'])   > C[0]*g_ab+C[1]*k_{a}*k_{b}  Control generated parameters: println GenerateTensor('_{ab}'.si,['g_mn', 'k_m'], [GeneratedParameters: {i -> "K$i".t}])


   > K0*g_ab+K1*k_{a}*k_{b}


• GenerateParameters:
if false then no parameters will be generated:
println GenerateTensor('_{ab}'.si, ['g_mn', 'k_m'], [GenerateParameters: false])


   > g_ab+k_{a}*k_{b}


• RaiseLower:
By default GenerateTensor tries to upper/lower indices of the provided samples to generate tensor of the most general form. If RaiseLower set to false, then it will use samples as is:
println GenerateTensor('_{ab}^{cd}'.si,  ['g_mn', 'k_m', 'k^m'], [RaiseLower: false])


   > C[0]*g_{ab}*k^{c}*k^{d}+C[1]*k_{a}*k_{b}*k^{c}*k^{d}

println GenerateTensor('_{ab}^{cd}'.si, ['g_mn', 'k_m']).size()

   > 10