/* * libss - efficient posterior approximation using Scaling Series approach * Copyright (C) 2004-2006, Anna Petrovskaya (libss@eonite.com) * All rights reserved. * */ #include #include "sampling.h" #include "misc.h" #include "tree.h" using std::cout; using std::endl; using std::ofstream; /******************************************************************** * * SampleGen * ********************************************************************/ SampleGen::SampleGen(int dimentionality, int extra) { N=dimentionality; T=N+extra; } SampleP SampleGen::gen() { SampleP s=new SampleStruct; s->w=0; s->s=new double[T]; dblArrZero(T,s->s); // cout<<"SG:ALLOC:"<s; delete s; } double SampleGen::dist(SampleP s1, SampleP s2) { SampleP t=gen(s1); dblArrSub(N,t->s,s2->s); double len=dblArrLen(N,t->s); free(t); return len; } void SampleGen::moveG(SampleP s, double sd) { for (int i=0;is[i]+=gaussRand(sd); } } void SampleGen::moveU(SampleP s, double md) { for (int i=0;is[i]+=doubleRand(-md,md); } } void SampleGen::copy(SampleP s, SampleP d) { d->w=s->w; d->d=s->d; dblArrCopy(T,s->s,d->s); } void SampleGen::print(SampleP s) { cout<<"d="<d<<", w="<w<<", s="; dblArrPrint(T,s->s); cout<sg=sg; } TempSamples::~TempSamples() { while (lSamples.size() > 0) { SampleP s=lSamples.front(); lSamples.pop_front(); sg->free(s); } } SampleP TempSamples::get() { SampleP s=sg->gen(); lSamples.push_front(s); return s; } /******************************************************************** * * SampleList * ********************************************************************/ SampleList::SampleList(SampleGen *sg) { this->sg=sg; samples=new SamplePVec; } SampleList::~SampleList() { clear(); delete samples; } SampleP SampleList::get(int i) { return (*samples)[i]; } int SampleList::size() { return samples->size(); } void SampleList::add(SampleP s) { samples->push_back(s); } void SampleList::addCopy(SampleP s) { SampleP newS = sg->gen(s); add(newS); } void SampleList::printStats(int col) { double l,u,mean,mean2; double s=get(0)->s[col]; l=s;u=s; mean=mean2=0; for (int i=0;is[col]; l=std::min(l,s);u=std::max(u,s); mean+=s; mean2+=s*s; } if (size()) { mean/=size(); mean2/=size(); } double std1=sqrt(mean2-(mean*mean)); double var2=0; for (int i=0;is[col]; s-=mean; s*=s; var2+=s; } if (size()) var2/=size(); double std2=sqrt(var2); cout<<"min="<print(lS); cout<<"sample list max:"; sg->print(uS); } void SampleList::getMinMax(SampleP minSample, SampleP maxSample) { SampleP lS=sg->gen(get(0)); SampleP uS=sg->gen(get(0)); for (int i=1;iN;j++) { if (lS->s[j]>s->s[j]) lS->s[j]=s->s[j]; if (uS->s[j]s[j]) uS->s[j]=s->s[j]; } } lS->w=lS->d=uS->w=uS->d=0; sg->copy(lS, minSample); sg->copy(uS, maxSample); sg->free(lS); sg->free(uS); } SampleP SampleList::computeMean() { SampleP mean = sg->gen(); double totalW=0; for (int i=0; iN; j++) { mean->s[j]+=s->w*s->s[j]; } totalW+=s->w; } if (totalW==0) { #ifdef VERBOSE cout<<"SampleList::computeMean: sum of weights is zero."<N; j++) { mean->s[j]/=totalW; } } return mean; } void SampleList::clear() { while (size()>0) { sg->free(get(size()-1)); samples->pop_back(); } } void SampleList::swapSamples(SampleList *sl) { SamplePVec *t; t=sl->samples; sl->samples=samples; samples=t; } void SampleList::writeToFile(const char *fileName) { ofstream outFile(fileName); if (!outFile.is_open()) { cout << "Unable to open file for writing: "<T;j++) { outFile<s[j]<<" "; } outFile<<"]"<error=err; setupError(); } void ModelBase::printSample(SampleP s) { getSG()->print(s); } void ModelBase::printMinMax(SampleList &lst) { SampleP minSample=getSG()->gen(); SampleP maxSample=getSG()->gen(); lst.getMinMax(minSample, maxSample); cout<<"min: "; printSample(minSample); cout<<"max: "; printSample(maxSample); getSG()->free(minSample); getSG()->free(maxSample); } bool ModelBase::withinBounds(__attribute__ ((unused)) SampleP s) { return true; } void ModelBase::setupDiversity(Diversity *d) { d->maxWeight=1.0; d->validParticleCutoff=0.5; } bool ModelBase::checkDiversity(Diversity *d) { d->printStats(); return true; } void ModelBase::setupError() { } /******************************************************************** * * SIR * ********************************************************************/ SIR::SIR(ModelBase *m,int startSamples):samples(m->getSG()) { model=m; nResamples=startSamples; for (int i=0;igetSG()->gen()); } uniformWeights(); zeroNormalizer=false; } SIR::~SIR() { freeSamples(); } void SIR::computeWeights() { int sz=samples.size(); //#pragma omp parallel for for (int i=0;iw=model->computeLikelihood(samples.get(i)); } weightsNormalize(); } void SIR::computeUnnormalizedWeights(Diversity *d) { d->clearStats(); int sz=samples.size(); //#pragma omp parallel for for (int i=0;icomputeLikelihood(samples.get(i)); samples.get(i)->w=w; d->addParticle(w); } } void SIR::computeWeights(Diversity *d) { computeUnnormalizedWeights(d); weightsNormalize(); } void SIR::weightsNormalize() { zeroNormalizer=false; double t=0; for (int i=0;iw; } if (t==0) { zeroNormalizer=true; //cout<<"SIR:weightNorm:ERROR:normalizer is 0:"<w/=t; } } void SIR::uniformWeights() { if (samples.size()==0) { cout<<"WARNING: SIR::uniformWeights: no samples!"<w=w; } } void SIR::freeSamples() { // don't need to do anything, samples and newSamples will clean themselves up } void SIR::resample() { SampleList ns(model->getSG()); //SampleP *ns=new SampleP[nResamples]; if (samples.size()==0) { cout<<"ERROR: SIR::resample: current sample set is empty"<w; while (r<1.0) { while (tsamples.size()) { cout<<"SIR:resample:Error, ran out of samples: nSamples="<w; while (r<1.0) { while (tsamples.size()) { cout<<"SIR:resample:Error, ran out of samples: nSamples="<getSG()->print(samples.get(highestWeightInd())); #ifdef VERBOSE model->printMinMax(samples); cout<<"top: "; model->printSample(samples.get(highestWeightInd())); #endif //samples.printMinMax(); if (delta==deltaDesired) { #ifdef VERBOSE model->checkDiversity(diversity); #endif break; } if (model->checkDiversity(diversity)) { delta=delta/zoom; if (deltazoomRetryMax) { cout<<"SSPF::runSSIS: cannot zoom, ran out of retrys, delta="<=limitTime) { cout<<"SSPF::reachedExitCondition: timeLimit"<=limitSamples) { cout<<"SSPF::reachedExitCondition: sampleLimit"<=validParticleCutoff) { validParticles++; } if (w>highWeight) { highWeight=w; } } void Diversity::printStats() { cout<<"Diversity Stats: delta="<gen(); sol->s[0]=1.232; sol->s[1]=0.23423; sol->s[2]=2.4237; sol->s[3]=4.232; sol->s[4]=5.23423; sol->s[5]=3.4237; } SampleP sol; double computeLikelihood(SampleP s) { //Pt3 p=cPt3(st[0],st[1],st[2]); s->d=getSG()->dist(s,sol); s->w=getGaussianVal(s->d,error/2); return s->w; } }; void testSSPF() { TestModel m; Diversity d; SSPF sspf(&m,1); sspf.samples.get(0)->w=1; sspf.uniformWeightNormalizeCutoff=0.1; sspf.setDeltaRange(10,0.001); sspf.setDiversity(&d); sspf.setParticlesPerDelta(6); sspf.runSSIS(); } void testSIR2(SampleGen *sg) { TempSamples ts(sg); }