Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
7.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1997
  6. //
  7. // File: clique.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // clique.h: junction tree and cliquing classes
  12. //
  13. #ifndef _CLIQUE_H_
  14. #define _CLIQUE_H_
  15. #include "gmobj.h"
  16. #include "marginals.h"
  17. #include "margiter.h"
  18. class GEDGEMBN_U;
  19. class GEDGEMBN_CLIQ;
  20. class GEDGEMBN_SEPSET;
  21. class GOBJMBN_CLIQUE;
  22. class GNODENUM_UNDIR;
  23. class GOBJMBN_CLIQSET;
  24. ////////////////////////////////////////////////////////////////////
  25. // class GEDGEMBN_CLIQUE:
  26. // A clique; that is, an ensemble of nodes identified by linkages via
  27. // GEDGEMBN_CLIQ edges to nodes in the dag and GEDGEMBN_SEPSET
  28. // edges to other cliques in its junction tree.
  29. ////////////////////////////////////////////////////////////////////
  30. class GOBJMBN_CLIQUE : public GOBJMBN
  31. {
  32. friend class GOBJMBN_CLIQSET;
  33. friend class CLIQSETWORK;
  34. public:
  35. virtual ~ GOBJMBN_CLIQUE ();
  36. // Return true if this is the root clique of its junction tree
  37. bool BRoot () const
  38. { return _bRoot ; }
  39. protected:
  40. GOBJMBN_CLIQUE ( int iClique, int iInferEngID = 0 );
  41. public:
  42. // Return the immutable object type
  43. virtual INT EType () const
  44. { return EBNO_CLIQUE; }
  45. bool BCollect() const
  46. { return _bCollect; }
  47. void SetCollect ( bool bCollect = true )
  48. { _bCollect = bCollect; }
  49. INT & IInferEngID ()
  50. { return _iInferEngID; }
  51. INT & IClique ()
  52. { return _iClique; }
  53. void GetMembers ( VPGNODEMBN & vpgnode );
  54. void InitFromMembers ();
  55. void GetBelief ( GNODEMBN * pgnd, MDVCPD & mdvBel );
  56. const MARGINALS & Marginals () const
  57. { return _marg; }
  58. MARGINALS & Marginals ()
  59. { return _marg; }
  60. void CreateMarginals ();
  61. void InitMarginals ();
  62. void LoadMarginals ();
  63. bool VerifyMarginals ();
  64. void Dump();
  65. protected:
  66. // Identity
  67. int _iClique; // Clique index
  68. int _iInferEngID; // Junction tree identifier (unused)
  69. bool _bRoot; // Is this a root clique?
  70. bool _bCollect; // Is "collect/distribute" pass necessary?
  71. MARGINALS _marg; // The clique marginals
  72. };
  73. ////////////////////////////////////////////////////////////////////
  74. // class GEDGEMBN_CLIQSET:
  75. // An edge between the clique set object and a root clique
  76. ////////////////////////////////////////////////////////////////////
  77. class GEDGEMBN_CLIQSET : public GEDGEMBN
  78. {
  79. public:
  80. GEDGEMBN_CLIQSET ( GOBJMBN_CLIQSET * pgobjSource,
  81. GOBJMBN_CLIQUE * pgobjSink )
  82. : GEDGEMBN( pgobjSource, pgobjSink )
  83. {}
  84. GOBJMBN_CLIQSET * PclqsetSource ()
  85. { return (GOBJMBN_CLIQSET *) GEDGE::PnodeSource(); }
  86. GOBJMBN_CLIQUE * PclqChild ()
  87. { return (GOBJMBN_CLIQUE *) GEDGE::PnodeSink(); }
  88. virtual INT EType () const
  89. { return ETCLIQSET ; }
  90. };
  91. ////////////////////////////////////////////////////////////////////
  92. // class GEDGEMBN_CLIQ:
  93. // An edge between a clique and its member nodes
  94. ////////////////////////////////////////////////////////////////////
  95. class GEDGEMBN_CLIQ : public GEDGEMBN
  96. {
  97. public:
  98. // What role does this clique play for this node?
  99. enum FCQLROLE
  100. { // These are bit flags, not integer values
  101. NONE = 0, // Just clique membership
  102. FAMILY = 1, // Link from "family" clique; i.e., smallest
  103. // clique containing node and its family
  104. SELF = 2 // Link from "self" clique;
  105. // i.e., the highest clique in the tree
  106. // which mentions the sink node
  107. };
  108. GEDGEMBN_CLIQ ( GOBJMBN_CLIQUE * pgnSource,
  109. GNODEMBN * pgndSink,
  110. int iFcqlRole );
  111. virtual ~ GEDGEMBN_CLIQ();
  112. virtual INT EType () const
  113. { return ETCLIQUE ; }
  114. int IFcqlRole () const
  115. { return _iFcqlRole; }
  116. GOBJMBN_CLIQUE * PclqParent ();
  117. GNODEMBN * PgndSink ();
  118. // Return true if this links node to its parent clique
  119. bool BFamily () const
  120. { return _iFcqlRole & FAMILY; }
  121. // Return true if this is the highest clique in the jtree in which
  122. // this node appears.
  123. bool BSelf () const
  124. { return _iFcqlRole & SELF; }
  125. // Return the ordering index of the sink node at the time of cliquing
  126. int IMark () const
  127. { return _iMark; }
  128. // Return the family reordering table
  129. const VIMD & VimdFamilyReorder () const
  130. {
  131. assert( IFcqlRole() & (FAMILY | SELF) );
  132. return _vimdFamilyReorder;
  133. }
  134. void Build ();
  135. bool BBuilt () const
  136. { return _bBuilt; }
  137. CLAMP & Clamp ()
  138. { return _clamp ; }
  139. void LoadCliqueFromNode ();
  140. // Return the iterator for full marginalization of the node ("family")
  141. MARGSUBITER & MiterNodeBelief ()
  142. {
  143. assert( BFamily() );
  144. return _miterBelief;
  145. }
  146. // Return the iterator for loading the node's CPD into the clique ("family")
  147. MARGSUBITER & MiterLoadClique ()
  148. {
  149. assert( BFamily() );
  150. return _miterLoad;
  151. }
  152. // Return the (reordered) marginals for the node ("family")
  153. MARGINALS & MargCpd ()
  154. {
  155. assert( BFamily() );
  156. return _margCpd;
  157. }
  158. protected:
  159. int _iFcqlRole; // Role of this clique for the node
  160. int _iMark; // Node number in original clique-time ordering
  161. bool _bBuilt; // Constructed?
  162. // This array is only filled for SELF and FAMILY edges. It is the same
  163. // size as the node's family, and contains, in CLIQUE ordering, the index
  164. // of each member of the nodes family. Note that the sink node has the
  165. // highest index in its family set.
  166. VIMD _vimdFamilyReorder;
  167. // The following variables are only used in "self" or "family" edges
  168. CLAMP _clamp; // Node evidence (used in "self")
  169. MARGINALS _margCpd; // Reordered marginals for node (used in "family")
  170. MARGSUBITER _miterBelief; // Marginals iterator for generating UPD (used in "family")
  171. MARGSUBITER _miterLoad; // Marginals iterator for loading CPD into clique (used in "family")
  172. protected:
  173. static void ReorderFamily ( GNODEMBN * pgnd, VIMD & vimd );
  174. };
  175. ////////////////////////////////////////////////////////////////////
  176. // class GEDGEMBN_SEPSET:
  177. // An edge in the junction tree between cliques; i.e., a "sepset".
  178. // These are directed edges that point from parent clique to child.
  179. ////////////////////////////////////////////////////////////////////
  180. class GEDGEMBN_SEPSET : public GEDGEMBN
  181. {
  182. public:
  183. GEDGEMBN_SEPSET ( GOBJMBN_CLIQUE * pgnSource,
  184. GOBJMBN_CLIQUE * pgnSink);
  185. virtual ~ GEDGEMBN_SEPSET();
  186. virtual INT EType () const
  187. { return ETJTREE; }
  188. void GetMembers ( VPGNODEMBN & vpgnode );
  189. GOBJMBN_CLIQUE * PclqParent();
  190. GOBJMBN_CLIQUE * PclqChild();
  191. const MARGINALS & Marginals () const
  192. { return *_pmargOld; }
  193. MARGINALS & Marginals ()
  194. { return *_pmargOld; }
  195. const MARGINALS & MarginalsOld () const
  196. { return *_pmargOld; }
  197. MARGINALS & MarginalsOld ()
  198. { return *_pmargOld; }
  199. const MARGINALS & MarginalsMew () const
  200. { return *_pmargNew; }
  201. MARGINALS & MarginalsNew ()
  202. { return *_pmargNew; }
  203. void ExchangeMarginals ();
  204. void CreateMarginals ();
  205. void InitMarginals ();
  206. void LoadMarginals ();
  207. bool VerifyMarginals ();
  208. void UpdateParentClique ();
  209. void UpdateChildClique ();
  210. bool BConsistent ();
  211. void BalanceCliquesCollect ();
  212. void BalanceCliquesDistribute ();
  213. void Dump();
  214. protected:
  215. MARGINALS * _pmargOld;
  216. MARGINALS * _pmargNew;
  217. protected:
  218. void UpdateRatios();
  219. void AbsorbClique ( bool bFromParentToChild );
  220. MARGSUBITER _miterParent; // Iterator between sepset and parent
  221. MARGSUBITER _miterChild; // Iterator between sepset and child
  222. };
  223. DEFINEVP(GEDGEMBN_SEPSET);
  224. // Node enumeration subclass for undirected arcs.
  225. class GNODENUM_UNDIR : public GNODENUM<GNODEMBN>
  226. {
  227. public:
  228. GNODENUM_UNDIR ()
  229. : GNODENUM<GNODEMBN>(true,true,true)
  230. {
  231. SetETypeFollow( GEDGEMBN::ETUNDIR );
  232. }
  233. GNODENUM_UNDIR & operator = ( GNODEMBN * pgnd )
  234. {
  235. Set( pgnd );
  236. return *this;
  237. }
  238. };
  239. #endif // _CLIQUE_H_