docs: public DiscreteFactor outerProduct(Factor other) {
      Preconditions.checkArgument(getVars().intersection(other.getVars()).size() == 0);
      DiscreteFactor otherAsDiscrete = other.coerceToDiscrete();
  
      // See if the fast, tensor outer product implementation is usable.
      int[] myDims = getVars().getVariableNumsArray();
      int[] otherDims = other.getVars().getVariableNumsArray();
      if (myDims.length == 0 || otherDims.length == 0 || myDims[myDims.length - 1] < otherDims[0]) {
        return new TableFactor(getVars().union(other.getVars()), 
            getWeights().outerProduct(otherAsDiscrete.getWeights()));
      }
      
      // This implementation is slow, but Tensors currently don't support all
      // outer products.
      TableFactorBuilder builder = new TableFactorBuilder(getVars().union(other.getVars()),
          SparseTensorBuilder.getFactory());
      Iterator<Outcome> myIter = outcomeIterator();
      while (myIter.hasNext()) {
        Outcome myOutcome = myIter.next();
        Iterator<Outcome> otherIter = otherAsDiscrete.outcomeIterator();
        while (otherIter.hasNext()) {
          Outcome otherOutcome = otherIter.next();
          builder.setWeight(myOutcome.getAssignment().union(otherOutcome.getAssignment()),
              myOutcome.getProbability() * otherOutcome.getProbability());
        }
      }
      return builder.build();
    }