Package cc.redberry.physics.feyncalc

Source Code of cc.redberry.physics.feyncalc.UnitaryTrace$CacheContainer

/*
* Redberry: symbolic tensor computations.
*
* Copyright (c) 2010-2013:
*   Stanislav Poslavsky   <stvlpos@mail.ru>
*   Bolotin Dmitriy       <bolotin.dmitriy@gmail.com>
*
* This file is part of Redberry.
*
* Redberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Redberry is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Redberry. If not, see <http://www.gnu.org/licenses/>.
*/
package cc.redberry.physics.feyncalc;

import cc.redberry.core.indexgenerator.IndexGenerator;
import cc.redberry.core.indices.IndexType;
import cc.redberry.core.indices.IndicesFactory;
import cc.redberry.core.indices.SimpleIndices;
import cc.redberry.core.number.Complex;
import cc.redberry.core.tensor.*;
import cc.redberry.core.tensor.iterator.FromChildToParentIterator;
import cc.redberry.core.transformations.EliminateMetricsTransformation;
import cc.redberry.core.transformations.Transformation;
import cc.redberry.core.transformations.expand.ExpandTransformation;
import cc.redberry.core.utils.ArraysUtils;
import cc.redberry.core.utils.TensorUtils;

import java.util.*;

import static cc.redberry.core.tensor.Tensors.*;

/**
* @author Dmitry Bolotin
* @author Stanislav Poslavsky
*/
public final class UnitaryTrace implements Transformation {
    private final SimpleTensor SuN, f, d;
    private final Tensor N;

    public UnitaryTrace(SimpleTensor suN, SimpleTensor f, SimpleTensor d, Tensor n) {
        SuN = suN;
        this.f = f;
        this.d = d;
        N = n;
    }

    @Override
    public Tensor transform(Tensor t) {
        return unitaryTrace(t, SuN, f, d, N);
    }

    public static final Tensor unitaryTrace(Tensor t) {
        return unitaryTrace(t, parseSimple("T^a'_b'a"), parseSimple("f_abc"), parseSimple("d_abc"), parseSimple("N"));
    }

    public static final Tensor unitaryTrace(Tensor tensor, SimpleTensor SuN, SimpleTensor f, SimpleTensor d, Tensor N) {
        IndexType[] types = TraceUtils.extractTypesFromMatrix(SuN);
        FromChildToParentIterator iterator = new FromChildToParentIterator(tensor);
        Tensor c;
        while ((c = iterator.next()) != null) {
            if (c instanceof SimpleTensor) {
                if (((SimpleTensor) c).getName() == SuN.getName() && c.getIndices().getOfType(types[1]).getFree().size() == 0)
                    iterator.set(Complex.ZERO);
            } else if (c instanceof Product) {
                TensorBuilder suns = new ProductBuilder();
                boolean containsSun = false;
                Tensor nonSun = c;
                for (int i = c.size() - 1; i >= 0; --i) {
                    if (isSuN(c.get(i), SuN.getName())) {
                        containsSun = true;
                        suns.put(c.get(i));
                        if (nonSun instanceof Product)
                            nonSun = ((Product) nonSun).remove(i);
                        else {
                            assert i == 0;
                            nonSun = Complex.ONE;
                        }
                    }
                }
                if (!containsSun)
                    continue;
                Tensor temp = multiply(nonSun, traceOfProduct(suns.build(), SuN.getName(), f.getName(), d.getName(), N, types[0], types[1]));
                temp = ExpandTransformation.expand(temp, EliminateMetricsTransformation.ELIMINATE_METRICS);
                temp = EliminateMetricsTransformation.eliminate(temp);
                iterator.set(temp);
            }
        }
        return iterator.result();
    }

    private static Tensor traceOfProduct(Tensor tensor,
                                         int sunName, int fName, int dName, Tensor N,
                                         IndexType metricType, IndexType matrixType) {
        Expression[] subs = getSubstitutions(sunName, fName, dName, N, metricType, matrixType);
        Transformation[] transformations = new Transformation[]{EliminateMetricsTransformation.ELIMINATE_METRICS};
        transformations = ArraysUtils.addAll(transformations, Arrays.copyOfRange(subs, 1, subs.length));

        Tensor oldTensor = tensor, newTensor;
        while (true) {
            newTensor = subs[0].transform(oldTensor);
            newTensor = ExpandTransformation.expand(newTensor, transformations);
            for (Transformation tr : transformations)
                newTensor = tr.transform(newTensor);
            if (newTensor == oldTensor)
                break;
            oldTensor = newTensor;
        }

        return newTensor;
    }

    private static final boolean isSuN(Tensor tensor, int sunName) {
        return tensor instanceof SimpleTensor && ((SimpleTensor) tensor).getName() == sunName;
    }

    private static final class CacheContainer {
        final int sunName, fName, dName;
        final Tensor N;

