}
if (res.isEmpty())
return null;
return res.equivalent();
} else if (target instanceof Product) {
Product product = (Product) target;
Tensor derivative;
List<Tensor> resultProducts = new ArrayList<>();
for (int i = 0; i < product.size(); ++i) {
derivative = getDerivative(product.getElements().get(i), var);
if (derivative == null)
continue;
Product clone = (Product) product.clone();
clone.getElements().remove(i);
if (!isOne(derivative))
clone.add(derivative);
resultProducts.add(clone.equivalent());
}
if (resultProducts.isEmpty())
return null;
if (resultProducts.size() == 1)
return resultProducts.get(0);
return new Sum(resultProducts);
} else if (target.getClass() == SimpleTensor.class) {
SimpleTensor sp = (SimpleTensor) target;
if (sp.getName() != var.getName())
return null;
if (sp.getIndices().size() == 0)
return TensorNumber.createONE();
Product kroneckers = new Product();
Indices targetIndices = sp.getIndices();
Indices varIndices = var.getIndices();
for (int i = 0; i < sp.getIndices().size(); ++i)
kroneckers.add(CC.createMetricOrKronecker(targetIndices.get(i), varIndices.get(i)));
return kroneckers.equivalent();
} else if (target.getClass() == TensorField.class) {
TensorField field = (TensorField) target;
Tensor[] args = field.getArgs();
for (int i = 0; i < args.length; ++i)
if (getDerivative(args[i], var) != null)
return Derivative.createFromInversed(target,var);
return null;
} else if (target instanceof AbstractScalarFunction) {
AbstractScalarFunction func = (AbstractScalarFunction) target;
Tensor der = getDerivative(func.getInnerTensor(), var);
if (der == null)
return null;
if (isOne(der))
return func.derivative();
return new Product(func.derivative(), der);
}
//TODO get derivative ot derivative
return null;
}