private static Tensor reduceGeneral(Tensor argument, TensorType reducedType, int[] indexesToKeep, Aggregator aggregator) {
        // TODO cells.size() is most likely an overestimate, and might need a better heuristic
        // But the upside is larger than the downside.
        Map<TensorAddress, ValueAggregator> aggregatingCells = new HashMap<>(argument.sizeAsInt());
        for (Iterator<Tensor.Cell> i = argument.cellIterator(); i.hasNext(); ) {
            Map.Entry<TensorAddress, Double> cell = i.next();
            TensorAddress reducedAddress = cell.getKey().partialCopy(indexesToKeep);
            ValueAggregator aggr = aggregatingCells.computeIfAbsent(reducedAddress, (key) ->ValueAggregator.ofType(aggregator));
            aggr.aggregate(cell.getValue());
        }
        Tensor.Builder reducedBuilder = Tensor.Builder.of(reducedType);
        for (Map.Entry<TensorAddress, ValueAggregator> aggregatingCell : aggregatingCells.entrySet())
            reducedBuilder.cell(aggregatingCell.getKey(), aggregatingCell.getValue().aggregatedValue());

        return reducedBuilder.build();
    }
Creates a reduce function.

@param argument the tensor to reduce
@param aggregator the aggregator function to use
@param dimensions the list of dimensions to remove. If an empty list is given, all dimensions are reduced,
                  producing a dimensionless tensor (a scalar).
@throws IllegalArgumentException if any of the tensor dimensions are not present in the input tensor
vespajlib/src/main/java/com/yahoo/tensor/functions/Reduce.java