292 lines
7.6 KiB
C
292 lines
7.6 KiB
C
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
//
|
||
|
// Copyright (C) Microsoft Corporation, 1997 - 1997
|
||
|
//
|
||
|
// File: clique.h
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
//
|
||
|
// clique.h: junction tree and cliquing classes
|
||
|
//
|
||
|
#ifndef _CLIQUE_H_
|
||
|
#define _CLIQUE_H_
|
||
|
|
||
|
#include "gmobj.h"
|
||
|
#include "marginals.h"
|
||
|
#include "margiter.h"
|
||
|
|
||
|
class GEDGEMBN_U;
|
||
|
class GEDGEMBN_CLIQ;
|
||
|
class GEDGEMBN_SEPSET;
|
||
|
class GOBJMBN_CLIQUE;
|
||
|
class GNODENUM_UNDIR;
|
||
|
class GOBJMBN_CLIQSET;
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
// class GEDGEMBN_CLIQUE:
|
||
|
// A clique; that is, an ensemble of nodes identified by linkages via
|
||
|
// GEDGEMBN_CLIQ edges to nodes in the dag and GEDGEMBN_SEPSET
|
||
|
// edges to other cliques in its junction tree.
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
class GOBJMBN_CLIQUE : public GOBJMBN
|
||
|
{
|
||
|
friend class GOBJMBN_CLIQSET;
|
||
|
friend class CLIQSETWORK;
|
||
|
public:
|
||
|
virtual ~ GOBJMBN_CLIQUE ();
|
||
|
|
||
|
// Return true if this is the root clique of its junction tree
|
||
|
bool BRoot () const
|
||
|
{ return _bRoot ; }
|
||
|
|
||
|
protected:
|
||
|
GOBJMBN_CLIQUE ( int iClique, int iInferEngID = 0 );
|
||
|
|
||
|
public:
|
||
|
// Return the immutable object type
|
||
|
virtual INT EType () const
|
||
|
{ return EBNO_CLIQUE; }
|
||
|
|
||
|
bool BCollect() const
|
||
|
{ return _bCollect; }
|
||
|
void SetCollect ( bool bCollect = true )
|
||
|
{ _bCollect = bCollect; }
|
||
|
|
||
|
INT & IInferEngID ()
|
||
|
{ return _iInferEngID; }
|
||
|
INT & IClique ()
|
||
|
{ return _iClique; }
|
||
|
|
||
|
void GetMembers ( VPGNODEMBN & vpgnode );
|
||
|
void InitFromMembers ();
|
||
|
void GetBelief ( GNODEMBN * pgnd, MDVCPD & mdvBel );
|
||
|
const MARGINALS & Marginals () const
|
||
|
{ return _marg; }
|
||
|
MARGINALS & Marginals ()
|
||
|
{ return _marg; }
|
||
|
|
||
|
void CreateMarginals ();
|
||
|
void InitMarginals ();
|
||
|
void LoadMarginals ();
|
||
|
bool VerifyMarginals ();
|
||
|
|
||
|
void Dump();
|
||
|
|
||
|
protected:
|
||
|
// Identity
|
||
|
int _iClique; // Clique index
|
||
|
int _iInferEngID; // Junction tree identifier (unused)
|
||
|
bool _bRoot; // Is this a root clique?
|
||
|
bool _bCollect; // Is "collect/distribute" pass necessary?
|
||
|
|
||
|
MARGINALS _marg; // The clique marginals
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
// class GEDGEMBN_CLIQSET:
|
||
|
// An edge between the clique set object and a root clique
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
class GEDGEMBN_CLIQSET : public GEDGEMBN
|
||
|
{
|
||
|
public:
|
||
|
GEDGEMBN_CLIQSET ( GOBJMBN_CLIQSET * pgobjSource,
|
||
|
GOBJMBN_CLIQUE * pgobjSink )
|
||
|
: GEDGEMBN( pgobjSource, pgobjSink )
|
||
|
{}
|
||
|
|
||
|
GOBJMBN_CLIQSET * PclqsetSource ()
|
||
|
{ return (GOBJMBN_CLIQSET *) GEDGE::PnodeSource(); }
|
||
|
|
||
|
GOBJMBN_CLIQUE * PclqChild ()
|
||
|
{ return (GOBJMBN_CLIQUE *) GEDGE::PnodeSink(); }
|
||
|
|
||
|
virtual INT EType () const
|
||
|
{ return ETCLIQSET ; }
|
||
|
};
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
// class GEDGEMBN_CLIQ:
|
||
|
// An edge between a clique and its member nodes
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
class GEDGEMBN_CLIQ : public GEDGEMBN
|
||
|
{
|
||
|
public:
|
||
|
// What role does this clique play for this node?
|
||
|
enum FCQLROLE
|
||
|
{ // These are bit flags, not integer values
|
||
|
NONE = 0, // Just clique membership
|
||
|
FAMILY = 1, // Link from "family" clique; i.e., smallest
|
||
|
// clique containing node and its family
|
||
|
SELF = 2 // Link from "self" clique;
|
||
|
// i.e., the highest clique in the tree
|
||
|
// which mentions the sink node
|
||
|
};
|
||
|
|
||
|
GEDGEMBN_CLIQ ( GOBJMBN_CLIQUE * pgnSource,
|
||
|
GNODEMBN * pgndSink,
|
||
|
int iFcqlRole );
|
||
|
|
||
|
virtual ~ GEDGEMBN_CLIQ();
|
||
|
|
||
|
virtual INT EType () const
|
||
|
{ return ETCLIQUE ; }
|
||
|
|
||
|
int IFcqlRole () const
|
||
|
{ return _iFcqlRole; }
|
||
|
|
||
|
GOBJMBN_CLIQUE * PclqParent ();
|
||
|
GNODEMBN * PgndSink ();
|
||
|
|
||
|
// Return true if this links node to its parent clique
|
||
|
bool BFamily () const
|
||
|
{ return _iFcqlRole & FAMILY; }
|
||
|
// Return true if this is the highest clique in the jtree in which
|
||
|
// this node appears.
|
||
|
bool BSelf () const
|
||
|
{ return _iFcqlRole & SELF; }
|
||
|
|
||
|
// Return the ordering index of the sink node at the time of cliquing
|
||
|
int IMark () const
|
||
|
{ return _iMark; }
|
||
|
|
||
|
// Return the family reordering table
|
||
|
const VIMD & VimdFamilyReorder () const
|
||
|
{
|
||
|
assert( IFcqlRole() & (FAMILY | SELF) );
|
||
|
return _vimdFamilyReorder;
|
||
|
}
|
||
|
|
||
|
void Build ();
|
||
|
|
||
|
bool BBuilt () const
|
||
|
{ return _bBuilt; }
|
||
|
CLAMP & Clamp ()
|
||
|
{ return _clamp ; }
|
||
|
|
||
|
void LoadCliqueFromNode ();
|
||
|
|
||
|
// Return the iterator for full marginalization of the node ("family")
|
||
|
MARGSUBITER & MiterNodeBelief ()
|
||
|
{
|
||
|
assert( BFamily() );
|
||
|
return _miterBelief;
|
||
|
}
|
||
|
// Return the iterator for loading the node's CPD into the clique ("family")
|
||
|
MARGSUBITER & MiterLoadClique ()
|
||
|
{
|
||
|
assert( BFamily() );
|
||
|
return _miterLoad;
|
||
|
}
|
||
|
// Return the (reordered) marginals for the node ("family")
|
||
|
MARGINALS & MargCpd ()
|
||
|
{
|
||
|
assert( BFamily() );
|
||
|
return _margCpd;
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
int _iFcqlRole; // Role of this clique for the node
|
||
|
int _iMark; // Node number in original clique-time ordering
|
||
|
bool _bBuilt; // Constructed?
|
||
|
|
||
|
// This array is only filled for SELF and FAMILY edges. It is the same
|
||
|
// size as the node's family, and contains, in CLIQUE ordering, the index
|
||
|
// of each member of the nodes family. Note that the sink node has the
|
||
|
// highest index in its family set.
|
||
|
VIMD _vimdFamilyReorder;
|
||
|
|
||
|
// The following variables are only used in "self" or "family" edges
|
||
|
CLAMP _clamp; // Node evidence (used in "self")
|
||
|
MARGINALS _margCpd; // Reordered marginals for node (used in "family")
|
||
|
MARGSUBITER _miterBelief; // Marginals iterator for generating UPD (used in "family")
|
||
|
MARGSUBITER _miterLoad; // Marginals iterator for loading CPD into clique (used in "family")
|
||
|
|
||
|
protected:
|
||
|
static void ReorderFamily ( GNODEMBN * pgnd, VIMD & vimd );
|
||
|
};
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
// class GEDGEMBN_SEPSET:
|
||
|
// An edge in the junction tree between cliques; i.e., a "sepset".
|
||
|
// These are directed edges that point from parent clique to child.
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
class GEDGEMBN_SEPSET : public GEDGEMBN
|
||
|
{
|
||
|
public:
|
||
|
GEDGEMBN_SEPSET ( GOBJMBN_CLIQUE * pgnSource,
|
||
|
GOBJMBN_CLIQUE * pgnSink);
|
||
|
virtual ~ GEDGEMBN_SEPSET();
|
||
|
virtual INT EType () const
|
||
|
{ return ETJTREE; }
|
||
|
|
||
|
void GetMembers ( VPGNODEMBN & vpgnode );
|
||
|
|
||
|
GOBJMBN_CLIQUE * PclqParent();
|
||
|
GOBJMBN_CLIQUE * PclqChild();
|
||
|
|
||
|
const MARGINALS & Marginals () const
|
||
|
{ return *_pmargOld; }
|
||
|
MARGINALS & Marginals ()
|
||
|
{ return *_pmargOld; }
|
||
|
|
||
|
const MARGINALS & MarginalsOld () const
|
||
|
{ return *_pmargOld; }
|
||
|
MARGINALS & MarginalsOld ()
|
||
|
{ return *_pmargOld; }
|
||
|
|
||
|
const MARGINALS & MarginalsMew () const
|
||
|
{ return *_pmargNew; }
|
||
|
MARGINALS & MarginalsNew ()
|
||
|
{ return *_pmargNew; }
|
||
|
|
||
|
void ExchangeMarginals ();
|
||
|
void CreateMarginals ();
|
||
|
void InitMarginals ();
|
||
|
void LoadMarginals ();
|
||
|
bool VerifyMarginals ();
|
||
|
void UpdateParentClique ();
|
||
|
void UpdateChildClique ();
|
||
|
bool BConsistent ();
|
||
|
void BalanceCliquesCollect ();
|
||
|
void BalanceCliquesDistribute ();
|
||
|
|
||
|
void Dump();
|
||
|
|
||
|
protected:
|
||
|
MARGINALS * _pmargOld;
|
||
|
MARGINALS * _pmargNew;
|
||
|
|
||
|
protected:
|
||
|
void UpdateRatios();
|
||
|
void AbsorbClique ( bool bFromParentToChild );
|
||
|
|
||
|
MARGSUBITER _miterParent; // Iterator between sepset and parent
|
||
|
MARGSUBITER _miterChild; // Iterator between sepset and child
|
||
|
};
|
||
|
|
||
|
DEFINEVP(GEDGEMBN_SEPSET);
|
||
|
|
||
|
// Node enumeration subclass for undirected arcs.
|
||
|
class GNODENUM_UNDIR : public GNODENUM<GNODEMBN>
|
||
|
{
|
||
|
public:
|
||
|
GNODENUM_UNDIR ()
|
||
|
: GNODENUM<GNODEMBN>(true,true,true)
|
||
|
{
|
||
|
SetETypeFollow( GEDGEMBN::ETUNDIR );
|
||
|
}
|
||
|
GNODENUM_UNDIR & operator = ( GNODEMBN * pgnd )
|
||
|
{
|
||
|
Set( pgnd );
|
||
|
return *this;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif // _CLIQUE_H_
|