SubstitutionIterator iterator = new SubstitutionIterator(tensor);
Tensor current;
while ((current = iterator.next()) != null) {
if (!(current instanceof Product))
continue;
Product cp = (Product) current;
while (true) {
IndexMappingBuffer buffer = null;
final Tensor[] currentIndexless = cp.getIndexless();
int[] indexlessBijection;
IndexlessBijectionsPort indexlessPort = new IndexlessBijectionsPort(fromIndexless, currentIndexless);
while ((indexlessBijection = indexlessPort.take()) != null) {
buffer = IndexMappings.createBijectiveProductPort(fromIndexless, extract(currentIndexless, indexlessBijection)).take();
if (buffer != null)
break;
}
if (buffer == null)
break;
boolean sign = buffer.getSignum();
buffer = null;
ProductContent currentContent = cp.getContent();
final Tensor[] currentData = currentContent.getDataCopy();
int[] dataBijection;
ProductsBijectionsPort dataPort = new ProductsBijectionsPort(fromContent, currentContent);
while ((dataBijection = dataPort.take()) != null) {
buffer = IndexMappings.createBijectiveProductPort(fromData, extract(currentData, dataBijection)).take();
if (buffer != null)
break;
}
if (buffer == null)
break;
buffer.addSignum(sign);
Tensor newTo;
if (symbolic)
newTo = to;
else {
int[] forbidden = new int[iterator.forbiddenIndices().size()];
int c = -1;
for (Integer f : iterator.forbiddenIndices())
forbidden[++c] = f;
Tensor temp = to;
newTo = ApplyIndexMapping.applyIndexMapping(temp, buffer, forbidden);
if (temp != newTo)
iterator.forbiddenIndices().addAll(TensorUtils.getAllIndicesNames(newTo));
}
Arrays.sort(indexlessBijection);
Arrays.sort(dataBijection);
ProductBuilder builder = new ProductBuilder();
builder.put(newTo);
int i;
for (i = 0; i < currentIndexless.length; ++i)
if (Arrays.binarySearch(indexlessBijection, i) < 0)
builder.put(currentIndexless[i]);
for (i = 0; i < currentData.length; ++i)
if (Arrays.binarySearch(dataBijection, i) < 0)
builder.put(currentData[i]);
builder.put(cp.getFactor().divide(fromFactor));
current = builder.build();
if (!(current instanceof Product))
break;
cp = (Product) current;
}