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.
|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1998
//
// File: utility.cpp
//
//--------------------------------------------------------------------------
//
// utility.cpp: utility computation
//
#include <basetsd.h>
#include <math.h>
#include "utility.h"
#include "infer.h"
MBNET_ENTROPIC_UTILITY :: MBNET_ENTROPIC_UTILITY ( GOBJMBN_INFER_ENGINE & inferEng ) : MBNET_NODE_RANKER( inferEng.Model() ), _inferEng( inferEng ), _propMgr( inferEng.Model() ), _cHypo(0), _cInfo(0) { _iLblHypo = _propMgr.ILblToUser( ESTDLBL_hypo ); _iLblInfo = _propMgr.ILblToUser( ESTDLBL_info ); _iLblProblem = _propMgr.ILblToUser( ESTDLBL_problem );
BuildWorkItems(); }
//
// Collect all informational, problem defining and hypothesis nodes
// into a structure with additional working data.
//
void MBNET_ENTROPIC_UTILITY :: BuildWorkItems () { ZSREF zsrPropTypeLabel = _propMgr.ZsrPropType( ESTDP_label ); MODEL::MODELENUM mdlenum( Model() );
_dquwrk.clear(); _cHypo = 0; _cInfo = 0;
UTILWORK uwDummy; GELEMLNK * pgelm;
// Collect all the nodes into a pointer array. Three node labels
// are collected: info and probdef nodes (considered as info)
// and hypo nodes (considered as hypo).
while ( pgelm = mdlenum.PlnkelNext() ) { if ( pgelm->EType() != GOBJMBN::EBNO_NODE ) continue;
// We only support discrete nodes for now.
DynCastThrow( pgelm, uwDummy._pgndd );
// See if this is an expansion (created) node
if ( uwDummy._pgndd->BFlag( EIBF_Expansion ) ) continue; // not a user-identifiable artifact; skip it
// See if it has a label
PROPMBN * propLbl = uwDummy._pgndd->LtProp().PFind( zsrPropTypeLabel ); if ( ! propLbl ) continue; // no label; skip it
uwDummy._iLbl = propLbl->Real(); if ( uwDummy._iLbl == _iLblHypo ) _cHypo++; else if ( uwDummy._iLbl == _iLblInfo || uwDummy._iLbl == _iLblProblem ) _cInfo++; else continue; // not a label of interest
// Initialize the other member variables
uwDummy._rUtil = 0.0; uwDummy._iClamp = -1; // Put the item on the work queue
_dquwrk.push_back( uwDummy ); } }
REAL MBNET_ENTROPIC_UTILITY :: RComputeHypoGivenInfo ( UTILWORK & uwHypo, UTILWORK & uwInfo ) { assert( uwHypo._iLbl == _iLblHypo ); assert( uwInfo._iLbl != _iLblHypo );
// Clamped nodes are irrelevant
if ( uwHypo._iClamp >= 0 || uwInfo._iClamp >= 0 ) return 0.0;
REAL rUtilOfInfoForHypo = 0.0; int cState = uwInfo._pgndd->CState(); int cStateHypo = uwHypo._pgndd->CState(); MDVCPD mdvhi; REAL rp_h0 = uwHypo._dd[0]; // Probability of hypo node being normal
for ( int istInfo = 0; istInfo < cState; istInfo++ ) { // Get belief of hypo node given info state
_inferEng.EnterEvidence( uwInfo._pgndd, CLAMP( true, istInfo, true ) ); _inferEng.GetBelief( uwHypo._pgndd, mdvhi ); REAL rp_h0xj = mdvhi[0]; // p(h0|xj)
REAL rLogSum = 0.0; for ( int istHypo = 1; istHypo < cStateHypo; istHypo++ ) { REAL rp_hi = uwHypo._dd[istHypo]; REAL rp_hixj = mdvhi[istHypo]; rLogSum += fabs( log(rp_hixj) - log(rp_h0xj) - log(rp_hi) + log(rp_h0) ); } rUtilOfInfoForHypo += rLogSum * uwInfo._dd[istInfo]; }
// Clear evidence against info node
_inferEng.EnterEvidence( uwInfo._pgndd, CLAMP() );
return rUtilOfInfoForHypo; }
DEFINEVP(UTILWORK);
void MBNET_ENTROPIC_UTILITY :: ComputeWorkItems() { CLAMP clamp; VPUTILWORK vpuw; // Remember pointers to hypo items
// Get unconditional beliefs of all relevant (unclamped) nodes
for ( DQUTILWORK::iterator itdq = _dquwrk.begin(); itdq != _dquwrk.end(); itdq++ ) { UTILWORK & ut = *itdq; ut._rUtil = 0.0; ut._iClamp = -1;
// Remember the indicies of the hypo nodes
if ( ut._iLbl == _iLblHypo ) vpuw.push_back( & (*itdq) );
// Get the current evidence for the node
_inferEng.GetEvidence( ut._pgndd, clamp ); // If node is unclamped,
if ( ! clamp.BActive() ) { // get unconditional probs, else
_inferEng.GetBelief( ut._pgndd, ut._dd ); } else { // remember clamped state (serves as marker)
ut._iClamp = clamp.Ist(); } }
for ( itdq = _dquwrk.begin(); itdq != _dquwrk.end(); itdq++ ) { UTILWORK & utInfo = *itdq; if ( utInfo._iLbl == _iLblHypo ) continue; utInfo._rUtil = 0.0; for ( int ih = 0; ih < vpuw.size(); ih++ ) { utInfo._rUtil += RComputeHypoGivenInfo( *vpuw[ih], utInfo ); } } }
void MBNET_ENTROPIC_UTILITY :: operator () () { // Clear any old results
Clear();
if ( _cHypo == 0 || _cInfo == 0 ) return; // Nothing to do
// Compute all utilities
ComputeWorkItems();
// Sort the work queue by utility
sort( _dquwrk.begin(), _dquwrk.end() );
// Pour the information into the output work areas
_vzsrNodes.resize(_cInfo); _vlrValues.resize(_cInfo); int iInfo = 0; for ( DQUTILWORK::reverse_iterator ritdq = _dquwrk.rbegin(); ritdq != _dquwrk.rend(); ritdq++ ) { UTILWORK & ut = *ritdq; if ( ut._iLbl == _iLblHypo ) continue; _vzsrNodes[iInfo] = ut._pgndd->ZsrefName(); _vlrValues[iInfo++] = ut._rUtil; } assert( iInfo == _cInfo ); }
|