public static void main(String[] args) throws Exception {

    // We first load the WasteIncinerator bayesian network which has multinomial and Gaussian
    // variables.
    BayesianNetwork bn = BayesianNetworkLoader.loadFromFile("./networks/WasteIncinerator.bn");

    // We recover the relevant variables for this example: Mout which is normally distributed, and W
    // which is multinomial.
    Variable varMout = bn.getVariables().getVariableByName("Mout");
    Variable varW = bn.getVariables().getVariableByName("W");

    // First we create an instance of a inference algorithm. In this case, we use the
    // ImportanceSampling class.
    ImportanceSampling inferenceAlgorithm = new ImportanceSampling();
    // Then, we set the BN model
    inferenceAlgorithm.setModel(bn);

    System.out.println(bn.toString());

    // If it exists, we also set the evidence.
    Assignment assignment = new HashMapAssignment(1);
    assignment.setValue(varW, 0);
    inferenceAlgorithm.setEvidence(assignment);

    // We can also set to be run in parallel on multicore CPUs
    inferenceAlgorithm.setParallelMode(true);

    // To perform more than one operation, data should be keep in memory
    inferenceAlgorithm.setKeepDataOnMemory(true);

    // Then we run inference
    inferenceAlgorithm.runInference();

    // Then we query the posterior of
    System.out.println("P(Mout|W=0) = " + inferenceAlgorithm.getPosterior(varMout));

    // Or some more refined queries
    System.out.println(
        "P(0.7<Mout<6.59 | W=0) = "
            + inferenceAlgorithm.getExpectedValue(varMout, v -> (0.7 < v && v < 6.59) ? 1.0 : 0.0));

    // We can also compute the probability of the evidence
    System.out.println("P(W=0) = " + Math.exp(inferenceAlgorithm.getLogProbabilityOfEvidence()));
  }
  @Test
  public void testNoFading() throws IOException, ClassNotFoundException {

    // load the true WasteIncinerator hugin Bayesian network containing 3 Multinomial and 6 Gaussian
    // variables

    BayesianNetwork trueBN = BayesianNetworkLoader.loadFromFile("./networks/WasteIncinerator.bn");

    System.out.println("\nWasteIncinerator network \n ");
    System.out.println(trueBN.getDAG().toString());
    System.out.println(trueBN.toString());

    // Sampling from trueBN
    BayesianNetworkSampler sampler = new BayesianNetworkSampler(trueBN);
    sampler.setSeed(0);

    // Load the sampled data
    DataStream<DataInstance> data = sampler.sampleToDataStream(100000);

    // Parameter Learning
    MaximumLikelihoodFading maximumLikelihoodFading = new MaximumLikelihoodFading();
    maximumLikelihoodFading.setLaplace(false);
    maximumLikelihoodFading.setFadingFactor(1.0);
    maximumLikelihoodFading.setBatchSize(1000);
    maximumLikelihoodFading.setDAG(trueBN.getDAG());
    maximumLikelihoodFading.setDataStream(data);

    maximumLikelihoodFading.runLearning();
    BayesianNetwork bnet = maximumLikelihoodFading.getLearntBayesianNetwork();

    // Check if the probability distributions of each node
    for (Variable var : trueBN.getVariables()) {
      System.out.println("\n------ Variable " + var.getName() + " ------");
      System.out.println("\nTrue distribution:\n" + trueBN.getConditionalDistribution(var));
      System.out.println("\nLearned distribution:\n" + bnet.getConditionalDistribution(var));
      Assert.assertTrue(
          bnet.getConditionalDistribution(var)
              .equalDist(trueBN.getConditionalDistribution(var), 0.05));
    }

    // Or check directly if the true and learned networks are equals
    Assert.assertTrue(bnet.equalBNs(trueBN, 0.05));
  }