New, non-fancy constructors
							parent
							
								
									fd7640b1b7
								
							
						
					
					
						commit
						4e5530b6d5
					
				| 
						 | 
				
			
			@ -57,6 +57,29 @@ public:
 | 
			
		|||
  /** Construct from signature */
 | 
			
		||||
  DiscreteConditional(const Signature& signature);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * Construct from key, parents, and a Table specifying the CPT.
 | 
			
		||||
  *
 | 
			
		||||
  * The first string is parsed to add a key and parents.
 | 
			
		||||
  * 
 | 
			
		||||
  * Example: DiscreteConditional P(D, {B,E}, table);
 | 
			
		||||
  */
 | 
			
		||||
  DiscreteConditional(const DiscreteKey& key, const DiscreteKeys& parents,
 | 
			
		||||
                      const Signature::Table& table)
 | 
			
		||||
      : DiscreteConditional(Signature(key, parents, table)) {}
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * Construct from key, parents, and a string specifying the CPT.
 | 
			
		||||
  *
 | 
			
		||||
  * The first string is parsed to add a key and parents. The second string
 | 
			
		||||
  * parses into a table.
 | 
			
		||||
  * 
 | 
			
		||||
  * Example: DiscreteConditional P(D, {B,E}, "9/1 2/8 3/7 1/9");
 | 
			
		||||
  */
 | 
			
		||||
  DiscreteConditional(const DiscreteKey& key, const DiscreteKeys& parents,
 | 
			
		||||
                      const std::string& spec)
 | 
			
		||||
      : DiscreteConditional(Signature(key, parents, spec)) {}
 | 
			
		||||
 | 
			
		||||
  /** construct P(X|Y)=P(X,Y)/P(Y) from P(X,Y) and P(Y) */
 | 
			
		||||
  DiscreteConditional(const DecisionTreeFactor& joint,
 | 
			
		||||
      const DecisionTreeFactor& marginal);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,6 +79,18 @@ namespace gtsam {
 | 
			
		|||
    return os;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Signature::Signature(const DiscreteKey& key, const DiscreteKeys& parents,
 | 
			
		||||
                       const Table& table)
 | 
			
		||||
      : key_(key), parents_(parents) {
 | 
			
		||||
    operator=(table);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Signature::Signature(const DiscreteKey& key, const DiscreteKeys& parents,
 | 
			
		||||
                       const std::string& spec)
 | 
			
		||||
      : key_(key), parents_(parents) {
 | 
			
		||||
    operator=(spec);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Signature::Signature(const DiscreteKey& key) :
 | 
			
		||||
    key_(key) {
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,9 +45,9 @@ namespace gtsam {
 | 
			
		|||
   *   T|A = "99/1  95/5"
 | 
			
		||||
   *   L|S = "99/1  90/10"
 | 
			
		||||
   *   B|S = "70/30  40/60"
 | 
			
		||||
   *   E|T,L = "F F F 1"
 | 
			
		||||
   *   (E|T,L) = "F F F 1"
 | 
			
		||||
   *   X|E = "95/5 2/98"
 | 
			
		||||
   *   D|E,B = "9/1 2/8 3/7 1/9"
 | 
			
		||||
   *   (D|E,B) = "9/1 2/8 3/7 1/9"
 | 
			
		||||
   */
 | 
			
		||||
  class GTSAM_EXPORT Signature {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,45 +72,66 @@ namespace gtsam {
 | 
			
		|||
    boost::optional<Table> table_;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
   /**
 | 
			
		||||
    * Construct from key, parents, and a Table specifying the CPT.
 | 
			
		||||
    *
 | 
			
		||||
    * The first string is parsed to add a key and parents.
 | 
			
		||||
    * 
 | 
			
		||||
    * Example: Signature sig(D, {B,E}, table);
 | 
			
		||||
    */
 | 
			
		||||
   Signature(const DiscreteKey& key, const DiscreteKeys& parents,
 | 
			
		||||
             const Table& table);
 | 
			
		||||
 | 
			
		||||
    /** Constructor from DiscreteKey */
 | 
			
		||||
    Signature(const DiscreteKey& key);
 | 
			
		||||
   /**
 | 
			
		||||
    * Construct from key, parents, and a string specifying the CPT.
 | 
			
		||||
    *
 | 
			
		||||
    * The first string is parsed to add a key and parents. The second string
 | 
			
		||||
    * parses into a table.
 | 
			
		||||
    * 
 | 
			
		||||
    * Example: Signature sig(D, {B,E}, "9/1 2/8 3/7 1/9");
 | 
			
		||||
    */
 | 
			
		||||
   Signature(const DiscreteKey& key, const DiscreteKeys& parents,
 | 
			
		||||
             const std::string& spec);
 | 
			
		||||
 | 
			
		||||
    /** the variable key */
 | 
			
		||||
    const DiscreteKey& key() const {
 | 
			
		||||
      return key_;
 | 
			
		||||
    }
 | 
			
		||||
   /**
 | 
			
		||||
    * Construct from a single DiscreteKey.
 | 
			
		||||
    *
 | 
			
		||||
    * The resulting signature has no parents or CPT table. Typical use then
 | 
			
		||||
    * either adds parents with | and , operators below, or assigns a table with
 | 
			
		||||
    * operator=().
 | 
			
		||||
    */
 | 
			
		||||
   Signature(const DiscreteKey& key);
 | 
			
		||||
 | 
			
		||||
    /** the parent keys */
 | 
			
		||||
    const DiscreteKeys& parents() const {
 | 
			
		||||
      return parents_;
 | 
			
		||||
    }
 | 
			
		||||
   /** the variable key */
 | 
			
		||||
   const DiscreteKey& key() const { return key_; }
 | 
			
		||||
 | 
			
		||||
    /** All keys, with variable key first */
 | 
			
		||||
    DiscreteKeys discreteKeys() const;
 | 
			
		||||
   /** the parent keys */
 | 
			
		||||
   const DiscreteKeys& parents() const { return parents_; }
 | 
			
		||||
 | 
			
		||||
    /** All key indices, with variable key first */
 | 
			
		||||
    KeyVector indices() const;
 | 
			
		||||
   /** All keys, with variable key first */
 | 
			
		||||
   DiscreteKeys discreteKeys() const;
 | 
			
		||||
 | 
			
		||||
    // the CPT as parsed, if successful
 | 
			
		||||
    const boost::optional<Table>& table() const {
 | 
			
		||||
      return table_;
 | 
			
		||||
    }
 | 
			
		||||
   /** All key indices, with variable key first */
 | 
			
		||||
   KeyVector indices() const;
 | 
			
		||||
 | 
			
		||||
    // the CPT as a vector of doubles, with key's values most rapidly changing
 | 
			
		||||
    std::vector<double> cpt() const;
 | 
			
		||||
   // the CPT as parsed, if successful
 | 
			
		||||
   const boost::optional<Table>& table() const { return table_; }
 | 
			
		||||
 | 
			
		||||
    /** Add a parent */
 | 
			
		||||
    Signature& operator,(const DiscreteKey& parent);
 | 
			
		||||
   // the CPT as a vector of doubles, with key's values most rapidly changing
 | 
			
		||||
   std::vector<double> cpt() const;
 | 
			
		||||
 | 
			
		||||
    /** Add the CPT spec */
 | 
			
		||||
    Signature& operator=(const std::string& spec);
 | 
			
		||||
   /** Add a parent */
 | 
			
		||||
   Signature& operator,(const DiscreteKey& parent);
 | 
			
		||||
 | 
			
		||||
    /** Add the CPT spec directly as a table */
 | 
			
		||||
    Signature& operator=(const Table& table);
 | 
			
		||||
   /** Add the CPT spec */
 | 
			
		||||
   Signature& operator=(const std::string& spec);
 | 
			
		||||
 | 
			
		||||
    /** provide streaming */
 | 
			
		||||
    GTSAM_EXPORT friend std::ostream& operator <<(std::ostream &os, const Signature &s);
 | 
			
		||||
   /** Add the CPT spec directly as a table */
 | 
			
		||||
   Signature& operator=(const Table& table);
 | 
			
		||||
 | 
			
		||||
   /** provide streaming */
 | 
			
		||||
   GTSAM_EXPORT friend std::ostream& operator<<(std::ostream& os,
 | 
			
		||||
                                                const Signature& s);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,11 +61,10 @@ TEST(DiscreteConditional, constructors_alt_interface) {
 | 
			
		|||
  r2 += 2.0, 3.0;
 | 
			
		||||
  r3 += 1.0, 4.0;
 | 
			
		||||
  table += r1, r2, r3;
 | 
			
		||||
  auto actual1 = boost::make_shared<DiscreteConditional>(X | Y = table);
 | 
			
		||||
  EXPECT(actual1);
 | 
			
		||||
  DiscreteConditional actual1(X, {Y}, table);
 | 
			
		||||
  DecisionTreeFactor f1(X & Y, "0.5 0.4 0.2 0.5 0.6 0.8");
 | 
			
		||||
  DiscreteConditional expected1(1, f1);
 | 
			
		||||
  EXPECT(assert_equal(expected1, *actual1, 1e-9));
 | 
			
		||||
  EXPECT(assert_equal(expected1, actual1, 1e-9));
 | 
			
		||||
 | 
			
		||||
  DecisionTreeFactor f2(
 | 
			
		||||
      X & Y & Z, "0.2 0.5 0.3 0.6 0.4 0.7 0.25 0.55 0.35 0.65 0.45 0.75");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,22 +32,27 @@ DiscreteKey X(0, 2), Y(1, 3), Z(2, 2);
 | 
			
		|||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
TEST(testSignature, simple_conditional) {
 | 
			
		||||
  Signature sig(X | Y = "1/1 2/3 1/4");
 | 
			
		||||
  Signature sig(X, {Y}, "1/1 2/3 1/4");
 | 
			
		||||
  CHECK(sig.table());
 | 
			
		||||
  Signature::Table table = *sig.table();
 | 
			
		||||
  vector<double> row[3]{{0.5, 0.5}, {0.4, 0.6}, {0.2, 0.8}};
 | 
			
		||||
  LONGS_EQUAL(3, table.size());
 | 
			
		||||
  CHECK(row[0] == table[0]);
 | 
			
		||||
  CHECK(row[1] == table[1]);
 | 
			
		||||
  CHECK(row[2] == table[2]);
 | 
			
		||||
  DiscreteKey actKey = sig.key();
 | 
			
		||||
  LONGS_EQUAL(X.first, actKey.first);
 | 
			
		||||
 | 
			
		||||
  DiscreteKeys actKeys = sig.discreteKeys();
 | 
			
		||||
  LONGS_EQUAL(2, actKeys.size());
 | 
			
		||||
  LONGS_EQUAL(X.first, actKeys.front().first);
 | 
			
		||||
  LONGS_EQUAL(Y.first, actKeys.back().first);
 | 
			
		||||
  CHECK(sig.key() == X);
 | 
			
		||||
 | 
			
		||||
  vector<double> actCpt = sig.cpt();
 | 
			
		||||
  EXPECT_LONGS_EQUAL(6, actCpt.size());
 | 
			
		||||
  DiscreteKeys keys = sig.discreteKeys();
 | 
			
		||||
  LONGS_EQUAL(2, keys.size());
 | 
			
		||||
  CHECK(keys[0] == X);
 | 
			
		||||
  CHECK(keys[1] == Y);
 | 
			
		||||
 | 
			
		||||
  DiscreteKeys parents = sig.parents();
 | 
			
		||||
  LONGS_EQUAL(1, parents.size());
 | 
			
		||||
  CHECK(parents[0] == Y);
 | 
			
		||||
 | 
			
		||||
  EXPECT_LONGS_EQUAL(6, sig.cpt().size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
| 
						 | 
				
			
			@ -60,16 +65,47 @@ TEST(testSignature, simple_conditional_nonparser) {
 | 
			
		|||
  table += row1, row2, row3;
 | 
			
		||||
 | 
			
		||||
  Signature sig(X | Y = table);
 | 
			
		||||
  DiscreteKey actKey = sig.key();
 | 
			
		||||
  EXPECT_LONGS_EQUAL(X.first, actKey.first);
 | 
			
		||||
  CHECK(sig.key() == X);
 | 
			
		||||
 | 
			
		||||
  DiscreteKeys actKeys = sig.discreteKeys();
 | 
			
		||||
  LONGS_EQUAL(2, actKeys.size());
 | 
			
		||||
  LONGS_EQUAL(X.first, actKeys.front().first);
 | 
			
		||||
  LONGS_EQUAL(Y.first, actKeys.back().first);
 | 
			
		||||
  DiscreteKeys keys = sig.discreteKeys();
 | 
			
		||||
  LONGS_EQUAL(2, keys.size());
 | 
			
		||||
  CHECK(keys[0] == X);
 | 
			
		||||
  CHECK(keys[1] == Y);
 | 
			
		||||
 | 
			
		||||
  vector<double> actCpt = sig.cpt();
 | 
			
		||||
  EXPECT_LONGS_EQUAL(6, actCpt.size());
 | 
			
		||||
  DiscreteKeys parents = sig.parents();
 | 
			
		||||
  LONGS_EQUAL(1, parents.size());
 | 
			
		||||
  CHECK(parents[0] == Y);
 | 
			
		||||
 | 
			
		||||
  EXPECT_LONGS_EQUAL(6, sig.cpt().size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
DiscreteKey A(0, 2), S(1, 2), T(2, 2), L(3, 2), B(4, 2), E(5, 2), D(7, 2);
 | 
			
		||||
 | 
			
		||||
// Make sure we can create all signatures for Asia network with constructor.
 | 
			
		||||
TEST(testSignature, all_examples) {
 | 
			
		||||
  DiscreteKey X(6, 2);
 | 
			
		||||
  Signature a(A, {}, "99/1");
 | 
			
		||||
  Signature s(S, {}, "50/50");
 | 
			
		||||
  Signature t(T, {A}, "99/1  95/5");
 | 
			
		||||
  Signature l(L, {S}, "99/1  90/10");
 | 
			
		||||
  Signature b(B, {S}, "70/30  40/60");
 | 
			
		||||
  Signature e(E, {T, L}, "F F F 1");
 | 
			
		||||
  Signature x(X, {E}, "95/5 2/98");
 | 
			
		||||
  Signature d(D, {E, B}, "9/1 2/8 3/7 1/9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make sure we can create all signatures for Asia network with operator magic.
 | 
			
		||||
TEST(testSignature, all_examples_magic) {
 | 
			
		||||
  DiscreteKey X(6, 2);
 | 
			
		||||
  Signature a(A % "99/1");
 | 
			
		||||
  Signature s(S % "50/50");
 | 
			
		||||
  Signature t(T | A = "99/1  95/5");
 | 
			
		||||
  Signature l(L | S = "99/1  90/10");
 | 
			
		||||
  Signature b(B | S = "70/30  40/60");
 | 
			
		||||
  Signature e((E | T, L) = "F F F 1");
 | 
			
		||||
  Signature x(X | E = "95/5 2/98");
 | 
			
		||||
  Signature d((D | E, B) = "9/1 2/8 3/7 1/9");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************* */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue