docs: public static DiscreteLogLinearFactor fromFeatureGeneratorSparse(DiscreteFactor factor,
        FeatureGenerator<Assignment, String> featureGen) {
      Iterator<Outcome> iter = factor.outcomeIterator();
      Set<String> featureNames = Sets.newHashSet();
      while (iter.hasNext()) {
        Outcome o = iter.next();
        for (Map.Entry<String, Double> f : featureGen.generateFeatures(o.getAssignment()).entrySet()) {
          featureNames.add(f.getKey());
        }
      }
      
      List<String> featureNamesSorted = Lists.newArrayList(featureNames);
      Collections.sort(featureNamesSorted);
      
      DiscreteVariable featureType = new DiscreteVariable(FEATURE_VAR_NAME, featureNamesSorted);
      VariableNumMap featureVar = VariableNumMap.singleton(
          Ints.max(factor.getVars().getVariableNumsArray()) + 1, FEATURE_VAR_NAME, featureType);
      TableFactorBuilder builder = new TableFactorBuilder(
          factor.getVars().union(featureVar), SparseTensorBuilder.getFactory());
      
      iter = factor.outcomeIterator();
      while (iter.hasNext()) {
        Outcome o = iter.next();
        for (Map.Entry<String, Double> f : featureGen.generateFeatures(o.getAssignment()).entrySet()) {
          Assignment featureAssignment = featureVar.outcomeArrayToAssignment(f.getKey());
          builder.setWeight(o.getAssignment().union(featureAssignment), f.getValue());
        }
      }
  
      DiscreteFactor featureFactor = builder.build();
      return new DiscreteLogLinearFactor(factor.getVars(), featureVar, featureFactor, factor);
    }