Indices indices = IndicesFactory.create(tensor.getIndices().getFree());
int[] indicesArray = indices.getAllIndices().copy();
List<Permutation> symmetries = TensorUtils.getIndicesSymmetriesForIndicesWithSameStates(indicesArray, tensor);
int lowerCount = indices.getLower().size(), upperCount = indices.getUpper().size();
IntPermutationsGenerator lowIndicesPermutationsGenerator,
upperIndicesPermutationGenerator;
SumBuilder sumBuilder = new SumBuilder();
Tensor summand;
List<int[]> generatedPermutations = new ArrayList<>();
if (upperCount != 0 && lowerCount != 0) {
lowIndicesPermutationsGenerator = new IntPermutationsGenerator(lowerCount);
while (lowIndicesPermutationsGenerator.hasNext()) {
int[] lowerPermutation = lowIndicesPermutationsGenerator.next().clone();
for (int i = 0; i < lowerCount; ++i)
lowerPermutation[i] = lowerPermutation[i] + upperCount;
upperIndicesPermutationGenerator = new IntPermutationsGenerator(upperCount);
UPPER:
while (upperIndicesPermutationGenerator.hasNext()) {
int[] upperPermutation = upperIndicesPermutationGenerator.next();
summand = permute(tensor, indicesArray, upperPermutation, lowerPermutation, generatedPermutations, symmetries);
if (summand != null)
sumBuilder.put(summand);
}
}
} else if (upperCount == 0) {
lowIndicesPermutationsGenerator = new IntPermutationsGenerator(lowerCount);
while (lowIndicesPermutationsGenerator.hasNext()) {
int[] lowerPermutation = lowIndicesPermutationsGenerator.next();
summand = permute(tensor, indicesArray, new int[0], lowerPermutation, generatedPermutations, symmetries);
if (summand != null)
sumBuilder.put(summand);
}
} else if (lowerCount == 0) {
upperIndicesPermutationGenerator = new IntPermutationsGenerator(upperCount);
while (upperIndicesPermutationGenerator.hasNext()) {
int[] upperPermutation = upperIndicesPermutationGenerator.next();
summand = permute(tensor, indicesArray, upperPermutation, new int[0], generatedPermutations, symmetries);
if (summand != null)
sumBuilder.put(summand);