// Plot the enrgy model
void plotEnergyDistrib(MixtureGD &mixt)
{
  unsigned long distribCount = mixt.getDistribCount();
  cout << "EnergyModel"<<endl;
  for (unsigned long c=0; c<distribCount; c++)
    cout << "Component["<<c<<"] Mean["<<mixt.getDistrib(c).getMean(0)<<
		 "] Cov["<<mixt.getDistrib(c).getCov(0)<<"] Weight["<<mixt.weight(c)<<"]"<<endl;
}	
// find the lowest energy component...
unsigned long findMinEnergyDistrib(MixtureGD &mixt)
{
  unsigned long distribCount = mixt.getDistribCount();
  unsigned long cmpMin=0;
  for (unsigned long c=1; c<distribCount; c++)
    if (mixt.getDistrib(c).getMean(0)<mixt.getDistrib(cmpMin).getMean(0))
      cmpMin=c;
  if (verbose) cout << "Lowest component["<<cmpMin<<"] Mean["<<mixt.getDistrib(cmpMin).getMean(0)<<
		 "] Cov["<<mixt.getDistrib(cmpMin).getCov(0)<<"] Weight["<<mixt.weight(cmpMin)<<"]"<<endl;
  return cmpMin; 
}	
//-------------------------------------------------------------------------
void W::writeMixtureGDRaw(const MixtureGD& m)
{
  unsigned long i;
  writeString("GD");
  writeUInt4(m.getId().length());
  writeString(m.getId());
  writeUInt4(m.getDistribCount());

  for (i=0; i< m.getDistribCount(); i++)
  {
    DistribGD& d = m.getDistrib(i);

    writeUInt4(d.dictIndex(K::k));
    writeDouble(m.weight(i));
  }
}
//-------------------------------------------------------------------------
void W::writeMixtureGDXml(const MixtureGD& m)
{
  unsigned long i;
  writeString("\n\t<MixtureGD");
  writeAttribute("id", m.getId());
  writeAttribute("distribCount", m.getDistribCount());
  writeString(">");

  for (i=0; i< m.getDistribCount(); i++)
  {
    DistribGD& d = m.getDistrib(i);
    writeString("\n\t\t<DistribGD");
    writeAttribute("i", i);
    writeAttribute("dictIdx", d.dictIndex(K::k));
    writeAttribute("weight", m.weight(i));
    writeString("/>");
  }
  writeString("\n\t</MixtureGD>");
}
// Main init function
double TopGauss::compute(MixtureGD & UBM,FeatureServer &fs,String & featureFilename,Config & config){
	StatServer ss(config);
	MixtureGDStat &acc=ss.createAndStoreMixtureStat(UBM);	
	unsigned long _mixsize=UBM.getDistribCount();
	String labelSelectedFrames =config.getParam("labelSelectedFrames");
	unsigned long begin=fs.getFirstFeatureIndexOfASource(featureFilename);
	fs.seekFeature(begin);
	SegServer segmentsServer;
	LabelServer labelServer;
	initializeClusters(featureFilename,segmentsServer,labelServer,config);
	//	__android_log_print(ANDROID_LOG_DEBUG, "TopGauss::compute", " Feature file  %s  \n", featureFilename.c_str());

	verifyClusterFile(segmentsServer,fs,config);
	unsigned long codeSelectedFrame=labelServer.getLabelIndexByString(labelSelectedFrames);	
	SegCluster& selectedSegments=segmentsServer.getCluster(codeSelectedFrame);  
	acc.resetLLK();
	double topD=config.getParam("topGauss").toDouble();
	if (verbose) {if(topD<1.0) cout << "LLK %="<< topD << "% ";else cout << "Top-"<<topD<<" ";}
	
	// Class values
	_nt=totalFrame(selectedSegments);	
	_nbg.setSize(_nt); _idx.setSize(0);_snsw.setSize(0); _snsl.setSize(0);
	_nbg.setAllValues(0); _idx.setAllValues(0);_snsw.setAllValues(0.0);_snsl.setAllValues(0.0);
	_nbgcnt=0;
	Seg *seg;          // current selected segment
	selectedSegments.rewind();		
	unsigned long t=0; //cnt frames
	while((seg=selectedSegments.getSeg())!=NULL){                       	
		unsigned long begin=seg->begin()+fs.getFirstFeatureIndexOfASource(seg->sourceName()); 
		fs.seekFeature(begin);
		Feature f;
		for (unsigned long idxFrame=0;idxFrame<seg->length();idxFrame++){
			fs.readFeature(f); 
			double llk=acc.computeAndAccumulateLLK(f,1.0,DETERMINE_TOP_DISTRIBS);
			const LKVector &topV=ss.getTopDistribIndexVector();
			double lk_tot=exp(llk);
			
			double val=0.0;
			if (topD<1.0) {
				for(unsigned long j=0;j<_mixsize;j++){
					if (val > topD*lk_tot) break;
					val+=(topV[j].lk);
					_nbg[t]++;
				}
			} else _nbg[t]=(unsigned long)topD;
			_nbgcnt+=_nbg[t];
			 
			double snsw=1.0;
			double snsl=lk_tot;					
			for(unsigned long j=0;j<_nbg[t];j++) {
				_idx.addValue(topV[j].idx);    		
				snsw -=UBM.weight(topV[j].idx);
				snsl -=topV[j].lk;
			}

			_snsw.addValue(snsw);
			if (snsl < EPS_LK)
				_snsl.addValue(EPS_LK);
			else _snsl.addValue(snsl);
			t++;
		}		
	}
	if (t!=_nt) cout << "W: t("<<t<<") != _nt(" <<_nt<<")"<<endl;
return acc.getMeanLLK();
}