@Override
public Tensor transform(Tensor tensor) {
//todo check for contains gammas
tensor = ExpandTransformation.expand(tensor, EliminateMetricsTransformation.ELIMINATE_METRICS);
tensor = EliminateMetricsTransformation.eliminate(tensor);
FromChildToParentIterator iterator = new FromChildToParentIterator(tensor);
Tensor current;
out:
while ((current = iterator.next()) != null) {
if (isGammaOrGamma5(current)
&& current.getIndices().getFree().size(matrixType) == 0) {
iterator.set(Complex.ZERO);
} else if (current instanceof Product) {
if (current.getIndices().getFree().size(matrixType) != 0)
continue;
Product product = (Product) current;
ProductContent pc = product.getContent();
int sizeOfIndexless = product.sizeOfIndexlessPart();
PrimitiveSubgraph[] partition
= PrimitiveSubgraphPartition.calculatePartition(pc, matrixType);
for (PrimitiveSubgraph subgraph : partition) {
if (subgraph.getGraphType() != GraphType.Cycle)
continue;
int[] positions = subgraph.getPartition();
//actual positions in current
for (int i = positions.length - 1; i >= 0; --i)
positions[i] = positions[i] + sizeOfIndexless;
int[] gg = calculateGammasInProduct(product.select(positions));
if (gg[0] + gg[1] != positions.length)
continue;
assert positions.length != 0;
if (positions.length == 1) {
iterator.set(Complex.ZERO);
continue out;
}
int gammasCount = gg[0];
int gamma5Count = gg[1];
if (gammasCount == 0) {
if (gamma5Count % 2 == 0) {
iterator.set(multiply(product.remove(positions), Complex.FOUR));
continue out;
} else {
iterator.set(Complex.ZERO);
continue out;
}
}
if (gamma5Count == 0 && gammasCount % 2 == 1) {
iterator.set(Complex.ZERO);
continue out;
}
if (gamma5Count % 2 == 1 && gammasCount % 2 == 1) {
iterator.set(Complex.ZERO);
continue out;
}
if (gamma5Count == 0)
current = traceWithout5(current, gammasCount);
else
current = trace5((Product) current, gammasCount, gamma5Count);
}
//todo d_i^i = 4
iterator.set(current);
}
}
return iterator.result();
}