windows-nt/Source/XPSP1/NT/enduser/troubleshoot/bn/mddist.h
2020-09-26 16:20:57 +08:00

174 lines
3.7 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1998
//
// File: mddist.h
//
//--------------------------------------------------------------------------
//
// mddist.h: model distributions
//
#ifndef _MDDIST_H_
#define _MDDIST_H_
#include <map>
#include "mdvect.h"
#include "leakchk.h"
////////////////////////////////////////////////////////////////////
// Probability table declarations
////////////////////////////////////////////////////////////////////
// Dense multidimensional array. Note that a null dimension set
// produces a one entry array.
typedef TMDVDENSE<REAL> MDVDENSE;
class MDVCPD : public MDVDENSE
{
public:
MDVCPD ( const VIMD & vimd )
: MDVDENSE ( vimd )
{}
MDVCPD () {}
~ MDVCPD () {}
void Init ( const VIMD & vimd, size_t start = 0 )
{
if ( vimd.size() > 0 )
{
MDVDENSE::Init( vimd, start );
}
else
{
assert( start == 0 );
MDVDENSE::Init( 1, 1 );
}
}
void Init ( int cdim, ... )
{
if ( cdim > 0 )
{
va_list vl;
va_start( vl, cdim );
MDVDENSE::Init( cdim, vl );
}
else
{
MDVDENSE::Init( 1, 1 );
}
}
void Clear ( REAL r = 0.0 )
{
size_t celem = size();
for ( int i = 0; i < celem; )
self[i++] = r;
}
REAL RSum () const
{
return first.sum();
}
void Normalize ()
{
REAL rSum = RSum();
if ( rSum != 0.0 && rSum != 1.0 )
{
size_t celem = size();
for ( int i = 0; i < celem; )
self[i++] /= rSum;
}
}
MDVCPD & operator = ( const MDVCPD & mdv )
{
MDVDENSE::Init( mdv.Slice() );
first = mdv.first;
return self;
}
// Convert this MDVCPD to a single-dimension object
MDVCPD & operator = ( const VLREAL & vlr )
{
Init( 1, vlr.size() );
first = vlr;
return self;
}
// Given a partial dimension (incomplete) subscript, update the appropriate
// range of elements. Note that providing an incomplete (i.e., short)
// subscript array to the "offset" functions is valid; the results
// are the same as if the missing lower-order elements were zero.
void UpdatePartial ( const VIMD & vimd, const VLREAL & vlr )
{
const VIMD vimdDim = VimdDim();
// Compute the appropriate number of elements
size_t cElem = 1;
assert( vimd.size() <= vimdDim.size() );
for ( int idim = vimd.size(); idim < vimdDim.size(); idim++ )
{
cElem *= vimdDim[idim];
}
ASSERT_THROW( vlr.size() == cElem,
EC_MDVECT_MISUSE,
"m-d vector partial projection count invalid" );
// Index to the proper position and update from the source data
assert( second._IOff(vimd) + cElem <= first.size() );
REAL * prSelf = & self[vimd];
for ( int iElem = 0; iElem < cElem; )
*prSelf++ = vlr[iElem++];
}
void Clone ( const MDVCPD & mdv )
{
self = mdv;
}
};
// Class MPCPDD: Distribution map by specific index
// Hungarian: 'drmap'
class MPCPDD : public map<VIMD, VLREAL, lessv<VIMD> >
{
public:
MPCPDD () {}
~ MPCPDD () {}
void Clone ( const MPCPDD & dmap )
{
self = dmap;
}
// Return a pointer to the dimensionless "default" vector or NULL
const VLREAL * PVlrDefault () const
{
VIMD vimdDefault;
const_iterator itdm = find( vimdDefault );
return itdm == end()
? NULL
: & (*itdm).second;
}
bool operator == ( const MPCPDD & mpcpdd ) const
{
if ( size() != mpcpdd.size() )
return false;
const_iterator itself = begin();
const_iterator itmp = mpcpdd.begin();
for ( ; itself != end(); itself++, itmp++ )
{
if ( (*itself).first != (*itmp).first )
return false;
if ( ! vequal( (*itself).second, (*itmp).second ) )
return false;
}
return true;
}
bool operator != ( const MPCPDD & mpcpdd ) const
{ return !(self == mpcpdd); }
};
#endif