void CGibbsSamplingInfEngine:: MarginalNodes( const int *queryIn, int querySz, int notExpandJPD ) { delete m_pQueryJPD; m_pQueryJPD = NULL; delete m_pPotMPE; m_pPotMPE = NULL; delete m_pEvidenceMPE; m_pEvidenceMPE = NULL; const CFactor *pFactor; CPotential *pPot = NULL; int *begin1; int *end1; int *begin2; int *end2; intVector domainVec; intVector queryVec; intVector obsQueryVec; queryVec.reserve(querySz); obsQueryVec.reserve(querySz); int i; for( i = 0; i < querySz; i++ ) { m_pEvidence->IsNodeObserved(queryIn[i]) ? obsQueryVec.push_back(queryIn[i]): queryVec.push_back(queryIn[i]); } CPotential *tmpPot = NULL; if( queryVec.size() ) { for( i = 0; i < m_queryFactors.size(); i++) { domainVec.clear(); pFactor = m_queryFactors[i]; pFactor->GetDomain(&domainVec); begin1 = &domainVec.front(); end1 = &domainVec.back() + 1; std::sort(begin1, end1); begin2 = &queryVec.front(); end2 = &queryVec.back() + 1; std::sort(begin2, end2); if( std::includes(begin1, end1, begin2, end2) ) { pPot = pFactor->ConvertStatisticToPot( (GetMaxTime()-GetBurnIn()-1)*GetNumStreams() ); tmpPot = pPot->Marginalize( queryVec ); delete pPot; break; } } if( !tmpPot ) { PNL_THROW(CInvalidOperation, "Invalid query"); } } delete m_pQueryJPD; if( obsQueryVec.size() ) { EDistributionType paramDistrType = pnlDetermineDistributionType( GetModel()->GetModelDomain(), querySz, queryIn, m_pEvidence); CPotential *pQueryPot; switch( paramDistrType ) { case dtTabular: { pQueryPot = CTabularPotential::CreateUnitFunctionDistribution( queryIn, querySz, m_pGraphicalModel->GetModelDomain() ); break; } case dtGaussian: { pQueryPot = CGaussianPotential::CreateUnitFunctionDistribution( queryIn, querySz, m_pGraphicalModel->GetModelDomain() ); break; } case dtScalar: { pQueryPot = CScalarPotential::Create( queryIn, querySz, m_pGraphicalModel->GetModelDomain() ); break; } case dtCondGaussian: { PNL_THROW( CNotImplemented, "conditional gaussian factors" ) break; } default: { PNL_THROW( CInconsistentType, "distribution type" ) } } if( tmpPot) { (*pQueryPot) *= (*tmpPot); delete tmpPot; } if( m_bMaximize ) { m_pPotMPE = static_cast<CPotential*> ( pQueryPot->ExpandObservedNodes( m_pEvidence, 0) ); m_pEvidenceMPE = m_pPotMPE->GetMPE(); } else { m_pQueryJPD = static_cast<CPotential*>( pQueryPot->ExpandObservedNodes( m_pEvidence, 0) ); } delete pQueryPot; }
void CJtreeInfEngine:: MarginalizeCliqueToQuery( int clqNum, int querySz, const int *query, int notExpandJPD ) { // bad-args check PNL_CHECK_RANGES( clqNum, 0, m_pJTree->GetNumberOfNodes() - 1 ); PNL_CHECK_RANGES( querySz, 1, m_pGraphicalModel->GetNumberOfNodes() ); PNL_CHECK_IS_NULL_POINTER(query); // bad-args check end // Note: cant call expand() for potentials, which contain continuous // observed nodes in domain, cause those are to be expanded to // mixture of gaussians, which we dont support right now. delete m_pQueryJPD; m_pQueryJPD = NULL; delete m_pPotMPE; m_pPotMPE = NULL; delete m_pEvidenceMPE; m_pEvidenceMPE = NULL; bool bExpandAllowed = true; CPotential* clqPotWithQuery = m_pJTree->GetNodePotential(clqNum); EDistributionType dtClqWithQuery = clqPotWithQuery->GetDistributionType(); if( std::find_first_of( query, query + querySz, m_actuallyObsNodes.begin(), m_actuallyObsNodes.end() ) != ( query + querySz ) ) { const int *queryIt = query, *query_end = query + querySz; for( ; queryIt != query_end; ++queryIt ) { if( std::find( m_actuallyObsNodes.begin(), m_actuallyObsNodes.end(), *queryIt ) != m_actuallyObsNodes.end() ) { int shrNodebDiscrete = m_pGraphicalModel->GetNodeType(*queryIt)->IsDiscrete(); if(((dtClqWithQuery == dtTabular)&&( !shrNodebDiscrete )) ||(( dtClqWithQuery == dtGaussian )&&( shrNodebDiscrete ))) { bExpandAllowed = false; break; } } } } if( ( bExpandAllowed == false ) && ( notExpandJPD == false ) ) { PNL_THROW( CAlgorithmicException, " JPD expansion not possible technically " ); } bExpandAllowed = notExpandJPD ? false : bExpandAllowed; CPotential *pMargJPot = clqPotWithQuery->Marginalize( query, querySz, m_bMaximize ); if( bExpandAllowed ) { CPotential *pExpObsJPot = pMargJPot->ExpandObservedNodes(m_pEvidence); if( m_bMaximize ) { if( pMargJPot->GetDistributionType() == dtScalar ) { m_pPotMPE = pExpObsJPot->GetNormalized(); m_pEvidenceMPE = m_pPotMPE->GetMPE(); } else { m_pPotMPE = pMargJPot->GetNormalized(); m_pEvidenceMPE = m_pPotMPE->GetMPE(); } } else { m_pQueryJPD = pExpObsJPot->GetNormalized(); } delete pExpObsJPot; } else { if( m_bMaximize ) { m_pPotMPE = pMargJPot->GetNormalized(); m_pEvidenceMPE = m_pPotMPE->GetMPE(); } else { m_pQueryJPD = pMargJPot->GetNormalized(); } } if((!m_bMaximize)&&(m_pQueryJPD->GetDistributionType() == dtGaussian)) { static_cast<CGaussianDistribFun*>( m_pQueryJPD->GetDistribFun())->UpdateMomentForm(); } if((m_bMaximize)&&(m_pPotMPE->GetDistributionType() == dtGaussian)) { static_cast<CGaussianDistribFun*>( m_pPotMPE->GetDistribFun())->UpdateMomentForm(); } delete pMargJPot; }