void CJtreeInfEngine:: DivideJTreeNodePotByDistribFun( int clqPotNum, const int *domain, const CDistribFun *pDistrFun ) { // bad-args check PNL_CHECK_RANGES( clqPotNum, 0, m_pJTree->GetNumberOfNodes() - 1 ); PNL_CHECK_IS_NULL_POINTER(domain); PNL_CHECK_IS_NULL_POINTER(pDistrFun); // bad-args check end CPotential *pNodePot = m_pJTree->GetNodePotential(clqPotNum); int nodePotDomSz; const int *nodePotDomain; pNodePot->GetDomain( &nodePotDomSz, &nodePotDomain ); pNodePot->GetDistribFun()->DivideInSelfData( nodePotDomain, domain, pDistrFun ); }
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 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"); }
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; }