Exemple #1
0
CFactorGraph CompressInterface::createCFactorGraph() {

	createVarClustering();
	createFacClustering();

	// create lifted fg here
	vector<CFactor> superFacs;

	// clusterIdx => facIdx
	for (map<size_t,size_t>::iterator facIter = _facRepr.begin(); facIter != _facRepr.end(); facIter++) {
		VarSet superVarSet;

		foreach (const dai::BipartiteGraph::Neighbor &tmpVar, _cfg.nbF(facIter->second)) {
			Var varCluster = _varRepr[_varColorVec[tmpVar]];
			if (!superVarSet.contains(varCluster)) {
				superVarSet |= Var(varCluster);
			}
		}

		CFactor superFac = CFactor(superVarSet, _cfg.factor(facIter->second).p());
		superFac.sigma() = _cfg.factor(facIter->second).sigma();
		superFac.position() = _cfg.factor(facIter->second).position();

		superFac.counts() = createCounts(facIter->second, superVarSet);
		superFacs.push_back(superFac);
	}

	return CFactorGraph(superFacs);
}
void CLWSamplingInfEngine::
EnterEvidence( const CEvidence *pEvidenceIn , int maximize , int sumOnMixtureNode  )
{
    PNL_CHECK_IS_NULL_POINTER(pEvidenceIn);
  
    LWSampling(pEvidenceIn);

	// Given evidencs, calculate particle weight by CPD 
	float w;
	int iSampleSize = m_currentEvVec.size();
	const int* ObsNodes = pEvidenceIn->GetAllObsNodes();
	int NumberObsNodes  = pEvidenceIn->GetNumberObsNodes();

	int i, j;

	for( i = 0; i < iSampleSize; i++)
	{
		w = 0;
		for( j = 0; j < NumberObsNodes; j++)
		{
			if(pEvidenceIn->IsNodeObserved(ObsNodes[j]))
			{
				CFactor* pFactor = m_pGraphicalModel->GetFactor(ObsNodes[j]);
		 		w = w +  pFactor->GetLogLik( m_currentEvVec[i]); 
			}
		}

		m_particleWeight[i] = (float)exp(w);
	}

	NormalizeWeight();
}
Exemple #3
0
void CFactorGraph::compute_energies() 
{
	for (int32_t fi = 0; fi < m_factors->get_num_elements(); ++fi)
	{
		CFactor* fac = dynamic_cast<CFactor*>(m_factors->get_element(fi));
		fac->compute_energies();
		SG_UNREF(fac);
	}
}
void CFactorGraph::loss_augmentation(SGVector<int32_t> states_gt, SGVector<float64_t> loss)
{
	if (loss.size() == 0)
	{
		loss.resize_vector(states_gt.size());
		SGVector<float64_t>::fill_vector(loss.vector, loss.vlen, 1.0 / states_gt.size());
	}

	int32_t num_vars = states_gt.size();
	ASSERT(num_vars == loss.size());

	SGVector<int32_t> var_flags(num_vars);
	var_flags.zero();

	// augment loss to incorrect states in the first factor containing the variable
	// since += L_i for each variable if it takes wrong state ever
	// TODO: augment unary factors
	for (int32_t fi = 0; fi < m_factors->get_num_elements(); ++fi)
	{
		CFactor* fac = dynamic_cast<CFactor*>(m_factors->get_element(fi));
		SGVector<int32_t> vars = fac->get_variables();
		for (int32_t vi = 0; vi < vars.size(); vi++)
		{
			int32_t vv = vars[vi];
			ASSERT(vv < num_vars);
			if (var_flags[vv])
				continue;

			SGVector<float64_t> energies = fac->get_energies();
			for (int32_t ei = 0; ei < energies.size(); ei++)
			{
				CTableFactorType* ftype = fac->get_factor_type();
				int32_t vstate = ftype->state_from_index(ei, vi);
				SG_UNREF(ftype);

				if (states_gt[vv] == vstate)
					continue;

				// -delta(y_n, y_i_n)
				fac->set_energy(ei, energies[ei] - loss[vv]);
			}

			var_flags[vv] = 1;
		}

		SG_UNREF(fac);
	}

	// make sure all variables have been checked
	int32_t min_var = SGVector<int32_t>::min(var_flags.vector, var_flags.vlen);
	ASSERT(min_var == 1);
}
Exemple #5
0
float64_t CFactorGraph::evaluate_energy(const SGVector<int32_t> state) const
{
	ASSERT(state.size() == m_cardinalities.size());

	float64_t energy = 0.0;
	for (int32_t fi = 0; fi < m_factors->get_num_elements(); ++fi)
	{
		CFactor* fac = dynamic_cast<CFactor*>(m_factors->get_element(fi));
		energy += fac->evaluate_energy(state);
		SG_UNREF(fac);
	}
	return energy;
}
Exemple #6
0
void CompressInterface::rearrangeCnfFactor(CFactor &cnfClause) {
	State state(cnfClause.vars());
	vector<size_t> (cnfClause.vars().size());
	vector<size_t> pos,neg,sigma;
	for (size_t i=0; i<cnfClause.states(); i++) {
		if (cnfClause[i] == 1) {
			for (vector<Var>::const_iterator varIter=cnfClause.vars().begin(); varIter!=cnfClause.vars().end();varIter++) {
				if (state(*varIter) == 0) {
					pos.push_back(varIter - cnfClause.vars().begin());
				} else {
					neg.push_back(varIter - cnfClause.vars().begin());
				}
			}
			break;
		} else if (cnfClause[i] == 0) {
			//TODO handle factors which contain zero states
			// in such cases the possible zero state could have been clamped;
			// possible solutions:
			// i) restore factor from backup (requires to clamp factors accordingly)
			// ii) cache zero states in advance
			return;
		}
		state++;
	}
	sigma.insert(sigma.begin(),pos.begin(), pos.end());
	sigma.insert(sigma.begin() + pos.size(),neg.begin(), neg.end());
	cnfClause.sigma() = sigma;
}
void CBayesLearningEngine::Learn()
{
    if(!m_pGrModel)
    {
        PNL_THROW( CNULLPointer, "no graphical model")
    }
    CStaticGraphicalModel *grmodel = this->GetStaticModel();
    CFactor *factor = NULL;
    int numberOfFactors = grmodel->GetNumberOfFactors();
    int domainNodes;
    
    if(m_numberOfLearnedEvidences == m_numberOfAllEvidences)
    {
        PNL_THROW(COutOfRange, "number of unlearned evidences must be positive")
    }
    int currentEvidNumber;
    const CEvidence* pCurrentEvid;
    
    //below code is intended to work on tabular CPD and gaussian CPD
    //later we will generalize it for other distribution types
    if ((grmodel->GetFactor(0))->GetDistributionType() == dtTabular)
    {
        for( int ev = m_numberOfLearnedEvidences; ev < m_numberOfAllEvidences; ev++)
        {
            currentEvidNumber = ev;
            pCurrentEvid = m_Vector_pEvidences[currentEvidNumber];
        
            if( !pCurrentEvid)
            {
                PNL_THROW(CNULLPointer, "evidence")
            }
        
            for( domainNodes = 0; domainNodes < numberOfFactors; domainNodes++ )
            {
                factor = grmodel->GetFactor( domainNodes );
                int DomainSize;
                const int *domain;
                factor->GetDomain( &DomainSize, &domain );
                const CEvidence *pEvidences[] = { pCurrentEvid };
                CTabularDistribFun* pDistribFun = (CTabularDistribFun*)(factor->GetDistribFun());
                pDistribFun->BayesUpdateFactor(pEvidences, 1, domain);
            }
        }
    }
    else 
    {
        for( domainNodes = 0; domainNodes < numberOfFactors; domainNodes++ )
SGVector< float64_t > CFactorGraphModel::get_joint_feature_vector(int32_t feat_idx, CStructuredData* y)
{
	// factor graph instance
	CFactorGraphFeatures* mf = CFactorGraphFeatures::obtain_from_generic(m_features);
	CFactorGraph* fg = mf->get_sample(feat_idx);

	// ground truth states
	CFactorGraphObservation* fg_states = CFactorGraphObservation::obtain_from_generic(y);
	SGVector<int32_t> states = fg_states->get_data();

	// initialize psi
	SGVector<float64_t> psi(get_dim());
	psi.zero();

	// construct unnormalized psi
	CDynamicObjectArray* facs = fg->get_factors();
	for (int32_t fi = 0; fi < facs->get_num_elements(); ++fi)
	{
		CFactor* fac = dynamic_cast<CFactor*>(facs->get_element(fi));
		CTableFactorType* ftype = fac->get_factor_type();
		int32_t id = ftype->get_type_id();
		SGVector<int32_t> w_map = get_params_mapping(id);

		ASSERT(w_map.size() == ftype->get_w_dim());

		SGVector<float64_t> dat = fac->get_data();
		int32_t dat_size = dat.size();

		ASSERT(w_map.size() == dat_size * ftype->get_num_assignments());

		int32_t ei = ftype->index_from_universe_assignment(states, fac->get_variables());
		for (int32_t di = 0; di < dat_size; di++)
			psi[w_map[ei*dat_size + di]] += dat[di];

		SG_UNREF(ftype);
		SG_UNREF(fac);
	}

	// negation (-E(x,y) = <w,phi(x,y)>)
	psi.scale(-1.0);

	SG_UNREF(facs);
	SG_UNREF(fg);

	return psi;
}
CMNet* CMNet::CreateWithRandomMatrices( const intVecVector& clqs,
                                            CModelDomain* pMD)
{
    CMNet* pMNet = CMNet::Create( clqs, pMD );

    pMNet->AllocFactors();
    int numFactors = pMNet->GetNumberOfFactors();
    int i;
    for( i = 0; i < numFactors; i++ )
    {
        pMNet->AllocFactor( i );
        CFactor* ft = pMNet->GetFactor(i);
        ft->CreateAllNecessaryMatrices();
    }
    
    return pMNet;
}
Exemple #10
0
void cfactor_setitem(CFactor& factor, size_t index, double value)
{
	if (index >= 0 && index < factor.states()) {
		factor[index] = value;
	}
	else {
		PyErr_SetString(PyExc_IndexError, "index out of range");
		boost::python::throw_error_already_set();
	}
}
//create mnet with random matrices
CMRF2* CMRF2::CreateWithRandomMatrices( int numberOfCliques,
                                       const int *cliqueSizes,
                                       const int **cliques,
                                       CModelDomain* pMD)
{
    CMRF2* pMRF2 = CMRF2::Create( numberOfCliques, cliqueSizes, cliques, pMD );
    
    pMRF2->AllocFactors();
    int numFactors = pMRF2->GetNumberOfFactors();
    int i;
    for( i = 0; i < numFactors; i++ )
    {
        pMRF2->AllocFactor( i );
        CFactor* ft = pMRF2->GetFactor(i);
        ft->CreateAllNecessaryMatrices();
    }
    
    return pMRF2;
}
void CMlLearningEngine::Learn()
{
/*
function takes an information from m_pEvidences and learns factors
of graphical model using prior probabilities or not
    */
    float logLikTmp = 0;
    if(!m_pGrModel)
    {
        PNL_THROW( CNULLPointer, "no graphical model")
    }
    CStaticGraphicalModel *grmodel = this->GetStaticModel();
    CFactor *parameter = NULL;
    int numberOfDomains = grmodel -> GetNumberOfFactors();
    
    for( int domainNodes = 0; domainNodes < numberOfDomains; domainNodes++ )
    {
        factor = grmodel->GetFactor( domainNodes );
        factor ->UpdateStatisticsML( &m_Vector_pEvidences.front(), 
            m_Vector_pEvidences.size() );
        PNL_CHECK_LEFT_BORDER(m_numberOfAllEvidences, 1);
        logLikTmp += parameter->ProcessingStatisticalData(m_numberOfAllEvidences);
    }
    switch( grmodel -> GetModelType() )
    {
    case mtBNet:
        {
            break;
        }
    case mtMRF2:
    case mtMNet:
        {
            logLikTmp = _LearnPotentials();
            break;
        }
    default:
        {
            PNL_THROW(CBadConst, "model type" )
                break;
        }
    }
    m_critValue.push_back(logLikTmp);
}
Exemple #13
0
double cfactor_getitem(CFactor &factor, size_t index)
{
	if (index >= 0 && index < factor.states()) {
		return factor[index];
	}
	else {
		PyErr_SetString(PyExc_IndexError, "index out of range");
		boost::python::throw_error_already_set();
		return -1;
	}
}
CCPD* CStaticStructLearnSEM::CreateRandomCPD(int nfamily, const int* family, CBNet* pBNet)
{
	int child = family[nfamily-1];
	CModelDomain* pMD = pBNet->GetModelDomain();
	CFactor* factor = pBNet->GetFactor(child);
	EDistributionType dt = factor->GetDistributionType();
	CCPD* pCPD;

	if( dt == dtTabular )
	{
		pCPD = CTabularCPD::Create(family, nfamily, pMD);
		pCPD->CreateAllNecessaryMatrices(1);
		return pCPD;
	}
	else
	{
		if( dt == dtMixGaussian )
		{
			floatVector data;
			static_cast<CMixtureGaussianCPD*>(factor)->GetProbabilities(&data);
			pCPD = CMixtureGaussianCPD::Create(family, nfamily, pMD, &data.front());
			static_cast<CCondGaussianDistribFun*>(pCPD->GetDistribFun()) -> CreateDefaultMatrices(1);
			return pCPD;
		}
		else
		{
			if( (dt == dtGaussian) || (dt == dtCondGaussian) )
			{
				pCPD = CGaussianCPD::Create(family, nfamily, pMD);
				pCPD->CreateAllNecessaryMatrices(1);
				return pCPD;
			}
			else
				PNL_THROW(CNotImplemented, "this type of distribution is not supported yet");
		}				
	}
}
Exemple #15
0
void CFactorGraph::connect_components()
{
	if (m_dset->get_connected())
		return;

	// need to be reset once factor graph is updated
	m_dset->make_sets();
	bool flag = false;

	for (int32_t fi = 0; fi < m_factors->get_num_elements(); ++fi)
	{
		CFactor* fac = dynamic_cast<CFactor*>(m_factors->get_element(fi));
		SGVector<int32_t> vars = fac->get_variables();

		int32_t r0 = m_dset->find_set(vars[0]);
		for (int32_t vi = 1; vi < vars.size(); vi++)
		{
			// for two nodes in a factor, should be an edge between them
			// but this time link() isn't performed, if they are linked already
			// means there is another path connected them, so cycle detected
			int32_t ri = m_dset->find_set(vars[vi]);	

			if (r0 == ri)
			{
				flag = true;	
				continue;
			}

			r0 = m_dset->link_set(r0, ri);
		}

		SG_UNREF(fac);
	}
	m_has_cycle = flag;
	m_dset->set_connected(true);
}
void CParEMLearningEngine::LearnOMP()
{
    CStaticGraphicalModel *pGrModel =  this->GetStaticModel();
    PNL_CHECK_IS_NULL_POINTER(pGrModel);
    PNL_CHECK_LEFT_BORDER(GetNumEv() - GetNumberProcEv() , 1);

    //omp_set_num_threads(2);
    int numberOfThreads = omp_get_num_procs();
    //CParPearlInfEngine **pCurrentInfEng = new CParPearlInfEngine*[numberOfThreads];
    CJtreeInfEngine **pCurrentInfEng = new CJtreeInfEngine*[numberOfThreads];
    for (int i = 0; i < numberOfThreads; i++)
        pCurrentInfEng[i] = NULL;
    CFactor *parameter1 = NULL;

    int exit = 0;
    int numberOfParameters = pGrModel->GetNumberOfParameters();
    int domainNodes;
    //int itsML = 0;

    // !!!
    float loglik = -FLT_MAX;
    float loglikOld = -FLT_MAX;
    float epsilon = GetPrecisionEM();
    float stopExpression = epsilon + 1.0f;
    int iteration = 0;

    int ev;

    // to create additional factors
    CFactor **ppAllFactors = new CFactor*[numberOfParameters*numberOfThreads];
    bool *was_updated = new bool[numberOfParameters*numberOfThreads];
    int factor;

#pragma omp parallel for private(factor) default(shared)
    for (factor = 0; factor < numberOfParameters; factor++)
    {
        ppAllFactors[factor] = pGrModel->GetFactor(factor);
        ppAllFactors[factor]->GetDistribFun()->ClearStatisticalData();
        was_updated[factor] = false;
        for (int proc = 1; proc < numberOfThreads; proc++)
        {
            ppAllFactors[factor + proc * numberOfParameters] =
                ppAllFactors[factor]->Clone();
            ppAllFactors[factor + proc * numberOfParameters]->GetDistribFun()->
                ClearStatisticalData();
            was_updated[factor + proc * numberOfParameters]= false;
        };
    };

    int* itsML = new int[numberOfThreads];  
    for (int delta = 0; delta < numberOfThreads; delta++)
    {
        itsML[delta] = 0;
    };

    int start_ev, end_ev;
    do
    {
        iteration++;

        start_ev = GetNumberProcEv();
        end_ev = GetNumEv();

#pragma omp parallel for schedule(dynamic) private(ev)
        for (ev = start_ev; ev < end_ev ; ev++)
        {  
            CFactor *parameter = NULL;
            int DomainNodes_new; 
            int bMaximize = 0;
            int bSumOnMixtureNode = 0;
            int infIsNeed = 0;
            int currentEvidNumber = ev; // !!!

            const CEvidence* pCurrentEvid = m_Vector_pEvidences[currentEvidNumber];

            infIsNeed = !GetObsFlags(ev)->empty(); // !!!

            int Num_thread = omp_get_thread_num();

            if (infIsNeed)
            {
                if (!pCurrentInfEng[Num_thread])
                {
                    pCurrentInfEng[Num_thread] = CJtreeInfEngine::Create(
                        (const CStaticGraphicalModel *)pGrModel);
                }
                pCurrentInfEng[Num_thread]->EnterEvidence(pCurrentEvid, bMaximize,
                    bSumOnMixtureNode);
            }
            for (DomainNodes_new = 0; DomainNodes_new < numberOfParameters; 
            DomainNodes_new++)
            {
                parameter = ppAllFactors[DomainNodes_new + 
                    Num_thread * numberOfParameters];
                if (infIsNeed)
                {
                    int DomainSize;
                    const int *domain;
                    parameter->GetDomain(&DomainSize, &domain);
                    if (IsDomainObserved(DomainSize, domain, currentEvidNumber))
                    {
                        const CEvidence *pEvidences[] = { pCurrentEvid };
                        parameter->UpdateStatisticsML(pEvidences, 1);
                        was_updated[DomainNodes_new+Num_thread*numberOfParameters]= true;
                    }
                    else
                    {
                        pCurrentInfEng[Num_thread]->MarginalNodes(domain, DomainSize, 1);
                        const CPotential * pMargPot = 
                            pCurrentInfEng[Num_thread]->GetQueryJPD();
                        parameter ->UpdateStatisticsEM(pMargPot, pCurrentEvid);
                        was_updated[DomainNodes_new+Num_thread*numberOfParameters]= true;
                    }
                }
                else
                {
                    const CEvidence *pEvidences[] = { pCurrentEvid };
                    parameter->UpdateStatisticsML(pEvidences, 1); 
                    was_updated[DomainNodes_new+Num_thread*numberOfParameters]= true;
                }  
            }
            itsML[Num_thread] = itsML[Num_thread] || !infIsNeed;
        }  // end of parallel for

        for (int delta = 1; delta < numberOfThreads; delta++)
        {
            itsML[0] = itsML[0] || itsML[delta];
        };

        //to join factors
#pragma omp parallel for private(factor) default(shared)
        for (factor = 0; factor < numberOfParameters; factor++)
        {
            for (int proc = 1; proc < numberOfThreads; proc++)
            {
                if (was_updated[factor+proc*numberOfParameters])
                {
                    ppAllFactors[factor]->UpdateStatisticsML(ppAllFactors[factor + 
                        proc*numberOfParameters]);
                    ppAllFactors[factor+proc*numberOfParameters]->GetDistribFun()->
                        ClearStatisticalData();
                };
                was_updated[factor+proc*numberOfParameters] = false;
            };
        };

        switch (pGrModel->GetModelType())
        {
        case mtBNet:
            {
                loglikOld = loglik;
                loglik = 0.0f;
                for (domainNodes = 0; domainNodes < numberOfParameters; domainNodes++)
                {
                    parameter1 = pGrModel->GetFactor(domainNodes);
                    loglik += parameter1->ProcessingStatisticalData(
                        m_numberOfAllEvidences);
                }
                break;
            }
        case mtMRF2:
        case mtMNet:
            {
                loglikOld = loglik;
                loglik = _LearnPotentials();
                break;
            }
        default:
            {
                PNL_THROW(CBadConst, "model type")
                    break;
            }
        }
        stopExpression = float(fabs(2 * (loglikOld - loglik) / 
            (loglikOld + loglik)));

        exit = ((stopExpression > epsilon) && (iteration <= GetMaxIterEM())) && !itsML[0];

        if (exit)
        {
            ClearStatisticData();
        }

        m_critValue.push_back(loglik);

        for (int j = 0; j < numberOfThreads; j++)
        {
            delete pCurrentInfEng[j];
            pCurrentInfEng[j] = NULL;
        }
    } while (exit);

    delete [] pCurrentInfEng;

    //”даление дополнительных факторов
    for (factor = numberOfParameters; factor < numberOfParameters * numberOfThreads;
    factor++)
    {
        delete ppAllFactors[factor];
    };

    delete[] ppAllFactors;
    delete[] was_updated;

    if (iteration > GetMaxIterEM())
    {
        PNL_THROW(CNotConverged, "maximum number of iterations")
    }

    SetNumProcEv( GetNumEv() );
}
void CParEMLearningEngine::Learn()
{
    CStaticGraphicalModel *pGrModel =  this->GetStaticModel();
    PNL_CHECK_IS_NULL_POINTER(pGrModel);
    PNL_CHECK_LEFT_BORDER(GetNumEv() - GetNumberProcEv() , 1);

    CJtreeInfEngine *pCurrentInfEng = NULL;

    CFactor *parameter = NULL;
    int exit = 0;
    int numberOfParameters = pGrModel->GetNumberOfParameters();
    int domainNodes;
    int infIsNeed = 0;
    int itsML = 0;

    // !!!
    float loglik = -FLT_MAX;
    float loglikOld = -FLT_MAX;
    float epsilon = GetPrecisionEM();
    float stopExpression = epsilon + 1.0f;
    int iteration = 0;
    int currentEvidNumber;
    int bMaximize = 0;
    int bSumOnMixtureNode = 0;
    const CEvidence* pCurrentEvid;
    int start_mpi, finish_mpi;
    int NumberOfProcesses, MyRank;
    int numSelfEvidences;
    
    MPI_Comm_size(MPI_COMM_WORLD, &NumberOfProcesses);
    MPI_Comm_rank(MPI_COMM_WORLD, &MyRank);

    int d = 0;
    do
    {
        iteration++;

        numSelfEvidences = (GetNumEv() - GetNumberProcEv()) / NumberOfProcesses;
        start_mpi = GetNumberProcEv() + numSelfEvidences * MyRank; // !!!
        if (MyRank < NumberOfProcesses - 1)
            finish_mpi = start_mpi + numSelfEvidences; // !!!
        else
            finish_mpi = GetNumEv(); // !!!        

        for(int ev = start_mpi; ev < finish_mpi; ev++)
        {
            infIsNeed = 0;
            currentEvidNumber = ev; // !!!

            pCurrentEvid = m_Vector_pEvidences[currentEvidNumber];
            if( !pCurrentEvid)
            {
                PNL_THROW(CNULLPointer, "evidence")
            }

            infIsNeed = !GetObsFlags(ev)->empty(); // !!!

            if(infIsNeed)
            {
                // create inference engine
                if(!pCurrentInfEng)
                {
                    pCurrentInfEng = CJtreeInfEngine::Create(pGrModel);
                }
                pCurrentInfEng->EnterEvidence(pCurrentEvid, bMaximize,
                    bSumOnMixtureNode);
            }

            for(domainNodes = 0; domainNodes < numberOfParameters; domainNodes++)
            {
                parameter = pGrModel->GetFactor(domainNodes);
                if(infIsNeed)
                {
                    int DomainSize;
                    const int *domain;
                    parameter->GetDomain(&DomainSize, &domain);
                    if (IsDomainObserved(DomainSize, domain, currentEvidNumber))
                    {
                        const CEvidence *pEvidences[] = { pCurrentEvid };
                        parameter->UpdateStatisticsML(pEvidences, 1);
                    }
                    else
                    {
                        pCurrentInfEng->MarginalNodes(domain, DomainSize, 1);
                        const CPotential * pMargPot = pCurrentInfEng->GetQueryJPD();
                        parameter ->UpdateStatisticsEM(pMargPot, pCurrentEvid);
                    }
                }
                else
                {
                    const CEvidence *pEvidences[] = { pCurrentEvid };
                    parameter->UpdateStatisticsML(pEvidences, 1);
                }
            }
            itsML = itsML || !infIsNeed;
        }

        for(domainNodes = 0; domainNodes < numberOfParameters; domainNodes++ )
        {
            parameter = pGrModel->GetFactor(domainNodes);
            
            CNumericDenseMatrix<float> *matForSending;
            int matDim;
            const int *pMatRanges;
            int dataLength;
            const float *pDataForSending;

            matForSending = static_cast<CNumericDenseMatrix<float>*>
                ((parameter->GetDistribFun())->GetStatisticalMatrix(stMatTable));

            matForSending->GetRanges(&matDim, &pMatRanges);
            matForSending->GetRawData(&dataLength, &pDataForSending);
            float *pDataRecv = new float[dataLength];
            float *pDataRecv_copy = new float[dataLength];
            MPI_Status status;

            MPI_Allreduce((void*)pDataForSending, pDataRecv, dataLength, MPI_FLOAT, MPI_SUM,
                MPI_COMM_WORLD);

            CNumericDenseMatrix<float> *RecvMatrix =
                static_cast<CNumericDenseMatrix<float>*>
                (parameter->GetDistribFun()->GetStatisticalMatrix(stMatTable));
            int dataLength_new;
            float *pData_new;
            RecvMatrix->GetRawData(&dataLength_new, (const float**)(&pData_new));
            for(int t=0;t<dataLength_new;t++)
                pData_new[t]=pDataRecv[t];
        }
        switch (pGrModel->GetModelType())
        {
        case mtBNet:
            {
                loglikOld = loglik;
                loglik = 0.0f;
                for(domainNodes = 0; domainNodes < numberOfParameters; domainNodes++)
                {
                    parameter = pGrModel->GetFactor(domainNodes);
                    loglik += parameter->ProcessingStatisticalData(m_numberOfAllEvidences);
                }
                break;
            }
        case mtMRF2:
        case mtMNet:
            {
                loglikOld = loglik;
                loglik = _LearnPotentials();
                break;
            }
        default:
            {
                PNL_THROW(CBadConst, "model type")
                    break;
            }
        }

        stopExpression = 
            float(fabs(2 * (loglikOld - loglik) / (loglikOld + loglik)));
        exit = ((stopExpression > epsilon) && (iteration <= GetMaxIterEM())) && !itsML;
        if(exit)
        {
            ClearStatisticData();
        }

        delete pCurrentInfEng;
        pCurrentInfEng = NULL;
    }while(exit);

    if(iteration > GetMaxIterEM())
    {
        PNL_THROW(CNotConverged, "maximum number of iterations")
    }

    SetNumProcEv( GetNumEv() );
}
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( &paramType, "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");
}
void CParEMLearningEngine::LearnContMPI()
{
    CStaticGraphicalModel *pGrModel =  this->GetStaticModel();
    PNL_CHECK_IS_NULL_POINTER(pGrModel);
    PNL_CHECK_LEFT_BORDER(GetNumEv() - GetNumberProcEv() , 1);
    
    CInfEngine *pInfEng = NULL;
  
    pInfEng = CJtreeInfEngine::Create(pGrModel);
      
    
    float loglik = 0.0f;
    int domainNodes;
    CFactor *parameter = NULL;
    int numberOfParameters = pGrModel->GetNumberOfParameters();
    
    int nFactors = pGrModel->GetNumberOfFactors();
    const CEvidence *pEv;
    CFactor *pFactor;
    
    int iteration = 0;
    int ev;
    int i,numSelfEvidences,NumberOfProcesses, MyRank;
    int start_mpi, finish_mpi;
    
    MPI_Comm_size(MPI_COMM_WORLD, &NumberOfProcesses);
    MPI_Comm_rank(MPI_COMM_WORLD, &MyRank);
    
    if (IsAllObserved())
    {
        int i;
        float **evid = NULL;
        EDistributionType dt;
        CFactor *factor = NULL;
        for (i = 0; i < nFactors; i++)
        {
            factor = pGrModel->GetFactor(i);
                 
            factor->UpdateStatisticsML(&m_Vector_pEvidences[GetNumberProcEv()], 
               GetNumEv() - GetNumberProcEv());
            
        }
        m_critValue.push_back(UpdateModel());
    }
    else
    {
        bool bContinue;
        const CPotential * pot;
        
        do
        {
            ClearStatisticData();
            iteration++;

            numSelfEvidences = (GetNumEv() - GetNumberProcEv()) / NumberOfProcesses;
            start_mpi = GetNumberProcEv() + numSelfEvidences * MyRank; 
            if (MyRank < NumberOfProcesses - 1)
                finish_mpi = start_mpi + numSelfEvidences; 
            else
                finish_mpi = GetNumEv();            

            for(int ev = start_mpi; ev < finish_mpi; ev++)
            {
                
                bool bInfIsNeed = !GetObsFlags(ev)->empty(); 
                pEv = m_Vector_pEvidences[ev];
                
                if( bInfIsNeed )
                {
                    pInfEng->EnterEvidence(pEv,      0, 0);
                }
                int i;
                
                for( i = 0; i < nFactors; i++ )
                {
                    pFactor = pGrModel->GetFactor(i);
                    int nnodes;
                    const int * domain;
                    pFactor->GetDomain( &nnodes, &domain );
                    if( bInfIsNeed && !IsDomainObserved(nnodes, domain, ev ) )
                    {
                        pInfEng->MarginalNodes( domain, nnodes, 1 );
                        pot = pInfEng->GetQueryJPD(); 
                        
                        pFactor->UpdateStatisticsEM( /*pInfEng->GetQueryJPD */ pot, pEv );
                    }
                    else
                    {
                        pFactor->UpdateStatisticsML( &pEv, 1 );
                    }
                }
            }
            
            for(domainNodes = 0; domainNodes < numberOfParameters; domainNodes++ )
            {   
                parameter = pGrModel->GetFactor(domainNodes);
                
                C2DNumericDenseMatrix<float> *matMeanForSending;
                C2DNumericDenseMatrix<float> *matCovForSending;
                int dataLengthM,dataLengthC;
                
                const float *pMeanDataForSending;
                const float *pCovDataForSending;
                
                matMeanForSending = static_cast<C2DNumericDenseMatrix<float>*>
                    ((parameter->GetDistribFun())->GetStatisticalMatrix(stMatMu));               
                
                matMeanForSending->GetRawData(&dataLengthM, &pMeanDataForSending);
                
                matCovForSending = static_cast<C2DNumericDenseMatrix<float>*>
                    ((parameter->GetDistribFun())->GetStatisticalMatrix(stMatSigma));               
                
                matCovForSending->GetRawData(&dataLengthC, &pCovDataForSending);
                
                float *pMeanDataRecv = new float[dataLengthM];
                float *pCovDataRecv = new float[dataLengthC];
                MPI_Status status;                         
                
                MPI_Allreduce((void*)pMeanDataForSending, pMeanDataRecv, dataLengthM, MPI_FLOAT, MPI_SUM,
                    MPI_COMM_WORLD);
                MPI_Allreduce((void*)pCovDataForSending, pCovDataRecv, dataLengthC, MPI_FLOAT, MPI_SUM,
                    MPI_COMM_WORLD);
                
                memcpy((void*)pMeanDataForSending,pMeanDataRecv,dataLengthM*sizeof(float));
                
                memcpy((void*)pCovDataForSending,pCovDataRecv,dataLengthC*sizeof(float));
            }                        

            loglik = UpdateModel();
            
            if( GetMaxIterEM() != 1)
            {
                bool flag = iteration == 1 ? true : 
                (fabs(2*(m_critValue.back()-loglik)/(m_critValue.back() + loglik)) > GetPrecisionEM() );
                
                bContinue = GetMaxIterEM() > iteration && flag;
            }
            else
            {
                bContinue = false;
            }
            m_critValue.push_back(loglik);
            
        }while(bContinue);
    }
    SetNumProcEv( GetNumEv() );
}
CBNet* CreateBNet()
{
	// Creation Water-Sprinkler Bayesian network

	const int numOfNds = 4;//*<-

	// 1 STEP:
	// need to specify the graph structure of the model;
	// there are two way to do it

	CGraph *pGraph;

		// Graph creation using neighbors list

		int numOfNbrs[numOfNds] = { 2, 2, 2, 2 };//*<-
		int nbrs0[] = { 1, 2 };//*<-
		int nbrs1[] = { 0, 3 };//*<-
		int nbrs2[] = { 0, 3 };//*<-
		int nbrs3[] = { 1, 2 };//*<-

		// number of neighbors for every node
		int *nbrs[] = { nbrs0, nbrs1, nbrs2, nbrs3 };//*<-

		// neighbors can be of either one of the three following types:
		// a parent, a child (for directed arcs) or just a neighbor (for undirected graphs).
		// Accordingly, the types are ntParent, ntChild or ntNeighbor.

		ENeighborType nbrsTypes0[] = { ntChild, ntChild };//*<-
		ENeighborType nbrsTypes1[] = { ntParent, ntChild };//*<-
		ENeighborType nbrsTypes2[] = { ntParent, ntChild };//*<-
		ENeighborType nbrsTypes3[] = { ntParent, ntParent };//*<-

		ENeighborType *nbrsTypes[] = { nbrsTypes0, nbrsTypes1,nbrsTypes2, nbrsTypes3 };//*<-

		// this is creation of a directed graph for the BNet model using neighbors list
		pGraph = CGraph::Create( numOfNds, numOfNbrs, nbrs, nbrsTypes );

	// 2 STEP:
	// Creation NodeType objects and specify node types for all nodes of the model.

	nodeTypeVector  nodeTypes;

	// number of node types is 1, because all nodes are of the same type
	// all four are discrete and binary
	CNodeType nt(1,2);//*<-
	nodeTypes.push_back(nt);

	intVector nodeAssociation;
	// reflects association between node numbers and node types
	// nodeAssociation[k] is a number of node type object in the
	// node types array for the k-th node
	nodeAssociation.assign(numOfNds, 0);

	// 2 STEP:
	// Creation base for BNet using Graph, types of nodes and nodes association

	CBNet* pBNet = CBNet::Create( numOfNds, nodeTypes, nodeAssociation, pGraph );

	// 3 STEP:
	// Allocation space for all factors of the model
	pBNet->AllocFactors();

	// 4 STEP:
	// Creation factors and attach their to model

	//create raw data tables for CPDs
	float table0[] = { 0.5f, 0.5f };//*<-
	float table1[] = { 0.5f, 0.5f, 0.9f, 0.1f };
	float table2[] = { 0.8f, 0.2f, 0.2f, 0.8f };
	float table3[] = { 1.0f, 0.0f, 0.1f, 0.9f, 0.1f, 0.9f, 0.01f, 0.99f };

	float* table[] = { table0, table1, table2, table3 };//*<-

	int i;
	for( i = 0; i < numOfNds; ++i )
	{
		pBNet->AllocFactor(i);

		CFactor* pFactor = pBNet->GetFactor(i);

		pFactor->AllocMatrix( table[i], matTable );
	}

	return pBNet;
}
void CStaticStructLearnSEM::CreateNeighborCPDs(CBNet* pBNet, 
	pCPDVector* vNeighborCPDs, EDGEOPVECTOR* vValidMoves, intVector* RevCorrespDel)
{
	CGraph* pGraph = pBNet->GetGraph();
	CDAG* pDAG = CDAG::Create(*pGraph);
	CModelDomain* pMD = pBNet->GetModelDomain();
	intVector vDiscrete, vContinuous;
	intVector vAncestor, vDescent;
	intVector vMixture, vMix;
	const CNodeType* nt;
	CFactor* factor;

	int i, j, position;
	vAncestor.assign(m_vAncestor.begin(), m_vAncestor.end());
	vDescent.assign(m_vDescent.begin(), m_vDescent.end());

	pBNet->FindMixtureNodes(&vMix);
	for(i=0; i<vMix.size(); i++)
	{
		factor = pBNet->GetFactor(vMix[i]);
		j = static_cast<CMixtureGaussianCPD*>(factor) -> GetNumberOfMixtureNode();
		vMixture.push_back(j);
	}

	for(i=0; i<m_nNodes; i++)
	{
		nt = pMD->GetVariableType(i);
		if( nt->IsDiscrete() )
		{
			vDiscrete.push_back(i);
		}
		else
			vContinuous.push_back(i);
	}
	
	vValidMoves->clear();
	vNeighborCPDs->clear();
	RevCorrespDel->clear();
	pDAG->GetAllValidMove(vValidMoves, &vMixture.front(), vMixture.size(), m_nMaxFanIn, 
		                  &vDiscrete, &vContinuous, &vDescent, &vAncestor );
	int nMoves = vValidMoves->size();
	intVector domain;
	EDGEOP curMove;

	int start, end;
	for(i=0; i<nMoves; i++)
	{
		domain.clear();
		curMove = (*vValidMoves)[i];
		switch (curMove.DAGChangeType)
		{
		case DAG_DEL : 
			start = curMove.originalEdge.startNode;
			end = curMove.originalEdge.endNode;
			factor = pBNet->GetFactor(end);
			factor->GetDomain(&domain);
			position = std::find(domain.begin(), domain.end(), start)
					       - domain.begin();
			domain.erase(domain.begin()+position);
			vNeighborCPDs->push_back(CreateRandomCPD(domain.size(), &domain.front(), pBNet));
			break;

		case DAG_ADD :
			start = curMove.originalEdge.startNode;
			end = curMove.originalEdge.endNode;
			factor = pBNet->GetFactor(end);
			factor->GetDomain(&domain);
			domain.insert(domain.begin(), start);
			vNeighborCPDs->push_back(CreateRandomCPD(domain.size(), &domain.front(), pBNet));
			break;

		case DAG_REV :
			end = curMove.originalEdge.startNode;
			start = curMove.originalEdge.endNode;
			factor = pBNet->GetFactor(end);
			factor->GetDomain(&domain);
			domain.insert(domain.begin(), start);
			vNeighborCPDs->push_back(CreateRandomCPD(domain.size(), &domain.front(), pBNet));
			break;
		}
	}

	RevCorrespDel->assign(nMoves, -1);
	EDGEOP pre_move;
	for(i=0; i<nMoves; i++)
	{
		curMove = (*vValidMoves)[i];
		if(curMove.DAGChangeType == DAG_REV)
		{
			start = curMove.originalEdge.startNode;
			end = curMove.originalEdge.endNode;
			for(j=0; j<nMoves; j++)
			{
				pre_move = (*vValidMoves)[j];
				if( (start == pre_move.originalEdge.startNode) &&
					(end == pre_move.originalEdge.endNode) &&
					(pre_move.DAGChangeType == DAG_DEL) )
				{
					(*RevCorrespDel)[i] = j;
					break;
				}
			}
		}
	}
}
Exemple #22
0
CFactor* CFactor::CopyWithNewDomain(const CFactor *factor, intVector &domain, 
                                                 CModelDomain *pMDNew,
                                                 const intVector& /* obsIndices */)
{
    int domSize = domain.size();
    intVector domOld;
    factor->GetDomain( &domOld );
    if( int(domOld.size()) != domSize )
    {
        PNL_THROW( CBadArg, "number of nodes" );
    }
    CModelDomain *pMDOld = factor->GetModelDomain();
    
    //check is the types are the same
    const pConstNodeTypeVector* ntFactor = factor->GetArgType();
    
    /*
    const CNodeType *nt;
    
    for( int i = 0; i < domSize; i++ )
    {
        nt = (*ntFactor)[i];
        if( nt->IsDiscrete() )
        {
            if( nt->GetNodeSize() == 1 )
            {
                if( *pMDOld->GetVariableType(domOld[i]) != 
                    *pMDNew->GetVariableType(domain[i]))
                {
                    PNL_THROW(CInconsistentType, "types of variables should correspond");
                }
                
            }
            else
            {
                if( *nt != *pMDNew->GetVariableType(domain[i]) )
                {
                    PNL_THROW(CInconsistentType, "types of variables should correspond");
                }
            }
        }
        else
        {
            if( nt->GetNodeSize() == 0 )
            {
                if( *pMDOld->GetVariableType(domOld[i]) != 
                    *pMDNew->GetVariableType(domain[i]))
                {
                    PNL_THROW(CInconsistentType, "types of variables should correspond");
                }
                
            }
            else
            {
                if( *nt != *pMDNew->GetVariableType(domain[i]) )
                {
                    PNL_THROW(CInconsistentType, "types of variables should correspond");
                }
            }
        }

        
    }
    */
    const CNodeType *nt;
    int i;
    intVector obsPositions;
    factor->GetObsPositions(&obsPositions);
    if( obsPositions.size() )
    {
	intVector::iterator iterEnd = obsPositions.end();
        for( i = 0; i < domSize; i++)
        {
            if( std::find( obsPositions.begin(),iterEnd, i) != iterEnd )
            {
                if( *pMDOld->GetVariableType(domOld[i]) != 
                    *pMDNew->GetVariableType(domain[i]))
                {
                    PNL_THROW(CInconsistentType, "types of variables should correspond");
                }
            }
        }
    }
    else
    {
        for( i = 0; i < domSize; i++ )
        {
            nt = (*ntFactor)[i];
            if( *nt != *pMDNew->GetVariableType(domain[i]) )
            {
                PNL_THROW(CInconsistentType, "types of variables should correspond");
            }
            
        }
    }
    
    

    CFactor *pNewFactor;
    switch ( factor->GetFactorType() )
    {
    case ftPotential:
            {
                switch ( factor->GetDistributionType() )
                {
            case dtTabular:
                {
                    pNewFactor = CTabularPotential::
                        Copy(static_cast<const CTabularPotential*>(factor) );
                    break;
                }
            case dtGaussian:
                {
                    pNewFactor = CGaussianPotential::
                        Copy(static_cast<const CGaussianPotential*>(factor));
                    break;
                }
            case dtScalar:
                {
                    pNewFactor = CScalarPotential::
                        Copy( static_cast<const CScalarPotential*>(factor) );
                    break;
                }
            default:
                {
                    PNL_THROW(CNotImplemented, "distribution type" );
                }
            }
            break;
        }
    case ftCPD:
        {
            switch ( factor->GetDistributionType() )
            {
            case dtTabular:
                {
                    pNewFactor = CTabularCPD::
                        Copy(static_cast<const CTabularCPD*>(factor));
                    break;
                }
            case dtGaussian:
                {
                    pNewFactor = CGaussianCPD::
                        Copy(static_cast<const CGaussianCPD*>(factor));
                    break;
                }
            case dtCondGaussian:
                {
                    pNewFactor = CGaussianCPD::
                        Copy(static_cast<const CGaussianCPD*>(factor));
                    break;
                }
            case dtSoftMax:
                {
                    pNewFactor = CSoftMaxCPD::
                        Copy(static_cast<const CSoftMaxCPD*>(factor));
                    break;
                }
            case dtCondSoftMax:
                {
                    pNewFactor = CSoftMaxCPD::
                        Copy(static_cast<const CSoftMaxCPD*>(factor));
                    break;
                }
            case dtMixGaussian:
                {
                    pNewFactor = CMixtureGaussianCPD::Copy( 
                        static_cast<const CMixtureGaussianCPD*>(factor));
                    break;
                }
            default:
                {
                    PNL_THROW(CNotImplemented, "distribution type" );
                }
            }
            break;
        }
    default:
        {
            PNL_THROW(CNotImplemented, "factor type" );
        }
    }
    PNL_CHECK_IF_MEMORY_ALLOCATED(pNewFactor);
    /*
    if( pMDNew == factor->GetModelDomain())
    {
        return pNewFactor;
    }
    else*/
    {
        pNewFactor->m_Domain = intVector(domain);
        pNewFactor->SetModelDomain(pMDNew, 0);
        return pNewFactor;
    }
    
}
CExInfEngine< INF_ENGINE, MODEL, FLAV, FALLBACK_ENGINE1, FALLBACK_ENGINE2 >::CExInfEngine( CStaticGraphicalModel const *gm )
    : CInfEngine( itEx, gm ), evidence_mine( false ),
      maximize( 0 ), MPE_ev( 0 ), query_JPD( 0 ), graphical_model( gm )
{
    int i, j, k;
    intVector dom;
    intVector conv;
    CFactor *fac;

    PNL_MAKE_LOCAL( CGraph *, gr, gm, GetGraph() );
    PNL_MAKE_LOCAL( int, sz, gr, GetNumberOfNodes() );

    gr->GetConnectivityComponents( &decomposition );

    for ( i = decomposition.size(); i--; )
    {
        std::sort( decomposition[i].begin(), decomposition[i].end() );
    }
    if ( PNL_IS_EXINFENGINEFLAVOUR_UNSORTED( FLAV ) )
    {
        gr->GetTopologicalOrder( &conv );
    }

    orig2comp.resize( sz );
    orig2idx.resize( sz );

    for ( k = 2; k--; )
    {
        for ( i = decomposition.size(); i--; )
        {
            for ( j = decomposition[i].size(); j--; )
            {
                orig2comp[decomposition[i][j]] = i;
                orig2idx[decomposition[i][j]] = j;
            }
        }

        if ( PNL_IS_EXINFENGINEFLAVOUR_UNSORTED( FLAV ) && k )
        {
            for ( i = sz; i--; )
            {
                decomposition[orig2comp[conv[i]]][orig2idx[conv[i]]] = i;
            }
        }
        else
        {
            break;
        }
    }

    graphs.resize( decomposition.size() );
    models.resize( decomposition.size() );
    engines.resize( decomposition.size() );

    for ( i = decomposition.size(); i--; )
    {
        graphs[i] = gr->ExtractSubgraph( decomposition[i] );
#if 0
        std::cout << "graph " << i << std::endl;
        graphs[i]->Dump();
#endif
    }
    node_types.resize( decomposition.size() );
    node_assoc.resize( decomposition.size() );
    for ( i = 0, k = 0; i < decomposition.size(); ++i )
    {
        node_types[i].resize( decomposition[i].size() );
        node_assoc[i].resize( decomposition[i].size() );
        for ( j = 0; j < decomposition[i].size(); ++j )
        {
            node_types[i][j] = *gm->GetNodeType( decomposition[i][j] );
            node_assoc[i][j] = j;
        }
    }
    for ( i = decomposition.size(); i--; )
    {
        models[i] = MODEL::Create( decomposition[i].size(), node_types[i], node_assoc[i], graphs[i] );
    }
    for ( i = 0; i < gm->GetNumberOfFactors(); ++i )
    {
        fac = gm->GetFactor( i );
        fac->GetDomain( &dom );
#if 0
        std::cout << "Ex received orig factor" << std::endl;
        fac->GetDistribFun()->Dump();
#endif
        k = orig2comp[dom[0]];
        for ( j = dom.size(); j--; )
        {
            dom[j] = orig2idx[dom[j]];
        }
        fac = CFactor::CopyWithNewDomain( fac, dom, models[k]->GetModelDomain() );
#if 0
        std::cout << "Ex mangled it to" << std::endl;
        fac->GetDistribFun()->Dump();
#endif
        models[k]->AttachFactor( fac );
    }
    for ( i = decomposition.size(); i--; )
    {
        switch ( decomposition[i].size() )
        {
        case 1:
            engines[i] = FALLBACK_ENGINE1::Create( models[i] );
            continue;
        case 2:
            engines[i] = FALLBACK_ENGINE2::Create( models[i] );
            continue;
        default:
            engines[i] = INF_ENGINE::Create( models[i] );
        }
    }
}
void CEMLearningEngine::LearnExtraCPDs(int nMaxFamily, pCPDVector* additionalCPDs, floatVector* additionalLLs)
{

    CStaticGraphicalModel *pGrModel =  this->GetStaticModel();
    PNL_CHECK_IS_NULL_POINTER(pGrModel);
    PNL_CHECK_LEFT_BORDER(GetNumEv(), 1);
    
    int numberOfFactors = pGrModel->GetNumberOfFactors();
    int numberOfAddFactors = additionalCPDs->size();
    
    additionalLLs->resize(numberOfAddFactors);
    additionalLLs->clear();
    
    m_vFamilyLogLik.resize(numberOfFactors);
    float	loglik = 0.0f, ll;
    int		i, ev;
    int iteration = 0;
    const CEvidence* pEv;
    
    CFactor *factor = NULL;
    int nnodes;
    const int * domain;
    
    bool bInfIsNeed;
    CInfEngine *pInfEng = m_pInfEngine;
    
    if (IsAllObserved())
    {
        for (i = 0; i < numberOfFactors; i++)
        {
            factor = pGrModel->GetFactor(i);
            factor->UpdateStatisticsML(&m_Vector_pEvidences[GetNumberProcEv()], 
                GetNumEv() - GetNumberProcEv());
        }
        
        for( ev = 0; ev < GetNumEv() ; ev++)
        {
            pEv = m_Vector_pEvidences[ev];
            for( i = 0; i < numberOfAddFactors; i++ )
            {
                factor = static_cast<CFactor*>((*additionalCPDs)[i]);
                factor->UpdateStatisticsML( &pEv, 1 );
            }
        }
        
        switch (pGrModel->GetModelType())
        {
        case mtBNet:
            {
                for( i = 0; i<numberOfFactors; i++ )
                {
                    factor = pGrModel->GetFactor(i);
                    ll = factor->ProcessingStatisticalData( GetNumEv());
                    m_vFamilyLogLik[i] = ll;
                    loglik += ll;
                }
                
                for( i = 0; i < numberOfAddFactors; i++ )
                {
                    factor = static_cast<CFactor*>((*additionalCPDs)[i]);
                    ll = factor->ProcessingStatisticalData( GetNumEv());
                    (*additionalLLs)[i] = ll;
                }
                break;
            }
        case mtMRF2:
        case mtMNet:
            {	
                break;
            }
        default:
            {
                PNL_THROW(CBadConst, "model type" )
                    break;
            }
        }
        m_critValue.push_back(loglik);    
        
    }
    else
    {
int CBICLearningEngine::DimOfModel(const CStaticGraphicalModel *pModel)
{
/*
compute dimension of the model in (d)
it using in BIC criterion:
BIC = LogLic - 0.5*d*log(N)
    */
    int nParam = pModel->GetNumberOfFactors();
    CFactor *param = NULL;
    int dimOfModel = 0;
    int dim = 1;
    CMatrix<float> *matrix;;
    for (int  i = 0; i < nParam; i++)
    {
	dim = 1;
	param = pModel->GetFactor(i);
	switch (param->GetFactorType())
	{
	case ftCPD:
	    {
		switch (param->GetDistributionType())
		{
		case dtTabular:
		    {

			matrix = param->GetMatrix(matTable);
			int size;
			const int *ranges;
			static_cast<CNumericDenseMatrix<float>*>(matrix)->
			    GetRanges(&size, &ranges);
			for(int j=0; j < size - 1; j++)
			{
			    dim *= ranges[j];

			}
			dim *= ranges[size-1]-1;
			break;

		    }//case dtTabular
		case dtGaussian:
		    {
			PNL_THROW(CNotImplemented,"Gaussian")
			    break;
		    }//case dtGaussian
		case dtCondGaussian:
		    {
			PNL_THROW(CNotImplemented,"CondGaussian")
			    break;
		    }//case dtCondGaussian
		default:
		    {
			PNL_THROW(CBadConst,"distribution type")
			    break;
		    }
		}//swith(param->GetFactorType)
		break;
	    }//end case ftCPD
	case ftPotential:
	    {
		PNL_THROW(CNotImplemented,"Factor")
		    break;
	    }
	default:
	    {
		PNL_THROW(CBadConst,"FactorType")
		    break;
	    }
	}//end switch(param->GetFactor)

	dimOfModel += dim;
    }//end for(i)
    return dimOfModel;
}
void CEMLearningEngine::Learn()
{
    CStaticGraphicalModel *pGrModel =  this->GetStaticModel();
    PNL_CHECK_IS_NULL_POINTER(pGrModel);
    PNL_CHECK_LEFT_BORDER(GetNumEv() - GetNumberProcEv() , 1);
    
    CInfEngine *pInfEng = NULL;
    if (m_pInfEngine)
    {
        pInfEng = m_pInfEngine;
    }
    else
    {
        if (!m_bAllObserved)
        {
            pInfEng = CJtreeInfEngine::Create(pGrModel);
            m_pInfEngine = pInfEng;
        }
    }
    
    float loglik = 0.0f;
    
    int nFactors = pGrModel->GetNumberOfFactors();
    const CEvidence *pEv;
    CFactor *pFactor;
    
    int iteration = 0;
    int ev;

    bool IsCastNeed = false;
    int i;
    for( i = 0; i < nFactors; i++ )
    {
        pFactor = pGrModel->GetFactor(i);
        EDistributionType dt = pFactor->GetDistributionType();
        if ( dt == dtSoftMax ) IsCastNeed = true;
    }

    float ** full_evid = NULL;
    if (IsCastNeed)
    {
        BuildFullEvidenceMatrix(&full_evid);
    }

    
    if (IsAllObserved())
    {
        int i;
        float **evid = NULL;
        EDistributionType dt;
        CFactor *factor = NULL;
        for (i = 0; i < nFactors; i++)
        {
            factor = pGrModel->GetFactor(i);
            dt = factor->GetDistributionType();
            if (dt != dtSoftMax)
            {
                factor->UpdateStatisticsML(&m_Vector_pEvidences[GetNumberProcEv()], 
                    GetNumEv() - GetNumberProcEv());
            }
            else
            {
                
                intVector family;
				family.resize(0);
                pGrModel->GetGraph()->GetParents(i, &family);
                family.push_back(i);
                CSoftMaxCPD* SoftMaxFactor = static_cast<CSoftMaxCPD*>(factor);
                SoftMaxFactor->BuildCurrentEvidenceMatrix(&full_evid, 
					&evid,family,m_Vector_pEvidences.size());
				SoftMaxFactor->InitLearnData();
                SoftMaxFactor->SetMaximizingMethod(m_MaximizingMethod);
                SoftMaxFactor->MaximumLikelihood(evid, m_Vector_pEvidences.size(),
                    0.00001f, 0.01f);
                SoftMaxFactor->CopyLearnDataToDistrib();
                for (int k = 0; k < factor->GetDomainSize(); k++)
                {
                    delete [] evid[k];
                }
                delete [] evid;
            }
        }
        m_critValue.push_back(UpdateModel());
    }
    else
    {
        bool bContinue;
        const CPotential * pot;
        
/*        bool IsCastNeed = false;
        int i;
        for( i = 0; i < nFactors; i++ )
        {
            pFactor = pGrModel->GetFactor(i);
            EDistributionType dt = pFactor->GetDistributionType();
            if ( dt == dtSoftMax ) IsCastNeed = true;
        }

        float ** full_evid;
        if (IsCastNeed)
        {
            BuildFullEvidenceMatrix(full_evid);
        }*/
        
        do
        {
            ClearStatisticData();
            iteration++;
            for( ev = GetNumberProcEv(); ev < GetNumEv() ; ev++ )
            {
                bool bInfIsNeed = !GetObsFlags(ev)->empty(); 
                pEv = m_Vector_pEvidences[ev];
                if( bInfIsNeed )
                {
                    pInfEng->EnterEvidence(pEv, 0, 0);
                }
                int i;
                for( i = 0; i < nFactors; i++ )
                {
                    pFactor = pGrModel->GetFactor(i);
                    int nnodes;
                    const int * domain;
                    pFactor->GetDomain( &nnodes, &domain );
                    if( bInfIsNeed && !IsDomainObserved(nnodes, domain, ev ) )
                    {
                        pInfEng->MarginalNodes( domain, nnodes, 1 );
                        pot = pInfEng->GetQueryJPD(); 
                        if ( (!(m_Vector_pEvidences[ev])->IsNodeObserved(i)) && (IsCastNeed) )
                        {
                            Cast(pot, i, ev, &full_evid);
                        }
                        EDistributionType dt;
                        dt = pFactor->GetDistributionType();
                        if ( !(dt == dtSoftMax) )
                            pFactor->UpdateStatisticsEM( /*pInfEng->GetQueryJPD */ pot, pEv );
                    }
                    else
                    {
                        if ((pFactor->GetDistributionType()) != dtSoftMax)
                            pFactor->UpdateStatisticsML( &pEv, 1 );
                    }
                }
            }
            
            int i;
/*
            printf ("\n My Full Evidence Matrix");
            for (i=0; i<nFactors; i++)
            {
                for (j=0; j<GetNumEv(); j++)
                {
                    printf ("%f   ", full_evid[i][j]);
                }
                printf("\n");
            } 
*/            
            float **evid = NULL;
            EDistributionType dt;
            CFactor *factor = NULL;
            // int i;
            for (i = 0; i < nFactors; i++)
            {
                factor = pGrModel->GetFactor(i);
                dt = factor->GetDistributionType();
                if (dt == dtSoftMax)
                {
					intVector family;
				    family.resize(0);
                    pGrModel->GetGraph()->GetParents(i, &family);
                    family.push_back(i);
                    CSoftMaxCPD* SoftMaxFactor = static_cast<CSoftMaxCPD*>(factor);
					SoftMaxFactor->BuildCurrentEvidenceMatrix(&full_evid, 
						&evid,family,m_Vector_pEvidences.size());
                    SoftMaxFactor->InitLearnData();
                    SoftMaxFactor->SetMaximizingMethod(m_MaximizingMethod);
                    //        SoftMaxFactor->MaximumLikelihood(evid, m_numberOfLastEvidences, 
                    SoftMaxFactor->MaximumLikelihood(evid, m_Vector_pEvidences.size(),
                        0.00001f, 0.01f);
                    SoftMaxFactor->CopyLearnDataToDistrib();
                    for (int k = 0; k < factor->GetDomainSize(); k++)
                    {
                        delete [] evid[k];
                    }
                    delete [] evid;
                }
            }
                        
            loglik = UpdateModel();
            
            if( GetMaxIterEM() != 1)
            {
                bool flag = iteration == 1 ? true : 
                (fabs(2*(m_critValue.back()-loglik)/(m_critValue.back() + loglik)) > GetPrecisionEM() );
                
                bContinue = GetMaxIterEM() > iteration && flag;
            }
            else
            {
                bContinue = false;
            }
            m_critValue.push_back(loglik);
            
        }while(bContinue);
    }
    SetNumProcEv( GetNumEv() );
   
    if (IsCastNeed)
    {
        int NumOfNodes = pGrModel->GetGraph()->GetNumberOfNodes();
        for (i=0; i<NumOfNodes; i++)
        {
            delete [] full_evid[i];
        }
        delete [] full_evid;
    }

}
Exemple #27
0
int testSetStatistics()
{
    int ret = TRS_OK;
    float eps = 0.1f;
    
    int seed = pnlTestRandSeed();
    pnlSeed( seed );   
            
    CBNet *pBNet = pnlExCreateCondGaussArBNet();
    CModelDomain *pMD = pBNet->GetModelDomain();

    
    CGraph *pGraph = CGraph::Copy(pBNet->GetGraph());
    
    CBNet *pBNet1 = CBNet::CreateWithRandomMatrices( pGraph, pMD );

    pEvidencesVector evidences;
    int nEvidences = pnlRand( 3000, 4000);
    
    pBNet->GenerateSamples( &evidences, nEvidences );
   
    
    int i;
    for( i = 0; i < nEvidences; i++)
    {
	
	//evidences[i]->MakeNodeHiddenBySerialNum(0);
    }
    

    CEMLearningEngine *pLearn = CEMLearningEngine::Create(pBNet1);
    pLearn->SetData( nEvidences, &evidences.front() );
    pLearn->SetMaxIterEM();
    pLearn->Learn();

    for( i = 0; i < pBNet->GetNumberOfFactors(); i++ )
    {
	if( ! pBNet->GetFactor(i)->IsFactorsDistribFunEqual(pBNet1->GetFactor(i), eps))
	{
	    ret = TRS_FAIL;
	    pBNet->GetFactor(i)->GetDistribFun()->Dump();
	    pBNet1->GetFactor(i)->GetDistribFun()->Dump();

	}
    }
    
    CDistribFun *pDistr;
    const CMatrix<float>* pMat;
    CFactor *pCPD;
    
    pDistr = pBNet1->GetFactor(0)->GetDistribFun();
    pMat = pDistr->GetStatisticalMatrix(stMatTable);
    
    pCPD = pBNet->GetFactor(0);
    pCPD->SetStatistics(pMat, stMatTable);
    pCPD->ProcessingStatisticalData(nEvidences);
    if( ! pCPD->IsFactorsDistribFunEqual(pBNet1->GetFactor(0), 0.0001f) )
    {
	ret = TRS_FAIL;
    }
    

    pDistr = pBNet1->GetFactor(1)->GetDistribFun();
    
    int parentVal;
    pCPD = pBNet->GetFactor(1);
    
    parentVal = 0;

    pCPD->SetStatistics(pMat, stMatCoeff);

    pMat = pDistr->GetStatisticalMatrix(stMatMu, &parentVal);
    pCPD->SetStatistics(pMat, stMatMu, &parentVal);
    
    
    pMat = pDistr->GetStatisticalMatrix(stMatSigma, &parentVal);
    pCPD->SetStatistics(pMat, stMatSigma, &parentVal);
    
    parentVal = 1;
    
    pMat = pDistr->GetStatisticalMatrix(stMatMu, &parentVal);
    pCPD->SetStatistics(pMat, stMatMu, &parentVal);
    
    
    pMat = pDistr->GetStatisticalMatrix(stMatSigma, &parentVal);
    pCPD->SetStatistics(pMat, stMatSigma, &parentVal);

    pCPD->ProcessingStatisticalData(nEvidences);
    
    if( ! pCPD->IsFactorsDistribFunEqual(pBNet1->GetFactor(1), eps) )
    {
	ret = TRS_FAIL;
    }
    
    
    for( i = 0; i < nEvidences; i++)
    {
	delete evidences[i];
    }
    delete pLearn;
    delete pBNet1;
    delete pBNet;

    
    return trsResult( ret, ret == TRS_OK ? "No errors" : 
    "Bad test on SetStatistics");
    
    
}
Exemple #28
0
void cfactor_setCounts(CFactor &fac, vector<map<size_t, int> > & counts) {
	fac.counts() = counts;
}
Exemple #29
0
int main()
{
    PNL_USING
	//we create very small model to start inference on it
	// the model is from Kevin Murphy's BNT\examples\static\belprop_polytree_gaussain
	/*
	Do the example from Satnam Alag's PhD thesis, UCB ME dept 1996 p46
	Make the following polytree, where all arcs point down
	
	 0   1
	  \ /
	   2
	  / \
	 3   4


	*/
	int i;
	//create this model
	int nnodes = 5;
	int numnt = 2;
	CNodeType *nodeTypes = new CNodeType[numnt];
 	nodeTypes[0] = CNodeType(0,2);
	nodeTypes[1] = CNodeType(0,1);
	
	intVector nodeAssociation = intVector(nnodes,0);
	nodeAssociation[1] = 1;
	nodeAssociation[3] = 1;
	int nbs0[] = { 2 };
	int nbs1[] = { 2 };
	int nbs2[] = { 0, 1, 3, 4 };
	int nbs3[] = { 2 };
	int nbs4[] = { 2 };
	int *nbrs[] = { nbs0, nbs1, nbs2, nbs3, nbs4 };
	int numNeighb[] = {1, 1, 4, 1, 1};

	
	ENeighborType ori0[] = { ntChild };
	ENeighborType ori1[] = { ntChild };
	ENeighborType ori2[] = { ntParent, ntParent, ntChild, ntChild };
	ENeighborType ori3[] = { ntParent };
	ENeighborType ori4[] = { ntParent };
	ENeighborType *orient[] = { ori0, ori1, ori2, ori3, ori4 }; 
	
	
	CGraph *pGraph;
	pGraph = CGraph::Create(nnodes, numNeighb, nbrs, orient);
	
	CBNet *pBNet;
	
	pBNet = CBNet::Create( nnodes, numnt, nodeTypes, &nodeAssociation.front(), pGraph );
	//Allocation space for all factors of the model
	pBNet->AllocFactors();
	
	for( i = 0; i < nnodes; i++ )
	{
	    //Allocation space for all matrices of CPD
	    pBNet->AllocFactor(i);
	}
	
	//now we need to create data for CPDs - we'll create matrices
	CFactor *pCPD;
	floatVector smData = floatVector(2,0.0f);
	floatVector bigData = floatVector(4,1.0f);
	intVector ranges = intVector(2, 1);
	ranges[0] = 2;
	smData[0] = 1.0f;
	CNumericDenseMatrix<float> *mean0 = CNumericDenseMatrix<float>::
        Create( 2, &ranges.front(), &smData.front());
	bigData[0] = 4.0f;
	bigData[3] = 4.0f;
	ranges[1] = 2;
	CNumericDenseMatrix<float> *cov0 = CNumericDenseMatrix<float>::
        Create( 2, &ranges.front(), &bigData.front());
	pCPD = pBNet->GetFactor(0);
	pCPD->AttachMatrix(mean0, matMean);
	pCPD->AttachMatrix(cov0, matCovariance);
	ranges[0] = 1;
	ranges[1] = 1;
	float val = 1.0f;
	CNumericDenseMatrix<float> *mean1 = CNumericDenseMatrix<float>::
        Create( 2, &ranges.front(), &val );
	CNumericDenseMatrix<float> *cov1 = CNumericDenseMatrix<float>::
        Create( 2, &ranges.front(), &val );
	pCPD = pBNet->GetFactor(1);
	pCPD->AttachMatrix(mean1, matMean);
	pCPD->AttachMatrix(cov1, matCovariance);
	smData[0] = 0.0f;
	smData[1] = 0.0f;
	ranges[0] = 2;
	CNumericDenseMatrix<float> *mean2 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &smData.front());
	smData[0] = 2.0f;
	smData[1] = 1.0f;
	CNumericDenseMatrix<float> *w21 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &smData.front());
	bigData[0] = 2.0f;
	bigData[1] = 1.0f;
	bigData[2] = 1.0f;
	bigData[3] = 1.0f;
	ranges[1] = 2;
	CNumericDenseMatrix<float> *cov2 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &bigData.front());
	bigData[0] = 1.0f;
	bigData[1] = 2.0f;
	bigData[2] = 1.0f;
	bigData[3] = 0.0f;
	CNumericDenseMatrix<float> *w20 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &bigData.front());
	pCPD = pBNet->GetFactor(2);
	pCPD->AttachMatrix( mean2, matMean );
	pCPD->AttachMatrix( cov2, matCovariance );
	pCPD->AttachMatrix( w20, matWeights,0 );
	pCPD->AttachMatrix( w21, matWeights,1 );
	
	val = 0.0f;
	ranges[0] = 1;
	ranges[1] = 1;
	CNumericDenseMatrix<float> *mean3 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &val);
	val = 1.0f;
	CNumericDenseMatrix<float> *cov3 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &val);
	ranges[1] = 2;
	smData[0] = 1.0f;
	smData[1] = 1.0f;
	CNumericDenseMatrix<float> *w30 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &smData.front());
	pCPD = pBNet->GetFactor(3);
	pCPD->AttachMatrix( mean3, matMean );
	pCPD->AttachMatrix( cov3, matCovariance );
	pCPD->AttachMatrix( w30, matWeights,0 );

	ranges[0] = 2; 
	ranges[1] = 1;
	smData[0] = 0.0f;
	smData[1] = 0.0f;
	CNumericDenseMatrix<float> *mean4 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &smData.front());
	ranges[1] = 2;
	bigData[0] = 1.0f;
	bigData[1] = 0.0f;
	bigData[2] = 0.0f;
	bigData[3] = 1.0f;
	CNumericDenseMatrix<float> *cov4 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &bigData.front());
	bigData[2] = 1.0f;
	CNumericDenseMatrix<float> *w40 = CNumericDenseMatrix<float>::
        Create(2, &ranges.front(), &bigData.front());
	pCPD = pBNet->GetFactor(4);
	pCPD->AttachMatrix( mean4, matMean );
	pCPD->AttachMatrix( cov4, matCovariance );
	pCPD->AttachMatrix( w40, matWeights,0 );

	//Generate random evidences for the modes
	int nEv = 1000;
	pEvidencesVector evid;
	pBNet->GenerateSamples( &evid, nEv );
	/////////////////////////////////////////////////////////////////////
		
	//Create copy of initial model with random matrices 
	CGraph *pGraphCopy = CGraph::Copy(pGraph); 
	CBNet *pLearnBNet = CBNet::CreateWithRandomMatrices(pGraphCopy, pBNet->GetModelDomain() );
	
	// Creating learning process	
	CEMLearningEngine *pLearn = CEMLearningEngine::Create(pLearnBNet);

	pLearn->SetData(nEv, &evid.front());
	pLearn->Learn();
	CNumericDenseMatrix<float> *pMatrix;
	int length = 0;
	const float *output;
	
	///////////////////////////////////////////////////////////////////////
	std::cout<<" results of learning (number of evidences = "<<nEv<<std::endl;
	for (i = 0; i < nnodes; i++ )
	{
	    int j;
	    std::cout<<"\n matrix mean for node "<<i;
	    std::cout<<"\n initial BNet \n";
	    pMatrix = static_cast<CNumericDenseMatrix<float>*>
		(pBNet->GetFactor(i)->GetMatrix(matMean));
	    pMatrix->GetRawData(&length, &output);
	    for ( j = 0; j < length; j++ )
	    {
		std::cout<<" "<<output[j];
	    }
	    std::cout<<"\n BNet with random matrices after learning \n ";
	    pMatrix = static_cast<CNumericDenseMatrix<float>*>
		(pLearnBNet->GetFactor(i)->GetMatrix(matMean));
	    pMatrix->GetRawData(&length, &output);
	    for ( j = 0; j < length; j++)
	    {
		std::cout<<" "<<output[j];
	    }
	    
    	    std::cout<<"\n \n matrix covariance for node "<<i<<'\n';
	    std::cout<<"\n initial BNet \n";

	    pMatrix = static_cast<CNumericDenseMatrix<float>*>
		(pBNet->GetFactor(i)->GetMatrix(matCovariance));
	    pMatrix->GetRawData(&length, &output);
	    for (j = 0; j < length; j++ )
	    {
		std::cout<<" "<<output[j];
	    }
    	    std::cout<<"\n BNet with random matrices after learning \n ";
	    pMatrix = static_cast<CNumericDenseMatrix<float>*>
		(pLearnBNet->GetFactor(i)->GetMatrix(matCovariance));
	    pMatrix->GetRawData(&length, &output);
	    for ( j = 0; j < length; j++ )
	    {
		std::cout<<" "<<output[j];
	    }

	    std::cout<<"\n ___________________________\n";
	    
	}
	
	
	for( i = 0; i < nEv; i++)
	{
	    delete evid[i];
	}
	delete pLearn;
	delete pLearnBNet;
	delete pBNet;
	
	

