@Override
    public final Tensor evaluate(EvaluationContext<NAMETYPE> context) {
        Tensor a = argumentA.evaluate(context);
        Tensor b = argumentB.evaluate(context);
        TensorType joinedType = new TensorType.Builder(a.type(), b.type()).build();

        if (canOptimize(a, b)) {
            return evaluate((IndexedTensor)a, (IndexedTensor)b, joinedType);
        }
        return Reduce.evaluate(Join.evaluate(a, b, joinedType, combinator), dimensions, aggregator);
    }
An optimization for tensor expressions where a join immediately follows a
reduce. Evaluating this as one operation is significantly more efficient
than evaluating each separately.

This implementation optimizes the case where the reduce is done on the same
dimensions as the join. A particularly efficient evaluation is done if there
is one common dimension that is joined and reduced on, which is a common
case as it covers vector and matrix like multiplications.

@author lesters
vespajlib/src/main/java/com/yahoo/tensor/functions/ReduceJoin.java