return new Fraction(new Sum(f1.getNumerator(), f), f1.getDenominator());
}
private static Struct calcStruct(Tensor t1, Tensor t2) {
if (t1 instanceof Product && !(t2 instanceof Product)) {
TensorIterator iterator = t1.iterator();
boolean commonDetected = false;
Tensor current;
while (iterator.hasNext()) {
current = iterator.next();
if (TTest.testParity(current, t2)) {
iterator.remove();
commonDetected = true;
break;
}
}
if (commonDetected)
return new Struct(null, t1.equivalent().clone(), new Product(t1, t2));
else
return new Struct(t2.clone(), t1.clone(), new Product(t1, t2));
}
if (!(t1 instanceof Product) && t2 instanceof Product)
return calcStruct(t2, t1).inverse();
if (t1 instanceof Product && t2 instanceof Product) {
Product _t1 = (Product) t1;
Product _t2 = (Product) t2;
_t1.sort();
_t2.sort();
TensorIterator iterator1 = _t1.iterator(), iterator2 = _t2.iterator();
Tensor current1 = iterator1.next(), current2 = iterator2.next();
int hash1 = current1.hashCode(), hash2 = current2.hashCode(), oldSize = 0;
boolean process = false;
List<Tensor> common = new ArrayList<>();
List<Tensor> equalsHash1 = new ArrayList<>();
while (true) {
if (hash1 < hash2) {
if (!iterator1.hasNext())
break;
current1 = iterator1.next();
} else if (hash2 < hash1) {
if (!iterator2.hasNext())
break;
current2 = iterator2.next();
hash2 = current2.hashCode();
process = process && hash2 == equalsHash1.get(0).hashCode();
if (process) {
for (int i = equalsHash1.size() - 1; i >= oldSize; --i)
if (TTest.testParity(equalsHash1.get(i), current2)) {
iterator2.remove();
// current2 = iterator2.next();
common.add(equalsHash1.remove(i));
break;
}
oldSize = equalsHash1.size();
}
} else if (TTest.testParity(current1, current2)) {
common.add(current1);
iterator1.remove();
iterator2.remove();
if (!iterator1.hasNext() || !iterator2.hasNext())
break;
current1 = iterator1.next();
current2 = iterator2.next();
} else {
process = true;
equalsHash1.add(current1);
iterator1.remove();
if (!iterator1.hasNext())
continue;
current1 = iterator1.next();
}
hash1 = current1.hashCode();
hash2 = current2.hashCode();
}
_t1.add(equalsHash1);