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; }
bool CSamplingInfEngine:: ConvertingFamilyToPot( int node, const CEvidence* pEv ) { bool ret = false; CPotential* potToSample = m_potsToSampling[node]; Normalization(potToSample); int i; if( !IsAllNdsTab() ) { if( GetModel()->GetModelType() == mtBNet ) { for( i = 0; i < m_environment[node].size(); i++ ) { int num = m_environment[node][i]; CPotential *pot1 = static_cast< CCPD* >( m_currentFactors[ num ] ) ->ConvertWithEvidenceToPotential(pEv); CPotential *pot2 = pot1->Marginalize(&node, 1); delete pot1; *potToSample *= *pot2; delete pot2; } } else { for( i = 0; i < m_environment[node].size(); i++ ) { int num = m_environment[node][i]; CPotential *pot1 = static_cast< CPotential* >( m_currentFactors[ num ] ) ->ShrinkObservedNodes(pEv); CPotential *pot2 = pot1->Marginalize(&node, 1); delete pot1; *potToSample *= *pot2; delete pot2; } } } else { CMatrix< float > *pMatToSample; pMatToSample = static_cast<CTabularDistribFun*>(potToSample->GetDistribFun()) ->GetMatrix(matTable); intVector dims; intVector vls; intVector domain; for( i = 0; i < m_environment[node].size(); i++ ) { int num = m_environment[node][i]; m_currentFactors[ num ]->GetDomain(&domain); GetObsDimsWithVls( domain, node, pEv, &dims, &vls); CMatrix< float > *pMat; pMat = static_cast<CTabularDistribFun*>(m_currentFactors[ num ]-> GetDistribFun())->GetMatrix(matTable); pMat->ReduceOp( &dims.front(), dims.size(), 2, &vls.front(), pMatToSample, PNL_ACCUM_TYPE_MUL ); dims.clear(); vls.clear(); domain.clear(); } } //check for non zero elements CMatrix<float> *pMat; if( potToSample->GetDistributionType()==dtTabular ) { pMat = potToSample->GetDistribFun()->GetMatrix(matTable); } else { CGaussianDistribFun* pDistr = static_cast<CGaussianDistribFun*>(potToSample->GetDistribFun()); if(pDistr->GetMomentFormFlag()) { pMat = pDistr->GetMatrix(matCovariance); } else { pMat = pDistr->GetMatrix(matK); } } CMatrixIterator<float>* iter = pMat->InitIterator(); for( iter; pMat->IsValueHere( iter ); pMat->Next(iter) ) { if(*(pMat->Value( iter )) > FLT_EPSILON) { ret = true; break; } } delete iter; return ret; }
int CJtreeInfEngine::GetDataForMargAndMult(const int source, const int sink, pnl::CNumericDenseMatrix< float > **sorceMatrix, int **dims_to_keep, int &num_dims_to_keep, pnl::CNumericDenseMatrix< float > **sepMatrix, pnl::CNumericDenseMatrix< float > **sinkMatrix, int **dims_to_mul, int &num_dims_to_mul) { // bad-args check PNL_CHECK_RANGES(source, 0, m_pJTree->GetNumberOfNodes() - 1); PNL_CHECK_RANGES(sink, 0, m_pJTree->GetNumberOfNodes() - 1); // bad-args check end if (source == sink) { PNL_THROW(CInvalidOperation, " source and sink should differ "); } if (!m_pJTree->GetGraph()->IsExistingEdge(source, sink)) { PNL_THROW(CInvalidOperation, " there is no edge between source and sink"); } CPotential *potSource = m_pJTree->GetNodePotential(source), *potSink = m_pJTree->GetNodePotential(sink); int numNdsInSourceDom, numNdsInSinkDom; const int *sourceDom, *sinkDom; potSource->GetDomain(&numNdsInSourceDom, &sourceDom); potSink->GetDomain(&numNdsInSinkDom, &sinkDom); CPotential *potSep = m_pJTree->GetSeparatorPotential(source, sink); int numNdsInSepDom; const int *sepDom; potSep->GetDomain(&numNdsInSepDom, &sepDom); EDistributionType sepDistType = potSep->GetDistributionType(); num_dims_to_keep = numNdsInSepDom; *dims_to_keep = new int [num_dims_to_keep]; int* pEquivPos; for (int i = 0; i < numNdsInSepDom; i++) { pEquivPos = (int*)std::find(sourceDom, sourceDom + numNdsInSourceDom, sepDom[i]); if (pEquivPos != sourceDom + numNdsInSourceDom) { (*dims_to_keep)[i] = (pEquivPos - sourceDom); } else { PNL_THROW( CInconsistentSize, "small domain isn't subset of domain") return 0; } //check that pSmallDom is m_Domain's subset } switch (sepDistType) { case dtTabular: { CDistribFun *sepDistrFun = potSep -> GetDistribFun(); CDistribFun *sourceDistrFun = potSource -> GetDistribFun(); CDistribFun *sinkDistrFun = potSink -> GetDistribFun(); if (!sourceDistrFun->IsValid()) { PNL_THROW( CInconsistentType, "MarginalizeData is invalid" ) } //check if distribution of potSource is Unit Function - do nothing if(sourceDistrFun->IsDistributionSpecific()) { return 0; } if ( sepDistrFun->IsDistributionSpecific() ) { sepDistrFun->SetUnitValue(0); } *sorceMatrix = static_cast<CNumericDenseMatrix<float> *>(sourceDistrFun-> GetMatrix(matTable)); *sepMatrix = static_cast<CNumericDenseMatrix<float> *>(sepDistrFun-> GetMatrix(matTable)); EDistributionType dtsink = sinkDistrFun->GetDistributionType(); if ((dtsink != dtTabular) && (dtsink != dtScalar)) { PNL_THROW(CInvalidOperation, "we can multiply only tabulars") } int location; num_dims_to_mul = numNdsInSepDom; *dims_to_mul = new int [num_dims_to_mul]; for (int i = 0; i < numNdsInSepDom; i++) { location = std::find(sinkDom, sinkDom + numNdsInSinkDom, sepDom[i]) - sinkDom; if (location < numNdsInSinkDom) { (*dims_to_mul)[i] = location; } } if(sinkDistrFun->IsDistributionSpecific()) { sinkDistrFun->SetUnitValue(0); floatVector *aValue = (floatVector *)((CDenseMatrix<float>*)sinkDistrFun-> GetMatrix(matTable))->GetVector(); aValue->assign(aValue->size(), 1.0f); } *sinkMatrix = static_cast<CNumericDenseMatrix<float>*>(sinkDistrFun-> GetMatrix(matTable)); break; } case dtScalar: { // propagate isn't need return 0; } default: { PNL_THROW(CNotImplemented, "we have only Tabular now"); return 0; } } if (numNdsInSepDom == 0) { PNL_THROW(COutOfRange, "domain size should be positive"); } return 1; }