public static Tensor symmetrize(SimpleTensor tensor, int[] freeIndices, Symmetries symmetries) { if (symmetries.isEmpty()) return tensor; int[] tempI = freeIndices.clone(); int[] allFreeIndices = tensor.getIndices().getFree().getAllIndices().copy(); Arrays.sort(tempI); Arrays.sort(allFreeIndices); int[] diff = MathUtils.intSetDifference(tempI, allFreeIndices); System.arraycopy(freeIndices, 0, allFreeIndices, 0, freeIndices.length); System.arraycopy(diff, 0, allFreeIndices, freeIndices.length, diff.length); SumBuilder builder = new SumBuilder(); Tensor temp; for (Symmetry symmetry : symmetries) { temp = applyIndexMapping(tensor, allFreeIndices, permute(allFreeIndices, symmetry), new int[0]); if (symmetry.isAntiSymmetry()) temp = negate(temp); builder.put(temp); } temp = builder.build(); if (temp instanceof Sum) { // retrieving factor Complex factor = null, tempF; for (int i = temp.size() - 1; i >= 0; --i) { if (temp.get(i) instanceof Product) { tempF = ((Product) temp.get(i)).getFactor(); assert tempF.isInteger(); tempF = tempF.abs(); } else tempF = Complex.ONE; if (factor == null) factor = tempF; assert factor.equals(tempF); } if (!factor.isOne()) temp = FastTensors.multiplySumElementsOnFactor((Sum) temp, factor.reciprocal()); return multiply(new Complex(new Rational(1, temp.size())), temp); } return temp; }