int testShrinkObservedNodes() { int i/*,j*/; int ret = TRS_OK; /*prepare to read the values from console*/ EDistributionType dt; int disType = -1; EFactorType pt; int paramType = -1; /*read int disType corresponding DistributionType*/ while((disType<0)||(disType>0))/*now we have only Tabulars&Gaussian*/ { trsiRead( &disType, "0", "DistributionType"); } /*read int paramType corresponding FactorType*/ while((paramType<0)||(paramType>2)) { trsiRead( ¶mType, "0", "FactorType"); } dt = EDistributionType(disType); pt = EFactorType(paramType); int numberOfNodes = 0; /*read number of nodes in Factor domain*/ while(numberOfNodes<=0) { trsiRead( &numberOfNodes, "1", "Number of Nodes in domain"); } int numNodeTypes = 0; /*read number of node types in model*/ while(numNodeTypes<=0) { trsiRead( &numNodeTypes, "1", "Number of node types in Domain"); } //int seed1 = pnlTestRandSeed()/*%100000*/; /*create string to display the value*/ /* char *value = new char[20]; value = _itoa(seed1, value, 10); trsiRead(&seed1, value, "Seed for srand to define NodeTypes etc."); delete []value; trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "seed for rand = %d\n", seed1); int *domain = (int *)trsGuardcAlloc(numberOfNodes, sizeof(int)); CNodeType * allNodeTypes = (CNodeType*)trsGuardcAlloc(numNodeTypes, sizeof(CNodeType)); //To generate the NodeTypes we use rand()% and creates only Tabular now for(i=0; i<numNodeTypes; i++) { allNodeTypes[i] = CNodeType(1, 1+rand()%(numNodeTypes+3)); } */ /*load data for parameter::ShrinkObservedNodes from console*/ intVector domain; domain.assign( numberOfNodes, 0 ); nodeTypeVector allNodeTypes; allNodeTypes.assign( numNodeTypes, CNodeType() ); /*read node types*/ for(i=0; i < numNodeTypes; i++) { int IsDiscrete = -1; int NodeSize = -1; while((IsDiscrete<0)||(IsDiscrete>1)) /*now we have tabular & Gaussian nodes!! */ trsiRead(&IsDiscrete, "1", "Is the node discrete?"); while(NodeSize<0) trsiRead(&NodeSize, "2", "NodeSize of node"); allNodeTypes[i] = CNodeType( IsDiscrete != 0, NodeSize ); } const CNodeType **nodeTypesOfDomain = (const CNodeType**) trsGuardcAlloc(numberOfNodes, sizeof(CNodeType*)); int numData = 1; int *Ranges = (int*)trsGuardcAlloc(numberOfNodes, sizeof(int)); /*associate nodes to node types*/ for(i=0; i<numberOfNodes; i++) { domain[i] = i; int nodeAssociationToNodeType = -1; while((nodeAssociationToNodeType<0)||(nodeAssociationToNodeType>= numNodeTypes)) trsiRead(&nodeAssociationToNodeType, "0", "node i has type nodeAssociationToNodeType"); nodeTypesOfDomain[i] = &allNodeTypes[nodeAssociationToNodeType]; // nodeTypesOfDomain[i] = &allNodeTypes[rand()%numNodeTypes]; Ranges[i] = nodeTypesOfDomain[i]->GetNodeSize(); numData=numData*Ranges[i]; } CModelDomain* pMD = CModelDomain::Create( allNodeTypes, domain ); /*create factor according all information*/ CFactor *pMyParam = NULL; float *data = (float *)trsGuardcAlloc(numData, sizeof(float)); char *stringVal;/* = (char*)trsGuardcAlloc(50, sizeof(char));*/ double val=0; /*read the values from console*/ if(pt == ftPotential) { pMyParam = CTabularPotential::Create( &domain.front(), numberOfNodes, pMD ); /*here we can create data by multiply on 0.1 - numbers are nonnormalized*/ for(i=0; i<numData; i++) { val = 0.1*i; stringVal = trsDouble(val); trsdRead(&val, stringVal, "value of i's data position"); data[i] = (float)val; //data[i] = (float)rand()/1000; } } else { /*we can only read data from console - it must be normalized!! (according their dimensions) - or we can normalize it by function!*/ if(pt == ftCPD) pMyParam = CTabularCPD::Create( &domain.front(), numberOfNodes, pMD ); for(i=0; i<numData; i++) { val = -1; while((val<0)||(val>1)) { trsdRead(&val, "-1", "value of (2*i)'s data position"); } data[i] = (float)val; } } //trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "data for Factor = %d\n", data[i]); pMyParam->AllocMatrix(data,matTable); int nObsNodes = 0; /*rand()%numberOfNodes;*/ while((nObsNodes<=0)||(nObsNodes>numberOfNodes)) { trsiRead(&nObsNodes, "1", "Number of Observed Nodes"); } intVector myHelpForEvidence = intVector(domain.begin(), domain.end() ); int *ObsNodes = (int *)trsGuardcAlloc(nObsNodes, sizeof(int)); valueVector TabularValues; TabularValues.assign( nObsNodes, (Value)0 ); char *strVal; for(i=0; i<nObsNodes; i++) { //fixme - we need to have noncopy only different ObsNodes /* j = rand()%(numberOfNodes-i);*/ int numberOfObsNode = -1; strVal = trsInt(i); intVector::iterator j = std::find( myHelpForEvidence.begin(), myHelpForEvidence.end(), numberOfObsNode ); while((numberOfObsNode<0)||(numberOfObsNode>numberOfNodes)|| (j==myHelpForEvidence.end())) { trsiRead(&numberOfObsNode, strVal,"Number of i's observed node"); j = std::find(myHelpForEvidence.begin(), myHelpForEvidence.end(), numberOfObsNode); } //ObsNodes[i] = myHelpForEvidence[j]; myHelpForEvidence.erase( j ); ObsNodes[i] = numberOfObsNode; int valueOfNode = -1; int maxValue = (*nodeTypesOfDomain[ObsNodes[i]]).GetNodeSize(); while((valueOfNode<0)||(valueOfNode>=maxValue)) { trsiRead(&valueOfNode,"0","this is i's observed node value"); } TabularValues[i].SetInt(valueOfNode); /*rand()%((*nodeTypesOfDomain[ObsNodes[i]]).pgmGetNodeSize());*/ } CEvidence* pEvidence = CEvidence::Create( pMD, nObsNodes, ObsNodes, TabularValues ); myHelpForEvidence.clear(); CNodeType *ObservedNodeType = (CNodeType*)trsGuardcAlloc(1, sizeof(CNodeType)); *ObservedNodeType = CNodeType(1,1); CPotential *myTakedInFactor = static_cast<CPotential*>(pMyParam)->ShrinkObservedNodes(pEvidence); const int *myfactorDomain; int factorDomSize ; myTakedInFactor->GetDomain(&factorDomSize, &myfactorDomain); #if 0 CNumericDenseMatrix<float> *mySmallMatrix = static_cast< CNumericDenseMatrix<float>*>(myTakedInFactor->GetMatrix(matTable)); int n; const float* mySmallData; mySmallMatrix->GetRawData(&n, &mySmallData); int nDims; // = mySmallMatrix->GetNumberDims(); const int * mySmallRanges; mySmallMatrix->GetRanges(&nDims, &mySmallRanges); if(nDims!=numberOfNodes) { ret = TRS_FAIL; trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "nDims = %d\n", nDims); } else { int numSmallData = 1; for(i=0; i<nDims; i++) { numSmallData = numSmallData*mySmallRanges[i]; trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "Range[%d] = %d\n", i, mySmallRanges[i]); } for(i=0; i<numSmallData; i++) { trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "mySmallData[%d] = %f ", i, mySmallData[i]); } } #endif //getchar(); delete(myTakedInFactor); delete (pMyParam); delete pMD; //test gaussian parameter nodeTypeVector nTypes; nTypes.assign( 2, CNodeType() ); nTypes[0] = CNodeType( 0, 2 ); nTypes[1] = CNodeType( 0,1 ); intVector domn = intVector(3,0); domn[1] = 1; domn[2] = 1; CModelDomain* pMD1 = CModelDomain::Create( nTypes, domn ); domn[2] = 2; CPotential *BigFactor = CGaussianPotential::CreateUnitFunctionDistribution( &domn.front(), domn.size(), pMD1,0 ); float mean[] = { 1.0f, 3.2f}; CPotential *SmallDelta = CGaussianPotential::CreateDeltaFunction( &domn.front(), 1, pMD1, mean, 1 ); domn.resize( 2 ); domn[0] = 1; domn[1] = 2; CPotential *SmallFunct = CGaussianPotential::Create( &domn.front(), domn.size(), pMD1); float datH[] = { 1.1f, 2.2f, 3.3f }; float datK[] = { 1.2f, 2.3f, 2.3f, 3.4f, 5.6f, 6.7f, 3.4f, 6.7f, 9.0f }; SmallFunct->AllocMatrix( datH, matH ); SmallFunct->AllocMatrix( datK, matK ); static_cast<CGaussianPotential*>(SmallFunct)->SetCoefficient( 0.2f, 1 ); CPotential* multFact = BigFactor->Multiply( SmallDelta ); CPotential* nextMultFact = multFact->Multiply( SmallFunct ); domn[0] = 0; domn[1] = 1; CPotential *marginalized = static_cast<CPotential*>(nextMultFact->Marginalize( &domn.front(), domn.size() )); int isSpecific = marginalized->IsDistributionSpecific(); if( isSpecific ) { trsWrite(TW_CON|TW_RUN|TW_DEBUG|TW_LST, "\nGaussian Distribution is specific"); } delete BigFactor; delete SmallFunct; delete SmallDelta; delete pMD1; int ranges_memory_flag = trsGuardCheck(Ranges); int data_memory_flag = trsGuardCheck(data); int nodeTypesOfDomain_mem_b = trsGuardCheck(nodeTypesOfDomain); int ObsNodes_mem_b = trsGuardCheck(ObsNodes); int ObsNodeType_mem_b = trsGuardCheck(ObservedNodeType); if(((ranges_memory_flag)||(data_memory_flag)|| (nodeTypesOfDomain_mem_b)|| (ObsNodes_mem_b)||(ObsNodeType_mem_b))) { ret = TRS_FAIL; return trsResult( ret, ret == TRS_OK ? "No errors" : "Bad test on ShrinkObservedNodes Method - memory"); } else { trsGuardFree(ObservedNodeType); trsGuardFree(ObsNodes); trsGuardFree(nodeTypesOfDomain); trsGuardFree(data); trsGuardFree(Ranges); } return trsResult( ret, ret == TRS_OK ? "No errors" : "Bad test on ShrinkObservedNodes Method"); }
//----------------------------------------------------------------------------- CPotential* CSoftMaxCPD::ConvertWithEvidenceToGaussianPotential( const CEvidence* pEvidence, floatVector MeanContParents, C2DNumericDenseMatrix<float>* CovContParents, const int *parentIndices, int flagSumOnMixtureNode ) const { int SoftMaxSize = GetSoftMaxSize(); if (SoftMaxSize != 2) { PNL_THROW(CNotImplemented, "It is not sigmoid"); } else { if (m_CorrespDistribFun->GetDistributionType() == dtSoftMax) { CPotential* pot = ConvertToGaussianPotential(pEvidence, m_CorrespDistribFun, MeanContParents, CovContParents); CPotential *pot2 = NULL; int domSize = pot->GetDomainSize(); bool IsAllContUnobserved = true; const pConstNodeTypeVector* ntVec = pot->GetDistribFun()->GetNodeTypesVector(); for( int i = 0; i < domSize-1; i++ ) { intVector Domain; pot->GetDomain(&Domain); int curNode = Domain[i]; if( (pEvidence->IsNodeObserved(curNode))) { if( !(*ntVec)[i]->IsDiscrete() ) { IsAllContUnobserved = false; } } } if ((pot->GetDomainSize() >= 3)&&(!IsAllContUnobserved)) { pot2 = pot->ShrinkObservedNodes(pEvidence); } else { intVector Domain; pot->GetDomain(&Domain); pot2 = pot->Marginalize(&(Domain[0]), 1); } delete pot; return pot2; } else //it means m_CorrespDistribFun->GetDistributionType == dtCondSoftMax { int i; const CSoftMaxDistribFun* dtSM; dtSM = static_cast<CCondSoftMaxDistribFun*>(m_CorrespDistribFun)-> GetDistribution(parentIndices); intVector pObsNodes; pConstValueVector pObsValues; pConstNodeTypeVector pNodeTypes; pEvidence->GetObsNodesWithValues(&pObsNodes, &pObsValues, &pNodeTypes); int r = -1; for (i = 0; i < pObsNodes.size(); i++) { if (m_Domain[m_Domain.size()-1] == pObsNodes[i]) { r = pObsValues[i]->GetInt(); break; } } if (r == -1) { PNL_THROW(CNotImplemented, "Not exist evidence"); } CDistribFun *gauFactData = const_cast<CSoftMaxDistribFun*>(dtSM)-> ConvertCPDDistribFunToPotential(MeanContParents, CovContParents, r); intVector gauSubDomain; const CNodeType *nt; for(i = 0; i < m_Domain.size(); i++) { nt = GetModelDomain()->GetVariableType( m_Domain[i] ); if(!(nt->IsDiscrete())) { gauSubDomain.push_back(m_Domain[i]); } } intVector obsIndex; for( i = 0; i < gauSubDomain.size(); i++ ) { if( pEvidence->IsNodeObserved(gauSubDomain[i]) ) { obsIndex.push_back( i ); } } CGaussianPotential *resFactor = CGaussianPotential::Create(&gauSubDomain.front(), gauSubDomain.size(), GetModelDomain()); resFactor->SetDistribFun( gauFactData ); CPotential *pot = NULL; int domSize = resFactor->GetDomainSize(); bool IsAllContUnobserved = true; const pConstNodeTypeVector* ntVec = resFactor->GetDistribFun()->GetNodeTypesVector(); for( i = 0; i < domSize-1; i++ ) { intVector Domain; resFactor->GetDomain(&Domain); int curNode = Domain[i]; if( (pEvidence->IsNodeObserved(curNode))) { if( !(*ntVec)[i]->IsDiscrete() ) { IsAllContUnobserved = false; } } } if ((resFactor->GetDomainSize() >= 3)&&(!IsAllContUnobserved)) { pot = resFactor->ShrinkObservedNodes(pEvidence); } else { intVector Domain; resFactor->GetDomain(&Domain); pot = resFactor->Marginalize(&(Domain[0]), 1); } delete resFactor; delete gauFactData; return pot; } } }
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; }
void CJtreeInfEngine::PropagateBetweenClqs(int source, int sink, bool isCollect) { PNL_CHECK_RANGES( source, 0, m_pJTree->GetNumberOfNodes() - 1 ); PNL_CHECK_RANGES( sink, 0, m_pJTree->GetNumberOfNodes() - 1 ); 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 "); } bool isDense = true; if(!m_pJTree->GetNodeType(source)->IsDiscrete() || !m_pJTree->GetNodeType(sink)->IsDiscrete()) { isDense = false; } CPotential *potSource = m_pJTree->GetNodePotential(source), *potSink = m_pJTree->GetNodePotential(sink); if(potSource->IsSparse() || potSink->IsSparse()) { isDense = false; } // check that nodes source and sink are discrete if(isDense && !m_bMaximize) { pnl::CNumericDenseMatrix< float > *sorceMatrix, *sepMatrix, *sinkMatrix; int *dims_to_keep, *dims_to_mul; int num_dims_to_keep, num_dims_to_mul; if (GetDataForMargAndMult(source, sink, &sorceMatrix, &dims_to_keep, num_dims_to_keep, &sepMatrix, &sinkMatrix, &dims_to_mul, num_dims_to_mul)) { DoPropagate(sorceMatrix, dims_to_keep, num_dims_to_keep, sepMatrix, sinkMatrix, dims_to_mul, num_dims_to_mul, isCollect); delete [] dims_to_keep; delete [] dims_to_mul; } else { CPotential *potSink = m_pJTree->GetNodePotential(sink); potSink->Normalize(); } } else { int numNdsInSepDom; const int *sepDom; int numNdsInSDom; const int *sDom; potSource->GetDomain( &numNdsInSDom, &sDom ); CPotential *potSep = m_pJTree->GetSeparatorPotential( source, sink ); CPotential *newPotSep, *updateRatio; potSep->GetDomain( &numNdsInSepDom, &sepDom ); newPotSep = potSource->Marginalize( sepDom, numNdsInSepDom, m_bMaximize ); updateRatio = newPotSep->Divide(potSep); *potSink *= *updateRatio; potSink->Normalize(); potSep->SetDistribFun(newPotSep->GetDistribFun()); delete newPotSep; delete updateRatio; } }
void CJtreeInfEngine::MarginalNodes( const int *query, int querySz, int notExpandJPD ) { // bad-args check PNL_CHECK_IS_NULL_POINTER(query); PNL_CHECK_RANGES( querySz, 1, m_pGraphicalModel->GetNumberOfNodes() ); // bad-args check end /* // the following should be working differently for the case of doing the // whole EnterEvidence procedure or just CollectEvidence for the root node if( ( m_lastOpDone != opsDistribute ) && ( m_lastOpDone != opsMargNodes ) ) { if( m_lastOpDone != opsCollect ) { PNL_THROW( CInvalidOperation, " cannot perform marginalization, infEngine inconsistent " ); } int numOfClqsContQuery; const int *clqsContQuery; m_pOriginalJTree->GetClqNumsContainingSubset( querySz, query, &numOfClqsContQuery, &clqsContQuery ); PNL_CHECK_FOR_ZERO(numOfClqsContQuery); if( std::find( clqsContQuery, clqsContQuery + numOfClqsContQuery, m_JTreeRootNode ) == clqsContQuery + numOfClqsContQuery ) { PNL_THROW( CInvalidOperation, " cannot marginalize to the non-root-clq nodes set " ); } //////// this is to debug for( int i = 0; i < numOfClqsContQuery; ++i ) { CPotential *pJPot = m_pJTree->GetNodePotential(clqsContQuery[i]) ->Marginalize( query, querySz ); CPotential *pJPot1 = pJPot->GetNormalized(); pJPot1->Dump(); delete pJPot; delete pJPot1; } /////////////////////////////////////////////////////// MarginalizeCliqueToQuery( m_JTreeRootNode, querySz, query ); m_lastOpDone = opsMargNodes; } else { */ int numOfClqsContQuery; const int *clqsContQuery; m_pJTree->GetClqNumsContainingSubset( querySz, query, &numOfClqsContQuery, &clqsContQuery ); if(numOfClqsContQuery) { if( std::find( clqsContQuery, clqsContQuery + numOfClqsContQuery, m_JTreeRootNode ) != ( clqsContQuery + numOfClqsContQuery ) ) { MarginalizeCliqueToQuery( m_JTreeRootNode, querySz, query, notExpandJPD ); } else { MarginalizeCliqueToQuery( *clqsContQuery, querySz, query, notExpandJPD ); } } else { const int* clqDomain; int clqSize; CPotential *resPot = NULL; delete m_pQueryJPD; m_pQueryJPD = NULL; ShrinkJTreeCliques(querySz, const_cast<int*>(query)); resPot = MergeCliques(querySz, const_cast<int*>(query)); resPot->GetDomain(&clqSize, &clqDomain); if( !pnlIsIdentical(querySz, const_cast<int*>(query), clqSize, const_cast<int*>(clqDomain)) ) { m_pQueryJPD = resPot->Marginalize(const_cast<int*>(query), querySz); } else { m_pQueryJPD = static_cast<CPotential*>(resPot->Clone()); } m_pQueryJPD->Normalize(); delete resPot; } }
CPotential* CJtreeInfEngine::MergeCliques(int domSize, int* Domain) { int numNodes = m_pJTree->GetNumberOfNodes(); potsPVector vPots(numNodes, (CPotential*)0); int i; const int* clqDomain; int clqSize; const int* sepDomain; int sepSize; const int *nbr, *nbrs_end; int numOfNbrs; const int *nbrs; const ENeighborType *nbrsTypes; intVector::const_iterator sourceIt, source_end; intVecVector::const_iterator layerIt = m_collectSequence.begin(), collSeq_end = m_collectSequence.end(); const CGraph *pGraph = m_pJTree->GetGraph(); intVector nodesSentMessages; intVector tmpV; for( ; layerIt != collSeq_end; ++layerIt ) { for( sourceIt = layerIt->begin(), source_end = layerIt->end(); sourceIt != source_end; ++sourceIt ) { if( !m_NodesAfterShrink[*sourceIt] ) continue; pGraph->GetNeighbors( *sourceIt, &numOfNbrs, &nbrs, &nbrsTypes ); tmpV.assign(Domain, Domain+domSize); for( nbr = nbrs, nbrs_end = nbrs + numOfNbrs; nbr != nbrs_end; ++nbr ) { if( !m_NodesAfterShrink[*nbr] ) continue; m_pJTree->GetSeparatorDomain(*sourceIt, *nbr, &sepSize, &sepDomain); tmpV = pnlSetUnion(sepSize, const_cast<int*>(sepDomain), tmpV.size(), &tmpV.front()); } m_pJTree->GetNodeContent(*sourceIt, &clqSize, &clqDomain); tmpV = pnlIntersect(clqSize, const_cast<int*>(clqDomain), tmpV.size(), &tmpV.front()); if( !pnlIsIdentical(tmpV.size(), &tmpV.front(), clqSize, const_cast<int*>(clqDomain)) ) { vPots[*sourceIt] = m_pJTree->GetNodePotential(*sourceIt)->Marginalize(tmpV); } else { vPots[*sourceIt] = static_cast<CPotential*>(m_pJTree->GetNodePotential(*sourceIt)->Clone()); } } } intVector bigDomain; layerIt = m_collectSequence.begin(); nodesSentMessages.assign(numNodes, false); CPotential* tPot; for( ; layerIt != collSeq_end; ++layerIt ) { for( sourceIt = layerIt->begin(), source_end = layerIt->end(); sourceIt != source_end; ++sourceIt ) { if( !m_NodesAfterShrink[*sourceIt] )continue; pGraph->GetNeighbors( *sourceIt, &numOfNbrs, &nbrs, &nbrsTypes ); for( nbr = nbrs, nbrs_end = nbrs + numOfNbrs; nbr != nbrs_end; ++nbr ) { if( !nodesSentMessages[*nbr] && m_NodesAfterShrink[*nbr] ) { CPotential* pPot = vPots[*nbr]; CPotential* cPot = vPots[*sourceIt]; CPotential* bigPot = pnlMultiply(pPot, cPot, GetModel()->GetModelDomain()); *bigPot /= *(m_pJTree->GetSeparatorPotential(*sourceIt, *nbr)); m_NodesAfterShrink[*sourceIt] = false; int numOfNbrs1; const int *nbrs1, *nbr1, *nbrs1_end; const ENeighborType *nbrsTypes1; pGraph->GetNeighbors( *nbr, &numOfNbrs1, &nbrs1, &nbrsTypes1 ); tmpV.assign(Domain, Domain+domSize); for(nbr1 = nbrs1, nbrs1_end = nbrs1 + numOfNbrs1; nbr1 != nbrs1_end; ++nbr1 ) { if( !m_NodesAfterShrink[*nbr1] ) continue; m_pJTree->GetSeparatorDomain(*nbr, *nbr1, &sepSize, &sepDomain); tmpV = pnlSetUnion(sepSize, const_cast<int*>(sepDomain), tmpV.size(), &tmpV.front()); } bigPot->GetDomain(&bigDomain); tmpV = pnlIntersect(tmpV.size(), &tmpV.front(), bigDomain.size(), &bigDomain.front()); if( tmpV.size() < bigDomain.size() ) { tPot = bigPot->Marginalize(&tmpV.front(), tmpV.size()); delete bigPot; bigPot = tPot; } delete vPots[*nbr]; vPots[*nbr] = bigPot; bigPot->GetDomain(&bigDomain); if( pnlIsSubset(domSize, Domain, bigDomain.size(), &bigDomain.front()) ) { CPotential* retPot = static_cast<CPotential*>(bigPot->Clone()); for(i=0; i<numNodes; i++) { delete vPots[i]; } vPots.clear(); m_NodesAfterShrink.clear(); return retPot; } } nodesSentMessages[*sourceIt] = true; } } } PNL_THROW(CInternalError, "internal error"); }
void CSpecPearlInfEngine::MarginalNodes( const int* query, int querySize, int notExpandJPD ) { if( notExpandJPD == 1 ) { PNL_THROW( CInconsistentType, "pearl inference work with expanded distributions only" ); } PNL_CHECK_LEFT_BORDER(querySize, 1); if( m_pQueryJPD ) { delete m_pQueryJPD; } if( m_pEvidenceMPE ) { delete m_pEvidenceMPE; } if( querySize == 1 ) { if( m_bMaximize ) { //compute MPE m_pEvidenceMPE = m_beliefs[m_curState][query[0]]->GetMPE(); } else { // get marginal for one node - cretae parameter on existing data - m_beliefs[query[0]]; m_pQueryJPD = m_beliefs[m_curState][query[0]]->GetNormalized(); } } else { int numParams; CFactor ** params; m_pGraphicalModel->GetFactors( querySize, query, &numParams ,¶ms ); if ( !numParams ) { PNL_THROW( CBadArg, "only members of one family can be in query instead of one node" ) } if( numParams != 1 ) { PNL_THROW( CBadArg, "add more nodes to specify which of jpd you want to know") } int i; //get informatiom from parametr on these nodes to crate new parameter //with updated Data CPotential* allPot; if( m_modelType == mtMRF2 ) { //just multiply and marginalize allPot = static_cast<CPotential*>(params[0]->Clone()); } else { //m_modelType == mtBNet //need to convert to potential withiut evidence and multiply //and marginalize after that allPot = static_cast<CCPD*>(params[0])->ConvertToPotential(); } //get neighbors of last node in domain (child for CPD) //to compute JPD for his family int domSize; const int* dom; params[0]->GetDomain(&domSize, &dom); //start multiply to add information after inference for( i = 0; i < domSize; i++ ) { (*allPot) *= (*m_beliefs[m_curState][dom[i]]) ; } m_pQueryJPD = allPot->Marginalize( query, querySize, m_bMaximize ); //fixme - can replace by normalize in self m_pQueryJPD->Normalize(); if( m_bMaximize ) { //compute MPE m_pEvidenceMPE = m_pQueryJPD->GetMPE(); delete m_pQueryJPD; m_pQueryJPD = NULL; } } }