public static Tensor applyIndexMappingWithDiffStates(Tensor target,
int[] from, int[] to, int[] usedIndices) {
if (from.length != to.length)
throw new IllegalArgumentException();
IndexMappingImpl preprocess = new IndexMappingImpl();
//creating metrics for rising-lowing indices
int fromIndex, toIndex, fromState, toState;
IndexGenerator ig = new IndexGenerator(TensorUtils.getAllIndices(target));
List<SimpleTensor> metrics = new ArrayList<>();
int i = 0;
for (; i < from.length; ++i) {
//diff states mapping detected
if ((fromState = IndicesUtils.getRawStateInt(from[i])) != (toState = IndicesUtils.getRawStateInt(to[i]))) {
fromIndex = IndicesUtils.getNameWithType(from[i]);
toIndex = ig.generate(IndicesUtils.getType(fromIndex));
preprocess.add(fromIndex, toIndex);
if (fromState != 0)
metrics.add(CC.createMetric(fromIndex, toIndex));
else
metrics.add(CC.createMetric(0x80000000 | fromIndex, 0x80000000 | toIndex));
}
from[i] = IndicesUtils.getNameWithType(from[i]);
to[i] = IndicesUtils.getNameWithType(to[i]);
}
//preprocessing conflicting indices
target = ApplyIndexMappingTransformation.INSTANCE.perform(target, preprocess);
//adding metrics
if (!metrics.isEmpty()) {
Product p = new Product();
p.add(target);
p.add(metrics);
target = p;
}
IndexMappingImpl im = new IndexMappingImpl(usedIndices, from, to);
return ApplyIndexMappingTransformation.INSTANCE.perform(target, im);
}