void CGibbsSamplingInfEngine::SetQueries(intVecVector &queryes)
{
  int nQueryes = queryes.size();
  PNL_CHECK_LEFT_BORDER( nQueryes, 1 );
  
  int i;
  for( i = 0; i < m_queryFactors.size(); i++ )
  {
    delete m_queryFactors[i];
  }
  
  intVector tmp;
  for( i = 0; i < nQueryes; i++ )
  {
    PNL_CHECK_RANGES( queryes[i].size(), 1, m_pGraphicalModel->GetNumberOfNodes() );
    tmp = queryes[i];
    std::sort( tmp.begin(), tmp.end() );
    intVector::iterator it = std::unique( tmp.begin(), tmp.end() );
    tmp.erase( it, tmp.end() );
    if( tmp.size() != queryes[i].size() )
    {
      PNL_THROW(CAlgorithmicException, "equal nodes in qurey");
    }
    tmp.clear();
  }
  m_queryes = queryes;    
  
  
}
CMlStaticStructLearn::CMlStaticStructLearn(CStaticGraphicalModel *pGrModel,
        ELearningTypes LearnType,
        EOptimizeTypes AlgorithmType,
        EScoreFunTypes ScoreType, int nMaxFanIn,
        intVector& vAncestor, intVector& vDescent)
    :CStaticLearningEngine(pGrModel, LearnType),
     m_pResultBNet(NULL), m_pResultDAG(NULL)
{
    int nnodes = pGrModel->GetNumberOfNodes();
    m_nNodes = nnodes;
    int i;
    for (i = 0; i<nnodes; i++) m_vResultRenaming.push_back(i);

    m_ScoreType = ScoreType;
    m_Algorithm = AlgorithmType;
    m_nMaxFanIn = nMaxFanIn;
    m_ScoreMethod = MaxLh;
    m_priorType = Dirichlet;
    m_K2alfa = 0;
    m_vAncestor.assign(vAncestor.begin(), vAncestor.end());
    m_vDescent.assign(vDescent.begin(),vDescent.end());
    PNL_CHECK_RANGES(nMaxFanIn, 1, nnodes);
    intVector ranges(nMaxFanIn);
    for(i=0; i<nMaxFanIn; i++) ranges[i] = nnodes+1;
    float max = 0.0f;
    m_pNodeScoreCache =	(CSparseMatrix<float>**)malloc(nnodes * sizeof(CSparseMatrix<float>*));
    for(i=0; i<nnodes; i++)
    {
        m_pNodeScoreCache[i] = CSparseMatrix<float>::Create(nMaxFanIn,
                               &ranges.front(), max, 0);
    }
}
Beispiel #3
0
void CFactor::CreateAllNecessaryMatrices( int typeOfMatrices )
{
    PNL_CHECK_RANGES( typeOfMatrices, 1, 1 );
    //we have only one type of matrices now
    if( m_CorrespDistribFun->IsDistributionSpecific() == 1 )
    {
        PNL_THROW( CInconsistentType,
            "uniform distribution can't have any matrices with data" );
    }
    m_CorrespDistribFun->CreateDefaultMatrices(typeOfMatrices);
}
Beispiel #4
0
CGraph* CreateRandomGraphWithToyQMRSpecific(int num_nodes, 
    int num_indep_nodes, int max_size_family)
{
    PNL_CHECK_LEFT_BORDER( num_nodes, 10 );
    PNL_CHECK_RANGES( num_indep_nodes, 1, num_nodes-1 );
    PNL_CHECK_RANGES( max_size_family, 2, num_nodes );
    
    int i, j, k;
    
    CGraph *pGraph = CGraph::Create(0, NULL, NULL, NULL);
    PNL_CHECK_IF_MEMORY_ALLOCATED( pGraph );
    
    srand((unsigned int)time(NULL));

    pGraph->AddNodes(num_nodes);
    
    int num_parents;
    int ind_parent;
    intVector prev_nodes(0);
    for ( i = num_indep_nodes; i < num_nodes; i++)
    {
        prev_nodes.resize(0);
        for ( j = 0; j < num_indep_nodes; j++) 
            prev_nodes.push_back(j);

        num_parents = rand() % (max_size_family - 1);
        num_parents += 1;
        num_parents = (num_parents > i) ? i : num_parents;
    
        for ( j = 0; j < num_parents; j++)
        {
            ind_parent = rand() % prev_nodes.size();
            pGraph->AddEdge(prev_nodes[ind_parent], i, 1);
            prev_nodes.erase(prev_nodes.begin() + ind_parent);
        }
    }

    return pGraph;
}
int CMRF2::GetFactors( int numberOfNodes, const int *nodes,
                      pFactorVector *params ) const
{
    /* bad-args check */
    PNL_CHECK_RANGES( numberOfNodes, 1, 2 );
    PNL_CHECK_IS_NULL_POINTER(nodes);
    PNL_CHECK_IS_NULL_POINTER(params);
    /* bad-args check end */
    
    params->clear();
    
    int       numOfClqsFrstNode;
    const int *clqsFrstNode;
    
    GetClqsNumsForNode( *nodes, &numOfClqsFrstNode, &clqsFrstNode );
    
    if( numberOfNodes == 1 )
    {
        const int *clqsIt = clqsFrstNode,
            *clqs_end = clqsFrstNode + numOfClqsFrstNode;
        
        for( ; clqs_end - clqsIt; ++clqsIt )
        {
            params->push_back(GetFactor(*clqsIt));
        }
    }
    else
    {
        int       numOfClqsScndNode;
        const int *clqsScndNode;
        
        GetClqsNumsForNode( *(nodes + 1), &numOfClqsScndNode, &clqsScndNode );
        
        const int *pClqNum = std::find_first_of( clqsFrstNode,
            clqsFrstNode + numOfClqsFrstNode, clqsScndNode,
            clqsScndNode + numOfClqsScndNode );
        
        if( pClqNum == clqsFrstNode + numOfClqsFrstNode )
        {
            return 0;
        }
        
        params->push_back(GetFactor(*pClqNum));
    }
    
    assert( params->size() != 0 );
    
    return 1;
}
void CJtreeInfEngine::EnterEvidence( const CEvidence *pEvidence,
				    int maximize, int sumOnMixtureNode )
{

    // bad-args check
    PNL_CHECK_IS_NULL_POINTER(pEvidence);
    PNL_CHECK_RANGES( maximize, 0, 2 );

    if( pEvidence->GetModelDomain() != m_pGraphicalModel->GetModelDomain() )
    {
	PNL_THROW( CInvalidOperation, 
	    "evidence and the Graphical Model must be on one Model Domain" );
    }
    // bad-args check end
    int i;

    ShrinkObserved( pEvidence, maximize, sumOnMixtureNode );

    CollectEvidence();

    DistributeEvidence();

	for (i = 0; i < m_pJTree->GetNumberOfNodes(); i++)
	{
		EDistributionType dt = m_pJTree->GetNodePotential(i)->GetDistribFun()->
			GetDistributionType();
		if(dt == dtGaussian)
		{
			static_cast<CGaussianDistribFun*>(m_pJTree->GetNodePotential(i)->
				GetDistribFun())->UpdateCanonicalCoefficient();
		}
	}

    if (GetModel()->GetModelType() == mtBNet)
    {
        for (i = 0; i < GetModel()->GetNumberOfNodes(); i++)
        {
            if (GetModel()->GetFactor(i)->GetDistributionType() == dtSoftMax)
            {
                GetModel()->GetModelDomain()->ChangeNodeType(i, 0);
            }
        }
    }

}
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 );
}
float CMlStaticStructLearn::ScoreFamily(intVector vFamily)
{
    int nParents = vFamily.size() - 1;
    PNL_CHECK_RANGES(nParents, 0, m_nMaxFanIn);
    intVector indexes(m_nMaxFanIn,0);
    int i;
    for(i=0; i<nParents; i++)
    {
        indexes[i] = vFamily[i]+1;
    }
    int node = vFamily[nParents];
    float score;
    float defval = m_pNodeScoreCache[node]->GetDefaultValue();
    score = m_pNodeScoreCache[node]->GetElementByIndexes(&indexes.front());
    if(score == defval)
    {
        score = ComputeFamilyScore(vFamily);
        m_pNodeScoreCache[node]->SetElementByIndexes(score, &indexes.front());
    }
    return score;
}
CMNet* CMNet::Create( int numberOfNodes, int numberOfNodeTypes,
		     const CNodeType *nodeTypes, const int *nodeAssociation,
		     int numberOfCliques, const int *cliqueSizes,
		     const int **cliques )
{
    /* bad-args check */
    PNL_CHECK_LEFT_BORDER( numberOfNodes, 1 );
    PNL_CHECK_RANGES( numberOfNodeTypes, 1, numberOfNodes );
    PNL_CHECK_IS_NULL_POINTER(nodeTypes);
    PNL_CHECK_IS_NULL_POINTER(nodeAssociation);
    PNL_CHECK_LEFT_BORDER( numberOfCliques, 1 );
    PNL_CHECK_IS_NULL_POINTER(cliqueSizes);
    PNL_CHECK_IS_NULL_POINTER(cliques);
    /* bad-args check end */

    /* creating the model */
    CMNet *pMNet = new CMNet( numberOfNodes, numberOfNodeTypes,
	nodeTypes, nodeAssociation, numberOfCliques, cliqueSizes, cliques );

    PNL_CHECK_IF_MEMORY_ALLOCATED(pMNet);

    return pMNet;
}
void CBKInfEngine::
MarginalNodes( const int *query, int querySize, int slice, int notExpandJPD )
{
    /////////////////////////////////////////////////////////////////////////
    if( GetProcedureType() == ptFiltering )
    {
	PNL_CHECK_LEFT_BORDER(m_CRingpEv.size(), 1);
    }
    else
    {
	PNL_CHECK_LEFT_BORDER(m_CRingpEv.size() , m_CRingJtreeInf.size());
    }
   
    /////////////////////////////////////////////////////////////////////////
    
    if( GetEvidenceMPE() )
    {
	delete GetEvidenceMPE();
	SetEvidenceMPE(NULL);
    }
    if( GetQueryPot() )
    {
	delete GetQueryPot();
	SetQueryPot(NULL);
    }
    
   
    SetQueryNodes(querySize, query);
    intVector queryVec;
    queryVec.assign(query, query + querySize);
    
    intVector finalQuery;

    switch( m_ProcedureType )
    {
    case ptFiltering:
	{
	    FindFinalQuery( queryVec, m_CurrentTime  - 1, &finalQuery);
	    m_QuerryJTree  =  m_CRingJtreeInf[m_CurrentTime  - 1];
	    m_QuerryJTree->MarginalNodes( &finalQuery.front(), querySize, notExpandJPD );
	    break;
	}
    case ptFixLagSmoothing:
	{
	    FindFinalQuery( queryVec, m_CurrentTime - m_Lag - 1, &finalQuery);
	    m_QuerryJTree = m_CRingJtreeInf[m_CurrentTime - m_Lag - 1];
	    m_QuerryJTree->MarginalNodes( &finalQuery.front(), querySize, notExpandJPD );
	    break;
	}
    case ptSmoothing:
    case ptViterbi:
	{
	    PNL_CHECK_RANGES(slice, 0, m_Lag);
	    
	    FindFinalQuery( queryVec, slice, &finalQuery);
	    m_QuerryJTree = m_CRingJtreeInf[slice];
	    m_QuerryJTree->MarginalNodes( &finalQuery.front(), querySize, notExpandJPD );
	    break;
	}
    }
}
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;
    }
}
void CJtreeInfEngine::ShrinkObserved( const CEvidence *pEvidence, 
				     int maximize, int sumOnMixtureNode,
				     bool bRebuildJTree )
{
    // bad-args check
    PNL_CHECK_IS_NULL_POINTER(pEvidence);
    PNL_CHECK_RANGES( maximize, 0, 2 );
    // bad-args check end

    m_norm = -1;
    m_pEvidence = pEvidence;
    m_bMaximize = maximize;

    // deletes an old internal junction tree to start computations anew
    m_pOriginalJTree->ClearCharge();
    m_pOriginalJTree->InitCharge( m_pGraphicalModel, pEvidence,
	sumOnMixtureNode );

    m_pJTree = m_pOriginalJTree;

    pConstValueVector allOffsets;

    m_pEvidence->GetObsNodesWithValues( &m_actuallyObsNodes, &allOffsets );

    /*    
    const int numOfNodesInGraph = m_pGraphicalModel->GetNumberOfNodes();
    const int numOfClqs         = m_pJTree->GetNumberOfNodes();

    const int numOfObsNodes          = m_pEvidence->GetNumberObsNodes();
    const int *obsNodes              = m_pEvidence->GetAllObsNodes();
    const int *actuallyObsNodesFlags = m_pEvidence->GetObsNodesFlags();
    const int *pOffset               = m_pEvidence->GetOffset();
    const unsigned char *evidData    = m_pEvidence->GetRawData();

    pnlVector< const unsigned char* > allOffsets( numOfNodesInGraph, NULL );

    int i;

    for( i = 0; i < numOfObsNodes; ++i )
    {
    if( actuallyObsNodesFlags[i] )
    {
    m_actuallyObsNodes.push_back(obsNodes[i]);
    allOffsets[obsNodes[i]] = evidData + pOffset[i];
    }
    }

    const int *clqIt, *clq_end;
    const int *nbrIt, *nbrs_end;
    const int *sepDomIt, *sepDom_end;

    intVector obsNodesInClq;
    intVector obsNodesInSep;

    obsNodesInClq.reserve(numOfObsNodes);
    obsNodesInSep.reserve(numOfObsNodes);

    // shrink node pots and separator pots based on the observed info
    for( i = 0; i < numOfClqs; ++i )
    {
    int       numOfNdsInClq;
    const int *clique;

    m_pJTree->GetNodeContent( i, &numOfNdsInClq, &clique );

    for( clqIt = clique, clq_end = clique + numOfNdsInClq;
    clqIt != clq_end; ++clqIt )
    {
    if( std::find( m_actuallyObsNodes.begin(),
    m_actuallyObsNodes.end(), *clqIt )
    != m_actuallyObsNodes.end() )
    {
    obsNodesInClq.push_back(*clqIt);
    }
    }

    if( !obsNodesInClq.empty() )
    {
    // here is a line, why it all should not work for a cond gaussian
    const CNodeType *pObsNodeNT = 
    m_pJTree->GetNodeType(i)->IsDiscrete()
    ? &m_ObsNodeType : &m_ObsGaussType;

    const CPotential *pShrPot = m_pJTree->GetNodePotential(i)
    ->ShrinkObservedNodes( obsNodesInClq.size(),
    obsNodesInClq.begin(), allOffsets.begin(), pObsNodeNT );

    // this should be changed to perform a safe operation
    m_pJTree->GetNodePotential(i)->SetDistribFun(
    pShrPot->GetDistribFun());

    delete pShrPot;

    // when done shrinking node pots, we go on with separator pots
    int                 numOfNbrs;
    const int           *nbrs;
    const ENeighborType *nbrsTypes;

    m_pJTree->GetGraph()->GetNeighbors( i, &numOfNbrs, &nbrs,
    &nbrsTypes );

    for( nbrIt = nbrs, nbrs_end = nbrs + numOfNbrs; nbrIt != nbrs_end;
    ++nbrIt )
    {
    if( *nbrIt > i )
    {
    int       sepDomSz;
    const int *sepDomain;

    m_pJTree->GetSeparatorDomain( i, *nbrIt, &sepDomSz,
    &sepDomain );

    for( sepDomIt = sepDomain, sepDom_end = sepDomain
    + sepDomSz; sepDomIt != sepDom_end; ++sepDomIt )
    {
    if( std::find( obsNodesInClq.begin(),
    obsNodesInClq.end(), *sepDomIt )
    != obsNodesInClq.end() )
    {
    obsNodesInSep.push_back(*sepDomIt);
    }
    }

    if( !obsNodesInSep.empty() )
    {
    pShrPot = m_pJTree->GetSeparatorPotential(i, *nbrIt)
    ->ShrinkObservedNodes( obsNodesInSep.size(),
    obsNodesInSep.begin(), allOffsets.begin(),
    pObsNodeNT );

    m_pJTree->GetSeparatorPotential(i, *nbrIt)
    ->SetDistribFun(pShrPot->GetDistribFun());

    delete pShrPot;
    }

    obsNodesInSep.clear();
    }
    }

    obsNodesInClq.clear();
    }
    }
    */
    m_lastOpDone = opsShrinkEv;
}
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;
}
Beispiel #15
0
CGraph* CreateRandomAndSpecificForIDNetGraph(int num_nodes,
  int num_indep_nodes, int max_size_family)
{
  PNL_CHECK_LEFT_BORDER(num_nodes, 10);
  PNL_CHECK_RANGES(num_indep_nodes, 1, num_nodes-1);
  PNL_CHECK_RANGES(max_size_family, 2, num_nodes);
  
  int i, j, k;
  
  CGraph *pGraph = CGraph::Create(0, NULL, NULL, NULL);
  PNL_CHECK_IF_MEMORY_ALLOCATED(pGraph);
  
  srand((unsigned int)time(NULL));
  
  pGraph->AddNodes(num_nodes);
  
  int num_parents;
  int ind_parent;
  intVector prev_nodes(0);
  for (i = num_indep_nodes; i < num_nodes; i++)
  {
    prev_nodes.resize(0);
    for (j = 0; j < i; j++)
      prev_nodes.push_back(j);
    
    num_parents = rand() % (max_size_family - 1);
    num_parents += 1;
    num_parents = (num_parents > i) ? i : num_parents;
    
    for (j = 0; j < num_parents; j++)
    {
      ind_parent = rand() % prev_nodes.size();
      pGraph->AddEdge(prev_nodes[ind_parent], i, 1);
      prev_nodes.erase(prev_nodes.begin() + ind_parent);
    }
  }
  
  intVector parents(0);
  intVector childs(0);
  for (i = 0; i < num_nodes; i++)
  {
    if (pGraph->GetNumberOfChildren(i) == 0)
    {
      pGraph->GetParents(i, &parents);
      for (j = 0; j < parents.size(); j++)
      {
        pGraph->GetChildren(parents[j], &childs);
        for (k = 0; k < childs.size(); k++)
          if ((childs[k] != i) && 
            (pGraph->GetNumberOfChildren(childs[k]) == 0) &&
            (pGraph->GetNumberOfParents(childs[k]) == 1))
          {
            if (i < childs[k])
            {
              pGraph->RemoveEdge(parents[j], childs[k]);
              pGraph->AddEdge(i, childs[k], 1);
            }
            else
            {
              pGraph->AddEdge(childs[k], i, 1);
            }
          }
      }
    }
  }
  
  return pGraph;
}
Beispiel #16
0
CIDNet* CreateRandomIDNet(int num_nodes, int num_indep_nodes,
  int max_size_family, int num_decision_nodes, int max_num_states_chance_nodes,
  int max_num_states_decision_nodes, int min_utility, int max_utility,
  bool is_uniform_start_policy)
{
  PNL_CHECK_RANGES(num_decision_nodes, 1, num_nodes-1);
  PNL_CHECK_LEFT_BORDER(max_num_states_chance_nodes, 1);
  PNL_CHECK_LEFT_BORDER(max_num_states_decision_nodes, 1);
  PNL_CHECK_LEFT_BORDER(max_utility, min_utility);
  
  CGraph* pGraph = 
    CreateRandomAndSpecificForIDNetGraph(num_nodes, num_indep_nodes,
    max_size_family);
  
  if (!pGraph->IsDAG())
  {
    PNL_THROW(CInconsistentType, " the graph should be a DAG ");
  }
  
  if (!pGraph->IsTopologicallySorted())
  {
    PNL_THROW(CInconsistentType, 
      " the graph should be sorted topologically ");
  }
  if (pGraph->NumberOfConnectivityComponents() > 1)
  {
    PNL_THROW(CInconsistentType, " the graph should be linked ");
  }
  
  int i, j, k;
  
  CNodeType *nodeTypes = new CNodeType [num_nodes];
  
  intVector nonValueNodes(0);
  intVector posibleDecisionNodes(0);
  nonValueNodes.resize(0);
  posibleDecisionNodes.resize(0);
  for (i = 0; i < num_nodes; i++)
  {
    if (pGraph->GetNumberOfChildren(i) == 0)
    {
      nodeTypes[i].SetType(1, 1, nsValue);
    }
    else
    {
      nonValueNodes.push_back(i);
      posibleDecisionNodes.push_back(i);
    }
  }
  int ind_decision_node;
  int num_states;
  int index;
  int node;
  intVector neighbors(0);
  neighborTypeVector neigh_types(0);

  num_decision_nodes = (num_decision_nodes > posibleDecisionNodes.size()) ? 
    posibleDecisionNodes.size() : num_decision_nodes;
  for (i = 0; (i < num_decision_nodes) && (posibleDecisionNodes.size()>0); i++)
  {
    ind_decision_node = rand() % posibleDecisionNodes.size();
    node = posibleDecisionNodes[ind_decision_node];
    num_states = GetRandomNumberOfStates(max_num_states_decision_nodes);
    nodeTypes[node].SetType(1, num_states, nsDecision);
    
    index = -1;
    for (j = 0; j < nonValueNodes.size(); j++)
    {
      if (nonValueNodes[j] == node)
      {
        index = j;
        break;
      }
    }
    if (index != -1)
      nonValueNodes.erase(nonValueNodes.begin() + index);
      
    posibleDecisionNodes.erase(posibleDecisionNodes.begin() + 
      ind_decision_node);
    pGraph->GetNeighbors(node, &neighbors, &neigh_types);
    for (j = 0; j < neighbors.size(); j++)
    {
      index = -1;
      for (k = 0; k < posibleDecisionNodes.size(); k++)
      {
        if (neighbors[j] == posibleDecisionNodes[k])
        {
          index = k;
          break;
        }
      }
      if (index != -1)
        posibleDecisionNodes.erase(posibleDecisionNodes.begin() + index);
    }
  }
  for (i = 0; i < nonValueNodes.size(); i++)
  {
    num_states = GetRandomNumberOfStates(max_num_states_chance_nodes);
    nodeTypes[nonValueNodes[i]].SetType(1, num_states, nsChance);
  }
  
  int *nodeAssociation = new int[num_nodes];
  for (i = 0; i < num_nodes; i++)
  {
    nodeAssociation[i] = i;
  }
  
  CIDNet *pIDNet = CIDNet::Create(num_nodes, num_nodes, nodeTypes,
    nodeAssociation, pGraph);
  pGraph = pIDNet->GetGraph();
  CModelDomain* pMD = pIDNet->GetModelDomain();
  
  CFactor **myParams = new CFactor*[num_nodes];
  int *nodeNumbers = new int[num_nodes];
  int **domains = new int*[num_nodes];
  
  intVector parents(0);
  for (i = 0; i < num_nodes; i++)
  {
    nodeNumbers[i] = pGraph->GetNumberOfParents(i) + 1;
    domains[i] = new int[nodeNumbers[i]];
    pGraph->GetParents(i, &parents);
    
    for (j = 0; j < parents.size(); j++)
    {
      domains[i][j] = parents[j];
    }
    domains[i][nodeNumbers[i]-1] = i;
  }
  
  pIDNet->AllocFactors();
  
  for (i = 0; i < num_nodes; i++)
  {
    myParams[i] = CTabularCPD::Create(domains[i], nodeNumbers[i], pMD);
  }
  
  float **data = new float*[num_nodes];
  int size_data;
  int num_states_node;
  int num_blocks;
  intVector size_nodes(0);
  float belief, sum_beliefs;
  
  for (i = 0; i < num_nodes; i++)
  {
    size_data = 1;
    size_nodes.resize(0);
    for (j = 0; j < nodeNumbers[i]; j++)
    {
      size_nodes.push_back(pIDNet->GetNodeType(domains[i][j])->GetNodeSize());
      size_data *= size_nodes[j];
    }
    num_states_node = size_nodes[size_nodes.size() - 1];
    num_blocks = size_data / num_states_node;
    
    data[i] = new float[size_data];
    switch (pIDNet->GetNodeType(i)->GetNodeState())
    {
      case nsChance:
      {
        for (j = 0; j < num_blocks; j++)
        {
          sum_beliefs = 0.0;
          for (k = 0; k < num_states_node - 1; k++)
          {
            belief = GetBelief(1.0f - sum_beliefs);
            data[i][j * num_states_node + k] = belief;
            sum_beliefs += belief;
          }
          belief = 1.0f - sum_beliefs;
          data[i][j * num_states_node + num_states_node - 1] = belief;
        }
        break;
      }
      case nsDecision:
      {
        if (is_uniform_start_policy)
        {
          belief = 1.0f / float(num_states_node);
          for (j = 0; j < num_blocks; j++)
          {
            sum_beliefs = 0.0;
            for (k = 0; k < num_states_node - 1; k++)
            {
              data[i][j * num_states_node + k] = belief;
              sum_beliefs += belief;
            }
            data[i][j * num_states_node + num_states_node - 1] = 
              1.0f - sum_beliefs;
          }
        }
        else
        {
          for (j = 0; j < num_blocks; j++)
          {
            sum_beliefs = 0.0;
            for (k = 0; k < num_states_node - 1; k++)
            {
              belief = GetBelief(1.0f - sum_beliefs);
              data[i][j * num_states_node + k] = belief;
              sum_beliefs += belief;
            }
            belief = 1.0f - sum_beliefs;
            data[i][j * num_states_node + num_states_node - 1] = belief;
          }
        }
        break;
      }
      case nsValue:
      {
        for (j = 0; j < num_blocks; j++)
        {
          data[i][j] = float(GetUtility(min_utility, max_utility));
        }
        break;
      }
    }
  }

  for (i = 0; i < num_nodes; i++)
  {
    myParams[i]->AllocMatrix(data[i], matTable);
    pIDNet->AttachFactor(myParams[i]);
  }

  delete [] nodeTypes;
  delete [] nodeAssociation;

  return pIDNet;
}
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;
}