return 1;
}
void CSoftMaxCPD::CreateMeanAndCovMatrixForNode(int Node, const CEvidence* pEvidence, 
    const CBNet *pBNet, floatVector &Mean, 
    C2DNumericDenseMatrix<float>**CovContParents) const
{
    int i, j, k;
    int *multiindex = new int [2];
    intVector contParents;
    pBNet->GetContinuousParents(Node, &contParents);
                   
    intVector lineSizes;
    lineSizes.assign(2, contParents.size());
    floatVector zerodata;
    zerodata.assign(contParents.size()*contParents.size(), 0.0f);
    
    *CovContParents = 
        C2DNumericDenseMatrix<float>::Create( &lineSizes.front(), &zerodata.front() );
    for (i = 0; i < contParents.size(); i++ )    
    {
        for (j = 0; j < contParents.size(); j++ )
        {
            multiindex[0] = i;
            multiindex[1] = j;
            (*CovContParents)->SetElementByIndexes(0.0f, multiindex);
        }
    }
 
    intVector pObsNodes;
    pConstValueVector pObsValues;
    pConstNodeTypeVector pNodeTypes;
    pEvidence->GetObsNodesWithValues(&pObsNodes, &pObsValues, &pNodeTypes);

    Mean.resize(0);
    for ( i = 0; i < contParents.size(); i++)
    { 
       int CurNode = contParents[i];  
       CFactor *param;
       param = pBNet->GetFactor(CurNode);
       intVector parentOut;
       intVector DiscrParents;
       pBNet->GetDiscreteParents(CurNode, &DiscrParents);
          
       int *parentComb = new int [DiscrParents.size()];
    
       for ( j = 0; j < DiscrParents.size(); j++)
       {
            for ( k = 0; k < pObsNodes.size(); k++)
            {
                if (DiscrParents[j] == pObsNodes[k])
                {
                    parentComb[j] = pObsValues[k]->GetInt();
                    break;
                }
            }
       }
                    
       const float *data;
       int datasize;
                    
       static_cast<CDenseMatrix<float>*>(param->GetMatrix(matMean, -1, parentComb))->
           GetRawData(&datasize, &data);
       Mean.push_back(data[0]);
                    
       static_cast<CDenseMatrix<float>*>(param->GetMatrix(matCovariance, -1, parentComb))->
           GetRawData(&datasize, &data);
       multiindex[0] = i;
       multiindex[1] = i;
       (*CovContParents)->SetElementByIndexes(data[0], multiindex);
       delete [] parentComb;
    }
    delete [] multiindex;
}