//------------------------------------------------------------------------------ CPotential* CSoftMaxCPD::ConvertWithEvidenceToTabularPotential( const CEvidence* pEvidence, int flagSumOnMixtureNode ) const { //need to convert to potential and after that add evidence CPotential* potWithoutEv = ConvertToTabularPotential(pEvidence); CPotential* potWithEvid = potWithoutEv->ShrinkObservedNodes(pEvidence); delete potWithoutEv; return potWithEvid; }
CPotential* CGaussianCPD::ConvertWithEvidenceToPotential(const CEvidence* pEvidence, int flagSumOnMixtureNode )const { if( m_CorrespDistribFun->GetDistributionType() == dtGaussian ) { //need to convert to potential and after that add evidence CPotential* potWithoutEv = ConvertToPotential(); CPotential* potWithEvid = potWithoutEv->ShrinkObservedNodes(pEvidence); delete potWithoutEv; return potWithEvid; } else //it means m_CorrespDistribFun->GetDistributionType == dtCondGaussian { //need to enter discrete & continuous evidence separetly //before it create node types - if all nodes discrete //or there are only nodes of size 0 from continuous - // - result distribution type is Tabular //collect information for enter discrete evidence & continuous int domSize = m_Domain.size(); intVector obsDiscreteIndex; obsDiscreteIndex.reserve( domSize ); //observed discrete values put into int vector intVector obsDiscrVals; obsDiscrVals.reserve( domSize ); //collect information about Gaussian observed indices intVector obsGauIndex; obsGauIndex.reserve( domSize ); //continuous observed values into vector of matrices pnlVector<C2DNumericDenseMatrix<float>*> obsGauVals; obsGauVals.reserve( domSize ); //create matrix to store observed value of node C2DNumericDenseMatrix<float>* obsSelfVal = NULL; //create vectors for storage temporary objects int i; int isTab; for( i = 0; i < domSize; i++ ) { int curNum = m_Domain[i]; if( pEvidence->IsNodeObserved(curNum) ) { const CNodeType* nt = GetModelDomain()->GetVariableType( curNum ); isTab = nt->IsDiscrete(); if( isTab ) { obsDiscreteIndex.push_back( i ); obsDiscrVals.push_back( pEvidence->GetValue(curNum)->GetInt() ); } else { int contSize = nt->GetNodeSize(); //create matrices to call Enter continuous evidence floatVector val; val.resize(contSize); const Value* vFromEv = pEvidence->GetValue(curNum); for( int j = 0; j < contSize; j++ ) { val[j] = vFromEv[j].GetFlt(); } intVector dims; dims.assign( 2, 1 ); dims[0] = contSize; if( i == domSize - 1 ) { obsSelfVal = C2DNumericDenseMatrix<float>::Create( &dims.front(), &val.front()); } else { //store only parent indices obsGauIndex.push_back( i ); C2DNumericDenseMatrix<float>* obsGauVal = C2DNumericDenseMatrix<float>::Create( &dims.front(), &val.front() ); obsGauVals.push_back( obsGauVal ); } } } } // for( i = 0; i < domSize; i++ ) CModelDomain* pMD = GetModelDomain(); CPotential* resPot = NULL; int isLastNodeObs = pEvidence->IsNodeObserved(m_Domain[m_Domain.size()-1]); if( (obsDiscreteIndex.size() + obsGauIndex.size() == m_Domain.size()-1) && isLastNodeObs) { //result distribution is scalar obsDiscreteIndex.insert(obsDiscreteIndex.end(), obsGauIndex.begin(), obsGauIndex.end()); //child node is observed obsDiscreteIndex.insert(obsDiscreteIndex.end(), domSize-1); resPot = CScalarPotential::Create( m_Domain, GetModelDomain(), obsDiscreteIndex ); } else { const CNodeType* nt; //if all discrete nodes are observed then distribution will be Gaussian (Bader - comment) int allDiscrObs = 1; int allContObs = 1; int i; int isTab; int isCon; for( i = 0; i < domSize; i++ ) { int curNum = m_Domain[i]; nt = GetModelDomain()->GetVariableType( curNum ); isTab = nt->IsDiscrete(); isCon = !(isTab); if( isTab ) if( !(pEvidence->IsNodeObserved(curNum)) ) allDiscrObs = 0; if( isCon ) if( !(pEvidence->IsNodeObserved(curNum)) ) allContObs = 0; } if (allContObs && (!allDiscrObs) ) { CCondGaussianDistribFun* withDiscrEv = (static_cast<CCondGaussianDistribFun*>(m_CorrespDistribFun))-> EnterDiscreteEvidence(obsDiscreteIndex.size(), &obsDiscreteIndex.front(), &obsDiscrVals.front(), pMD->GetObsTabVarType() ); CTabularDistribFun* resDistr = withDiscrEv-> EnterFullContinuousEvidence( obsGauIndex.size(), &obsGauIndex.front(), obsSelfVal, &obsGauVals.front(), pMD->GetObsGauVarType() ); //need to unite gaussian and tabular observed index obsDiscreteIndex.insert(obsDiscreteIndex.end(), obsGauIndex.begin(), obsGauIndex.end()); //child node is observed obsDiscreteIndex.insert(obsDiscreteIndex.end(), domSize-1); resPot = CTabularPotential::Create( &m_Domain.front(), m_Domain.size(), GetModelDomain(), NULL, obsDiscreteIndex ); resPot->SetDistribFun( resDistr ); delete withDiscrEv; delete resDistr; } else { if (allDiscrObs && !allContObs) { intVector discParents; for ( i = 0; i < m_Domain.size(); i++) { nt = GetModelDomain()->GetVariableType( m_Domain[i] ); if (nt->IsDiscrete()) discParents.push_back(m_Domain[i]); } int *parentComb = new int [discParents.size()]; intVector pObsNodes; pConstValueVector pObsValues; pConstNodeTypeVector pNodeTypes; pEvidence->GetObsNodesWithValues(&pObsNodes, &pObsValues, &pNodeTypes); int j; int location; for ( j = 0; j < discParents.size(); j++) { location = std::find(pObsNodes.begin(), pObsNodes.end(), discParents[j]) - pObsNodes.begin(); parentComb[j] = pObsValues[location]->GetInt(); } const CGaussianDistribFun* resDistr = static_cast<CCondGaussianDistribFun*>(m_CorrespDistribFun)->GetDistribution(parentComb); CDistribFun* newResDistr = resDistr->ConvertCPDDistribFunToPot(); obsGauIndex.insert(obsGauIndex.end(), obsDiscreteIndex.begin(), obsDiscreteIndex.end()); intVector gauSubDomain; for( j = 0; j < m_Domain.size(); j++) { nt = GetModelDomain()->GetVariableType( m_Domain[j] ); if(!(nt->IsDiscrete())) gauSubDomain.push_back(m_Domain[j]); } resPot = CGaussianPotential::Create( &gauSubDomain.front(), gauSubDomain.size(), GetModelDomain()); resPot->SetDistribFun( newResDistr ); delete newResDistr; delete [] parentComb; } else { //can enter discrete evidence first if all continuous nodes observed //need to check if all them observed! CCondGaussianDistribFun* withDiscrEv = (static_cast<CCondGaussianDistribFun*>(m_CorrespDistribFun))-> EnterDiscreteEvidence(obsDiscreteIndex.size(), &obsDiscreteIndex.front(), &obsDiscrVals.front(), pMD->GetObsTabVarType() ); //need to enter continuous evidence CTabularDistribFun* resDistr = withDiscrEv-> EnterFullContinuousEvidence( obsGauIndex.size(), &obsGauIndex.front(), obsSelfVal, &obsGauVals.front(), pMD->GetObsGauVarType() ); //need to unite gaussian and tabular observed index obsDiscreteIndex.insert(obsDiscreteIndex.end(), obsGauIndex.begin(), obsGauIndex.end()); //child node is observed obsDiscreteIndex.insert(obsDiscreteIndex.end(), domSize-1); resPot = CTabularPotential::Create( &m_Domain.front(), m_Domain.size(), GetModelDomain(), NULL, obsDiscreteIndex ); resPot->SetDistribFun( resDistr ); delete withDiscrEv; delete resDistr; } } } delete obsSelfVal; for( i = 0; i < obsGauVals.size(); i++ ) { delete obsGauVals[i]; } return resPot; } }
//----------------------------------------------------------------------------- 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; } } }