        private CacheContainer(int sunName, int fName, int dName, Tensor n) {
            this.sunName = sunName;
            this.fName = fName;
            this.dName = dName;
            this.N = n;
        }

        @Override
        public boolean equals(Object o) {
            CacheContainer that = (CacheContainer) o;
            return sunName == that.sunName &&
                    fName == that.sunName &&
                    dName == that.dName &&
                    TensorUtils.equals(N, that.N);
        }

        @Override
        public int hashCode() {
            int result = sunName;
            result = 31 * result + fName;
            result = 31 * result + dName;
            result = 31 * result + N.hashCode();
            return result;
        }

    }

    //todo static expression vs CC.resetTensorNames
    private static final Map<CacheContainer, Expression[]> cachedSubstitutions = new HashMap<>();

    private static Expression[] getSubstitutions(int sunName, int fName, int dName, Tensor N,
                                                 IndexType metricType, IndexType matrixType) {
        CacheContainer cacheContainer = new CacheContainer(sunName, fName, dName, N);
        Expression[] expressions = cachedSubstitutions.get(cacheContainer);
        if (expressions != null)
            return expressions;
        List<Expression> expressionsList = new ArrayList<>();
        IndexGenerator generator = new IndexGenerator();

        //creating  T_a*T_b  = 1/2N g_ab + I/2*f_abc*T^c + 1/2*d_abc*T^c
        int upper, lower, contracted, firstMetric, secondMetric, thirdMetric;
        SimpleIndices indicesOfA = IndicesFactory.createSimple(null,
                firstMetric = generator.generate(metricType),
                upper = (0x80000000 | generator.generate(matrixType)),
                contracted = generator.generate(matrixType));

        SimpleIndices indicesOfB = IndicesFactory.createSimple(null,
                secondMetric = generator.generate(metricType),
                (0x80000000 | contracted),
                lower = generator.generate(matrixType));

        SimpleIndices indicesOfC = IndicesFactory.createSimple(null,
                (0x80000000 | (thirdMetric = generator.generate(metricType))),
                upper, lower);

        Tensor lhs = multiply(simpleTensor(sunName, indicesOfA),
                simpleTensor(sunName, indicesOfB));

        //(1/(2*N))*g_ab
        Tensor gTerm = multiply(Complex.ONE_HALF, reciprocal(N),
                createMetric(firstMetric, secondMetric), createKronecker(upper, lower));

        SimpleIndices fIndices = IndicesFactory.createSimple(null, firstMetric, secondMetric, thirdMetric);
        Tensor C = simpleTensor(sunName, indicesOfC);
        //(I/2)*f_abc*T^c
        Tensor fTerm = multiply(Complex.ONE_HALF, Complex.IMAGE_ONE,
                simpleTensor(fName, fIndices), C);
        //(1/2)*d_abc*T^c
        Tensor dTerm = multiply(Complex.ONE_HALF,
                simpleTensor(dName, fIndices), C);

        expressionsList.add(expression(lhs, sum(gTerm, fTerm, dTerm)));

        //creating Tr[T] = 0
        indicesOfA = IndicesFactory.createSimple(null, firstMetric, (0x80000000 | contracted), contracted);
        expressionsList.add(expression(simpleTensor(sunName, indicesOfA), Complex.ZERO));

        //creating d_apq*d_b^pq = (N**2 - 4)/N * g_ab
        indicesOfA = IndicesFactory.createSimple(null,
                upper = generator.generate(metricType),
                firstMetric = generator.generate(metricType),
                secondMetric = generator.generate(metricType));
        indicesOfB = IndicesFactory.createSimple(null,
                lower = generator.generate(metricType),
                (0x80000000 | firstMetric),
                (0x80000000 | secondMetric));

        lhs = multiply(simpleTensor(dName, indicesOfA), simpleTensor(dName, indicesOfB));
        Tensor rhs = multiply(reciprocal(N), subtract(pow(N, 2), Complex.FOUR), createMetric(upper, lower));
        expressionsList.add(expression(lhs, rhs));

        //creating f_apq*f_b^pq = N * g_ab
        lhs = multiply(simpleTensor(fName, indicesOfA), simpleTensor(fName, indicesOfB));
        rhs = multiply(N, createMetric(upper, lower));
        expressionsList.add(expression(lhs, rhs));

        //creating f_apq*d_b^pq = 0
        lhs = multiply(simpleTensor(fName, indicesOfA), simpleTensor(dName, indicesOfB));
        expressionsList.add(expression(lhs, Complex.ZERO));


        //creating Tr[1] = N
        lhs = createKronecker(contracted, (0x80000000 | contracted));
        expressionsList.add(expression(lhs, N));

        expressions = expressionsList.toArray(new Expression[expressionsList.size()]);
        cachedSubstitutions.put(cacheContainer, expressions);
        return expressions;
    }
}
TOP

Related Classes of cc.redberry.physics.feyncalc.UnitaryTrace$CacheContainer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.