code: public GraphicalModel compileNormalizedModel() {
      GraphicalModel normalized = new GraphicalModel();
      CliqueTree.MarginalResult marginalsResult = this.calculateMarginals();
  
      double partitionFunction = marginalsResult.partitionFunction;
      assert partitionFunction >= 0.0;
  
      for (Map.Entry<GraphicalModel.Factor, TableFactor> entry : marginalsResult.jointMarginals.entrySet()) {
        GraphicalModel.Factor factor = entry.getKey();
        TableFactor tableFactor = entry.getValue();
  
        // Compute the normalization constant
        double localNorm = Math.pow(partitionFunction, -1.0 / ((double) model.factors.size()));
        assert !Double.isNaN(localNorm);
  
        // Get the normalized value if the partition function is 0
        int factorSize = 1;
        for (int dim : tableFactor.getDimensions()) {
          factorSize *= dim;
        }
        double uniformValue = 1.0 / ((double) factorSize);
  
        // Set the value
        normalized.addStaticFactor(factor.neigborIndices, factor.getDimensions(), assign -> {
          if (partitionFunction == 0) {
            return uniformValue;
          } else {
            double value = factor.getAssignmentValue(assign, weights);
            assert !Double.isNaN(value);
            return Math.log(Math.exp(value) * localNorm);
          }
        });
      }
  
      // Add any metadata
      for (int var = 0; var < model.numVariables(); ++var) {
        Map<String, String> metadata = model.getVariableMetaDataByReference(var);
        if (metadata.containsKey(VARIABLE_OBSERVED_VALUE)) {
          normalized.getVariableMetaDataByReference(var).put(VARIABLE_OBSERVED_VALUE, metadata.get(VARIABLE_OBSERVED_VALUE));
        }
      }
  
      return normalized;
    }
docs: Solve the graphical model, and then normalize all the factors.
  The new graphical model is constructed entirely with static factors -- no weights are needed
  to solve it.
  The partition function of this new graphical model should be 1.
  
  @return A static graphical model (i.e., not dependent on the weights anymore) with a partition function of 1.