result[result.length - 1] = factor;
return Tensors.multiply(result);
}
SubsResult atomicSubstitute(PContent content, TIntHashSet forbidden) {
Mapping mapping = null;
int[] indexlessBijection, dataBijection;
IndexlessBijectionsPort indexlessPort
= new IndexlessBijectionsPort(fromIndexless, content.indexless);
while ((indexlessBijection = indexlessPort.take()) != null) {
mapping = createBijectiveProductPort(fromIndexless, extract(content.indexless, indexlessBijection)).take();
if (mapping != null)
break;
}
if (mapping == null)
return null;
boolean sign = mapping.getSign();
mapping = null;
Tensor[] currentData;
if (content.data instanceof Product) {
ProductContent currentContent = ((Product) content.data).getContent();
currentData = currentContent.getDataCopy();
ProductsBijectionsPort dataPort = new ProductsBijectionsPort(fromContent, currentContent);
while ((dataBijection = dataPort.take()) != null) {
mapping = createBijectiveProductPort(fromData, extract(currentData, dataBijection)).take();
if (mapping != null)
break;
}
} else {
if (TensorUtils.isOne(content.data)) {
if (fromContent.size() != 0)
return null;
dataBijection = new int[0];
currentData = new Tensor[0];
mapping = Mapping.IDENTITY;
} else {
if (fromContent.size() != 1)
return null;
dataBijection = new int[1];
currentData = new Tensor[]{content.data};
mapping = getFirst(fromContent.get(0), content.data);
}
}
if (mapping == null)
return null;
mapping = mapping.addSign(sign);
Arrays.sort(indexlessBijection);
Arrays.sort(dataBijection);
Tensor[] indexlessRemainder = new Tensor[content.indexless.length - fromIndexless.length];
ProductBuilder dataRemainder = new ProductBuilder(0,
(content.data instanceof Product)
? content.data.size()
: 1 - fromContent.size());
int pivot = 0;
int i, j = 0;
for (i = 0; i < content.indexless.length; ++i) {
if (pivot < indexlessBijection.length && i == indexlessBijection[pivot])
++pivot;
else
indexlessRemainder[j++] = content.indexless[i];
}
pivot = 0;
for (i = 0; i < currentData.length; ++i) {
if (pivot < dataBijection.length && i == dataBijection[pivot])
++pivot;
else
dataRemainder.put(currentData[i]);
}
Tensor dataRemainderT = dataRemainder.build();
PContent remainder = new PContent(indexlessRemainder, dataRemainderT);
Tensor newTo;
if (toIsSymbolic)
newTo = mapping.getSign() ? Tensors.negate(to) : to;
else {
TIntHashSet remainderIndices = new TIntHashSet(forbidden);
remainderIndices.addAll(getAllIndicesNamesT(indexlessRemainder));
remainderIndices.addAll(getAllIndicesNamesT(dataRemainderT));
newTo = applyIndexMapping(to, mapping, remainderIndices.toArray());