/**
   * Tests that models can be created that have multiple factors over the same edge, and that
   * potentialOfEdge returns the product in that case.
   */
  public void testMultipleEdgePotentials() {
    Variable v1 = new Variable(2);
    Variable v2 = new Variable(2);
    Variable[] vars = new Variable[] {v1, v2};

    FactorGraph mdl = new FactorGraph(vars);

    Factor ptl1 = new TableFactor(vars, new double[] {0.5, 0.5, 0.5, 0.5});
    mdl.addFactor(ptl1);

    Factor ptl2 = new TableFactor(vars, new double[] {0.25, 0.25, 0.5, 0.5});
    mdl.addFactor(ptl2);

    try {
      mdl.factorOf(v1, v2);
      fail();
    } catch (RuntimeException e) {
    }

    Collection factors = mdl.allFactorsContaining(new HashVarSet(vars));
    assertEquals(2, factors.size());
    assertTrue(factors.contains(ptl1));
    assertTrue(factors.contains(ptl2));

    double[] vals = {0.125, 0.125, 0.25, 0.25};
    Factor total = TableFactor.multiplyAll(factors);
    Factor expected = new TableFactor(vars, vals);

    assertTrue(
        "Arrays not equal\n  Expected "
            + ArrayUtils.toString(vals)
            + "\n  Actual "
            + ArrayUtils.toString(((TableFactor) total).toValueArray()),
        expected.almostEquals(total, 1e-10));
  }
  /**
   * Tests that models can be created that have multiple factors over the same variable, and that
   * potentialOfVertex returns the product in that case.
   */
  public void testMultipleNodePotentials() {
    Variable var = new Variable(2);
    FactorGraph mdl = new FactorGraph(new Variable[] {var});

    Factor ptl1 = new TableFactor(var, new double[] {0.5, 0.5});
    mdl.addFactor(ptl1);

    Factor ptl2 = new TableFactor(var, new double[] {0.25, 0.25});
    mdl.addFactor(ptl2);

    // verify that factorOf(var) doesn't work
    try {
      mdl.factorOf(var);
      fail();
    } catch (RuntimeException e) {
    } // expected

    List factors = mdl.allFactorsOf(var);
    Factor total = TableFactor.multiplyAll(factors);
    double[] expected = {0.125, 0.125};
    assertTrue(
        "Arrays not equal\n  Expected "
            + ArrayUtils.toString(expected)
            + "\n  Actual "
            + ArrayUtils.toString(((TableFactor) total).toValueArray()),
        Arrays.equals(expected, ((TableFactor) total).toValueArray()));
  }
  public void testPotentialConnections() {
    Variable v1 = new Variable(2);
    Variable v2 = new Variable(2);
    Variable v3 = new Variable(2);
    Variable[] vars = new Variable[] {v1, v2, v3};
    FactorGraph mdl = new FactorGraph();

    TableFactor ptl = new TableFactor(vars, new double[8]);
    mdl.addFactor(ptl);

    assertTrue(mdl.isAdjacent(v1, v2));
    assertTrue(mdl.isAdjacent(v2, v3));
    assertTrue(mdl.isAdjacent(v1, v3));
  }
  public void testFactorOfSet() {
    Variable[] vars = new Variable[3];
    for (int i = 0; i < vars.length; i++) {
      vars[i] = new Variable(2);
    }
    Factor factor = new TableFactor(vars, new double[] {0, 1, 2, 3, 4, 5, 6, 7});

    FactorGraph fg = new FactorGraph(vars);
    fg.addFactor(factor);

    assertTrue(factor == fg.factorOf(factor.varSet()));

    HashSet set = new HashSet(factor.varSet());
    assertTrue(factor == fg.factorOf(set));
    set.remove(vars[0]);
    assertTrue(null == fg.factorOf(set));
  }
  public void testThreeNodeModel() {
    Random r = new Random(23534709);

    FactorGraph mdl = new FactorGraph();
    Variable root = new Variable(2);
    Variable childL = new Variable(2);
    Variable childR = new Variable(2);

    mdl.addFactor(root, childL, RandomGraphs.generateMixedPotentialValues(r, 1.5));
    mdl.addFactor(root, childR, RandomGraphs.generateMixedPotentialValues(r, 1.5));

    //    assertTrue (mdl.isConnected (root, childL));
    //    assertTrue (mdl.isConnected (root, childR));
    //    assertTrue (mdl.isConnected (childL, childR));
    assertTrue(mdl.isAdjacent(root, childR));
    assertTrue(mdl.isAdjacent(root, childL));
    assertTrue(!mdl.isAdjacent(childL, childR));

    assertTrue(mdl.factorOf(root, childL) != null);
    assertTrue(mdl.factorOf(root, childR) != null);
  }
 public void addFactor(Factor factor) {
   super.addFactor(factor);
   if (factor.varSet().size() == 2) {
     edges.add(factor.varSet());
   }
 }