void CSamplingInfEngine::
CreateSamplingPotentials( potsPVector* potsToSampling )
{
    
    CModelDomain *pMD = GetModel()->GetModelDomain();
    
    intVector ndsForSampling;
    GetNdsForSampling( &ndsForSampling );
    potsToSampling->resize( ndsForSampling.size() );
    
    CPotential *tmpPot;
    
    int i;
    for( i = 0; i < ndsForSampling.size(); i++ )
    {
        const CNodeType* nt = pMD->GetVariableType( ndsForSampling[i]);
        if( nt->IsDiscrete() )
        {
            tmpPot = CTabularPotential::
                Create( &ndsForSampling[i], 1, pMD, &floatVector(nt->GetNodeSize(), 1.0f).front() );
        }
        else
        {
            tmpPot = CGaussianPotential::
                CreateUnitFunctionDistribution( &ndsForSampling[i], 1, pMD );
        }
        (*potsToSampling)[i] = tmpPot;
    }
}
void CSamplingInfEngine::
FindEnvironment( intVecVector *chlds )
{
    
    
    const CGraph *pGraph = m_pGraphicalModel->GetGraph();
    int i;
    if( GetModel()->GetModelType() != mtBNet )
    {
        int nnodes; 
        nnodes = GetModel()->GetNumberOfNodes();
        chlds->resize( nnodes );
        const CMNet* pMNet = static_cast<const CMNet*>( m_pGraphicalModel );
        
        for( i = 0; i < nnodes; i++ )
        {
            
            pMNet->GetClqsNumsForNode( i, &(*chlds)[i] );
        }
    }
    else
    {
        intVector ndsForSampling;
        GetNdsForSampling( &ndsForSampling );
        chlds->resize( ndsForSampling.size() );
        
        for( i = 0; i < ndsForSampling.size(); i++ )
        {
            pGraph->GetChildren( ndsForSampling[i], &(*chlds)[i] );
            (*chlds)[i].push_back( ndsForSampling[i]) ;
        }
        
    }
    
}
void CGibbsSamplingInfEngine::
Sampling( int statTime, int endTime )
{
  
  intVector ndsForSampling;
  GetNdsForSampling( &ndsForSampling );
  boolVector sampleIsNeed;
  GetSamplingNdsFlags( &sampleIsNeed );
  
  int numNdsForSampling = ndsForSampling.size();
  
  pEvidencesVector currentEvidences;
  GetCurrentEvidences( &currentEvidences );
  CEvidence * pCurrentEvidence;
  
  int t; 
  int i;
  for( t = statTime; t < endTime; t++ )
  {
    int series;
    for( series = 0; series < GetNumStreams(); series++ )
    {
      pCurrentEvidence = currentEvidences[series];
      
      
      for( i = 0; i < numNdsForSampling; i++ )
      {
        if( sampleIsNeed[i] )
        {
          pCurrentEvidence->ToggleNodeStateBySerialNumber(1, &i);
          bool canBeSample = ConvertingFamilyToPot( ndsForSampling[i], pCurrentEvidence );
          if(canBeSample)
          {
            
            GetPotToSampling(ndsForSampling[i])->GenerateSample( pCurrentEvidence, m_bMaximize );
          }
          else
          {
            pCurrentEvidence->ToggleNodeStateBySerialNumber(1, &i);
          }
        }
        
      }	
      
    }
    if( t > GetBurnIn())
    {
      pFactorVector queryFactors;
      GetQueryFactors( &queryFactors );
      int i;
      for( i = 0; i < queryFactors.size(); i++ )
      {
        queryFactors[i]->UpdateStatisticsML( &(GetCurrentEvidences()->front()), GetNumStreams() );
      }  
      
    }
  }
  
}
void CSamplingInfEngine::FindCurrentNdsForSampling(boolVector *flags) const
{
    intVector ndsForSampling;
    GetNdsForSampling(&ndsForSampling);
    
    int nnds = ndsForSampling.size();
    
    const CEvidence *pEv = m_pEvidence;
    flags->assign(nnds, true);
    int i;
    for( i = 0; i < nnds; i++ )
    {
	if( pEv->IsNodeObserved(ndsForSampling[i]) )
	{
	    (*flags)[i] = false;
	}
    }
}