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.

205 lines
5.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1997
  6. //
  7. // File: margiter.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // margiter.h: compiled marginals iterators
  12. //
  13. #ifndef _MARGITER_H_
  14. #define _MARGITER_H_
  15. /*
  16. This class is intended to be used in sepsets. There will be two of them,
  17. one representing the parent clique and the sepset, the other representing
  18. the child clique and the sepset. The sepset is the "subset" in both
  19. cases.
  20. A MARGSUBITER "compiles" the subscripts from the iteration of the subset
  21. marginal into an array of integers. Iteration using this array is much
  22. faster than performing full array stride multiplication and summation.
  23. The cost is the additional memory to contain the offsets in each sepset,
  24. which is roughly:
  25. sizeof(int) * ( (# of entries in child clique)
  26. + (# of entries in parent clique))
  27. */
  28. #include <list>
  29. // Class VMARGSUB: a reference counted array of subscripts
  30. class VMARGSUB : public VINT, public REFCNT
  31. {
  32. public:
  33. VMARGSUB ( MARGINALS::Iterator & itMarg );
  34. ~ VMARGSUB ();
  35. void NoRef ();
  36. int ISearchPass () const
  37. { return _iSearchPass; }
  38. int & ISearchPass ()
  39. { return _iSearchPass; }
  40. LEAK_VAR_ACCESSOR
  41. protected:
  42. int _iSearchPass;
  43. LEAK_VAR_DECL
  44. HIDE_UNSAFE(VMARGSUB);
  45. };
  46. // Class MARGSUBREF: a reference (via pointer) to a VMARGSUB
  47. // and an applicable length. This class exists so that
  48. // when a new, longer, superset subscript array (VMARGSUB)
  49. // is added to the ensemble, all older references to smaller
  50. // VMARGSUBs can be converted to reference the new, larger
  51. // VMARGSUB and the older one discarded.
  52. //
  53. class MARGSUBREF : public REFCNT
  54. {
  55. public:
  56. MARGSUBREF ( VMARGSUB * pvmsub = NULL, int cSize = -1 );
  57. ~ MARGSUBREF ();
  58. MARGSUBREF ( const MARGSUBREF & msubr );
  59. MARGSUBREF & operator = ( const MARGSUBREF & msubr );
  60. // Set the array
  61. void SetVmsub ( VMARGSUB * pvmsub, int cSize = -1 );
  62. // Return iteration information
  63. VINT & VintSub ()
  64. {
  65. assert( _pvmsub );
  66. return *_pvmsub;
  67. }
  68. VMARGSUB & Vmsub ()
  69. {
  70. assert( _pvmsub );
  71. return *_pvmsub;
  72. }
  73. VMARGSUB * Pvmsub ()
  74. {
  75. assert( _pvmsub );
  76. return _pvmsub;
  77. }
  78. int CSize() const
  79. { return _cSize ; }
  80. DECLARE_ORDERING_OPERATORS(MARGSUBREF);
  81. LEAK_VAR_ACCESSOR
  82. protected:
  83. VMARGSUB * _pvmsub; // Pointer to array of subscripts
  84. int _cSize; // Applicable length
  85. LEAK_VAR_DECL
  86. };
  87. typedef list<MARGSUBREF> LTMSUBR;
  88. // A wrapper for a linked list of MARGSUBREFs.
  89. // There is one global instance of this.
  90. class LTMARGSUBREF
  91. {
  92. public:
  93. LTMARGSUBREF ();
  94. MARGSUBREF * PmsubrAdd ( MARGINALS::Iterator & itMarg );
  95. void Release ( MARGSUBREF * pmsubr );
  96. void Dump ();
  97. protected:
  98. LTMSUBR _ltmsubr;
  99. int _iSearchPass;
  100. int _cArrays;
  101. size_t _cArrayTotalSize;
  102. int _cSubRefs;
  103. };
  104. class MARGSUBITER // Marginals Subset Iterator
  105. {
  106. public:
  107. MARGSUBITER ();
  108. ~ MARGSUBITER () ;
  109. bool BBuilt () const
  110. { return _pmsubr != NULL; }
  111. // Build the iterator for two cliques
  112. void Build ( MARGINALS & margSelf, MARGINALS & margSubset );
  113. // Build the iterator for a clique and a node
  114. void Build ( MARGINALS & margSelf, GNODEMBND * pgndd );
  115. // Marginalize the superset to the subset (subset changed)
  116. inline void MarginalizeInto ( MDVCPD & mdvSubset );
  117. // Marginalize the superset to a node's UPD
  118. inline void MarginalizeBelief ( MDVCPD & mdvBel, GNODEMBND * pgndd );
  119. // Multiply the superset by the subset (superset changed)
  120. inline void MultiplyBy ( MARGINALS & margSubset );
  121. // Verify subscripts
  122. void Test ( MARGINALS & margSubset );
  123. static void Dump ()
  124. { _ltmargsubr.Dump(); }
  125. protected:
  126. MARGINALS * _pmargSelf;
  127. MARGSUBREF * _pmsubr;
  128. static LTMARGSUBREF _ltmargsubr;
  129. };
  130. inline
  131. void MARGSUBITER :: MarginalizeInto ( MDVCPD & mdvSubset )
  132. {
  133. assert( _pmsubr && _pmargSelf );
  134. mdvSubset.Clear();
  135. VINT & visub = _pmsubr->VintSub();
  136. int cEnd = _pmsubr->CSize();
  137. const int * pisub = & visub[0];
  138. // Note: this funny reference is due to BoundsChecker complaining that I'm accessing memory
  139. // beyond the end of the array. I'm not, but it doesn't complain about this
  140. const int * pisubMax = & visub[0] + cEnd;
  141. double * pvlSubset = & mdvSubset.first[0];
  142. double * pvlSelf = & _pmargSelf->first[0];
  143. while ( pisub != pisubMax )
  144. {
  145. pvlSubset[*pisub++] += *pvlSelf++;
  146. }
  147. }
  148. inline
  149. void MARGSUBITER :: MultiplyBy ( MARGINALS & margSubset )
  150. {
  151. assert( _pmsubr && _pmargSelf );
  152. VINT & visub = _pmsubr->VintSub();
  153. int cEnd = _pmsubr->CSize();
  154. const int * pisub = & visub[0];
  155. // Note: See note above about funny subscripting
  156. const int * pisubMax = & visub[0] + cEnd;
  157. double * pvlSubset = & margSubset.first[0];
  158. double * pvlSelf = & _pmargSelf->first[0];
  159. while ( pisub != pisubMax )
  160. {
  161. *pvlSelf++ *= pvlSubset[*pisub++];
  162. }
  163. }
  164. // Marginalize the superset to a node's UPD
  165. inline
  166. void MARGSUBITER :: MarginalizeBelief ( MDVCPD & mdvBel, GNODEMBND * pgndd )
  167. {
  168. MARGINALS::ResizeDistribution( pgndd, mdvBel );
  169. MarginalizeInto( mdvBel );
  170. mdvBel.Normalize();
  171. }
  172. #endif // _MARGITER_H_