All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cc.redberry.physics.feyncalc.SimplifyGamma5Transformation Maven / Gradle / Ivy

/*
 * Redberry: symbolic tensor computations.
 *
 * Copyright (c) 2010-2015:
 *   Stanislav Poslavsky   
 *   Bolotin Dmitriy       
 *
 * 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 .
 */
package cc.redberry.physics.feyncalc;

import cc.redberry.core.graph.GraphType;
import cc.redberry.core.graph.PrimitiveSubgraph;
import cc.redberry.core.graph.PrimitiveSubgraphPartition;
import cc.redberry.core.number.Complex;
import cc.redberry.core.tensor.Product;
import cc.redberry.core.tensor.ProductContent;
import cc.redberry.core.tensor.SimpleTensor;
import cc.redberry.core.tensor.Tensor;
import cc.redberry.core.tensor.iterator.FromChildToParentIterator;
import cc.redberry.core.transformations.options.Creator;
import cc.redberry.core.transformations.options.Options;
import cc.redberry.core.utils.IntArrayList;

import java.util.ArrayList;
import java.util.List;

import static cc.redberry.core.indices.IndicesFactory.createSimple;
import static cc.redberry.core.indices.IndicesUtils.raise;
import static cc.redberry.core.tensor.Tensors.*;

/**
 * @author Dmitry Bolotin
 * @author Stanislav Poslavsky
 */
public final class SimplifyGamma5Transformation extends AbstractTransformationWithGammas {
    public SimplifyGamma5Transformation(SimpleTensor gammaMatrix, SimpleTensor gamma5) {
        super(gammaMatrix, gamma5, null, null, null);
    }

    @Creator
    public SimplifyGamma5Transformation(@Options DiracOptions options) {
        this(options.gammaMatrix, options.gamma5);
    }

    @Override
    public Tensor transform(Tensor tensor) {
        FromChildToParentIterator iterator = new FromChildToParentIterator(tensor);
        Tensor current;
        while ((current = iterator.next()) != null) {
            if (!(current instanceof Product))
                continue;
            if (current.getIndices().size(matrixType) == 0)
                continue;
            Product product = (Product) current;
            int offset = product.sizeOfIndexlessPart();
            ProductContent pc = product.getContent();

            PrimitiveSubgraph[] partition
                    = PrimitiveSubgraphPartition.calculatePartition(pc, matrixType);

            IntArrayList positionsOfGammas = new IntArrayList();
            List ordered = new ArrayList<>();
            out:
            for (PrimitiveSubgraph subgraph : partition) {
                if (subgraph.getGraphType() != GraphType.Cycle && subgraph.getGraphType() != GraphType.Line)
                    continue;

                if (subgraph.size() < 2)
                    continue;

                int g5 = 0;
                for (int i = 0; i < subgraph.size(); ++i)
                    if (isGamma5(pc.get(subgraph.getPosition(i))))
                        ++g5;
                if (g5 == 0)
                    continue;
                if (g5 == 1) {
                    if (subgraph.getGraphType() == GraphType.Cycle)
                        continue;
                    //check g5 is not last
                    for (int i = subgraph.size() - 1; i >= 0; --i)
                        if (isGamma(pc.get(subgraph.getPosition(i))))
                            break;
                        else if (isGamma5(pc.get(subgraph.getPosition(i))))
                            continue out;
                }

                List gammas = new ArrayList<>();
                for (int i = 0; i < subgraph.size(); ++i) {
                    for (; i < subgraph.size(); ++i) {
                        if (!isGammaOrGamma5(pc.get(subgraph.getPosition(i))))
                            break;
                        else {
                            positionsOfGammas.add(offset + subgraph.getPosition(i));
                            gammas.add(pc.get(subgraph.getPosition(i)));
                        }
                    }
                    if (!gammas.isEmpty())
                        ordered.add(simplifyProduct(gammas));
                    gammas.clear();
                }
            }
            if (positionsOfGammas.isEmpty())
                continue;

            ordered.add(product.remove(positionsOfGammas.toArray()));
            iterator.set(multiply(ordered));
        }
        return iterator.result();
    }

    private Tensor simplifyProduct(List gammas) {
        if (gammas.size() == 0)
            return Complex.ONE;
        else if (gammas.size() == 1)
            return gammas.get(0);
        int upper = gammas.get(0).getIndices().getUpper().get(matrixType, 0),
                lower = gammas.get(gammas.size() - 1).getIndices().getLower().get(matrixType, 0);
        int initialSize = gammas.size();
        boolean sign = false;
        int dummy = -1;
        for (int i = gammas.size() - 1; i >= 0; --i) {
            if (isGamma5(gammas.get(i))) {
                sign ^= (gammas.size() - i) % 2 == 0;
                dummy = del(gammas, i);
            }
        }
        if ((initialSize - gammas.size()) % 2 == 1) {
            //adding last gamma
            if (gammas.isEmpty())
                gammas.add(simpleTensor(gamma5Name,
                        createSimple(null, upper, lower)));
            else {
                Tensor t = gammas.get(gammas.size() - 1);
                gammas.set(gammas.size() - 1, setLowerMatrixIndex((SimpleTensor) t, dummy));
                gammas.add(simpleTensor(gamma5Name,
                        createSimple(null, raise(dummy), t.getIndices().getLower().get(matrixType, 0))));
            }
        }
        Tensor r = multiply(gammas);
        if (sign) r = negate(r);
        return r;
    }

    private int del(List arr, int i) {
        Tensor t = arr.remove(i);
        if (arr.isEmpty())
            return t.getIndices().getLower().get(matrixType, 0);
        if (i == 0) {
            arr.set(0, setUpperMatrixIndex((SimpleTensor) arr.get(0),
                    t.getIndices().getUpper().get(matrixType, 0)));
            return t.getIndices().getLower().get(matrixType, 0);
        } else if (i == arr.size()) {
            arr.set(arr.size() - 1, setLowerMatrixIndex((SimpleTensor) arr.get(arr.size() - 1),
                    t.getIndices().getLower().get(matrixType, 0)));
            return t.getIndices().getUpper().get(matrixType, 0);
        } else {
            arr.set(i, setUpperMatrixIndex((SimpleTensor) arr.get(i),
                    t.getIndices().getUpper().get(matrixType, 0)));
            return t.getIndices().getLower().get(matrixType, 0);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy