libFAUDES

Sections

Index

sp_densityfnct.cpp

Go to the documentation of this file.
00001 /** @file sp_densityfnct.cpp  Discrete density function approximation */
00002 
00003 
00004 /* 
00005    Copyright (C) 2008  Thomas Moor
00006    Exclusive copyright is granted to Klaus Schmidt
00007 */
00008 
00009 #include "sp_densityfnct.h"
00010 #include "sp_executor.h"
00011 
00012 #include <cmath>
00013 
00014 namespace faudes {
00015 
00016 /*
00017 ***********************************************************
00018 ***********************************************************
00019 ***********************************************************
00020 
00021 implementation of density function approximattion
00022 
00023 ***********************************************************
00024 ***********************************************************
00025 ***********************************************************
00026 */
00027 
00028 // construct
00029 DiscreteDensityFunction::DiscreteDensityFunction(void) : 
00030   mCount(0), mMaxValue(0), mMinValue(0), mMaxTime(0), mMinTime(0), mSum(0), mSquareSum(0), mAverage(0), mVariance(0), mQuantile05(0), mQuantile95(0) 
00031 { 
00032 }
00033 
00034 //Write(rTw);
00035 void DiscreteDensityFunction::Write(TokenWriter& rTw) const {
00036   Token token;
00037   rTw.WriteBegin("Density");
00038   rTw << Name();
00039   int oldcolumns = rTw.Columns();
00040   rTw.Columns(3);
00041   rTw << "\n";
00042   for(CIterator mit=Begin(); mit!=End(); mit++) {
00043     if(mit->second.value==0) continue;
00044     rTw.WriteFloat(mit->second.timeint.LB());
00045     rTw.WriteFloat(mit->second.timeint.UB());
00046     rTw.WriteFloat(mit->second.value);
00047   }
00048   rTw.Columns(oldcolumns);
00049   rTw.WriteEnd("Density");
00050 }
00051 
00052 // ToString()
00053 std::string DiscreteDensityFunction::ToString(void) const {
00054   TokenWriter tw(TokenWriter::String);
00055   Write(tw);
00056   return tw.Str();
00057 }
00058 
00059 // Write()
00060 void DiscreteDensityFunction::Write(void) const {
00061   TokenWriter tw(TokenWriter::Stdout);
00062   Write(tw);
00063 }    
00064 
00065 //Read(rTr)
00066 void DiscreteDensityFunction::Read(TokenReader& rTr) {
00067   Clear();
00068   rTr.ReadBegin("Density");
00069   rTr.ReadEnd("Density");
00070 }
00071 
00072 
00073 // reset all
00074 void DiscreteDensityFunction::Clear(void) {
00075  FD_DX("DiscreteDensityFunction::Clear()");
00076  mValueMap.clear();
00077  mMinValue=0;
00078  mMaxValue=0;
00079  mMinTime=0;
00080  mMaxTime=0;
00081  mSum=0;
00082  mSquareSum=0;
00083  mAverage=0;
00084  mVariance=0;
00085  mQuantile05=0;
00086  mQuantile95=0;
00087  mCount=0;
00088 }
00089 
00090 // const fake version
00091 void DiscreteDensityFunction::Compile(void) const {
00092   DiscreteDensityFunction* fakeconst = const_cast<DiscreteDensityFunction*>(this);
00093   fakeconst->CompileNonConst();
00094 }
00095 
00096 // compute (assume right open intervals) 
00097 void DiscreteDensityFunction::CompileNonConst(void) {
00098   FD_DX("DiskreteDensityFunction::Compile(" << mName << ")");
00099   if(mValueMap.size()<1) return; // error
00100   // normalize
00101   double integral=0;
00102   for(Iterator mit=Begin() ;mit!=End(); mit++) {
00103     integral+= (mit->second.timeint.UB()-mit->second.timeint.LB())* mit->second.value;
00104   };
00105   if(integral==0) return; // error
00106   double norm=1/integral;
00107   for(Iterator mit=Begin() ;mit!=End(); mit++) {
00108     mit->second.value*= norm;
00109   };
00110   // find min, max, and sums
00111   mMinValue=-1;
00112   mMaxValue=-1;
00113   mMinTime=-1;
00114   mMaxTime=-1;
00115   for(Iterator mit=Begin() ;mit!=End(); mit++) {
00116     if(mMinValue<0 || (mit->second.value < mMinValue)) mMinValue=mit->second.value;
00117     if(mMaxValue<0 || (mit->second.value > mMaxValue)) mMaxValue=mit->second.value;
00118     double time = (mit->second.timeint.UB() -1  + mit->second.timeint.LB()) / 2.0; // discrete time
00119     double prob = (mit->second.timeint.UB() - mit->second.timeint.LB()) * mit->second.value; 
00120     mSum=mSum + time * prob;
00121     mSquareSum=mSquareSum= time*time*prob;
00122   }
00123   // min and max
00124   if(mMinValue<0) mMinValue=0;
00125   if(mMaxValue<0) mMaxValue=0;
00126   mMinTime=Begin()->second.timeint.LB();
00127   mMaxTime=(--End())->second.timeint.UB() -1; // discrete time;
00128   // avaerage and variance
00129   mAverage= mSum;
00130   mVariance=sqrt(fabs(mSquareSum - mSum*mSum)); // fix!!
00131   // quantile 05  (todo: inspect/test/fix)
00132   mQuantile05=mMinTime;
00133   integral=0;
00134   double len=0, area=0;
00135   Iterator mit;
00136   for(mit=Begin() ;mit!=End(); mit++) {
00137     len = mit->second.timeint.UB()-mit->second.timeint.LB(); 
00138     area=len* mit->second.value;
00139     if(integral + area >= 0.05) break;
00140     integral = integral + area;
00141   }
00142   if((mit!=End()) && (integral + area >= 0.05)) {
00143     if(mit->second.value>0.01) 
00144       mQuantile05 = mit->second.timeint.LB() + (0.05-integral)/mit->second.value;
00145     else 
00146       mQuantile05 = mit->second.timeint.LB() + len/2;
00147   }
00148   if(mQuantile05<=mMinTime) mQuantile05=mMinTime;
00149   // quantile 95  (todo: inspect/test/fix)
00150   mQuantile95=mMaxTime;
00151   integral=0;
00152   len=0, area=0;
00153   for(mit=End();mit!=Begin(); ) {
00154     mit--;
00155     len = mit->second.timeint.UB()-mit->second.timeint.LB(); 
00156     area=len* mit->second.value;
00157     if(integral + area >= 0.05) break;
00158     integral = integral + area;
00159   }
00160   if(integral +area >= 0.05) {
00161     if(mit->second.value>0.01) 
00162       mQuantile95 = mit->second.timeint.UB() - (0.05-integral)/mit->second.value;
00163     else 
00164       mQuantile95 = mit->second.timeint.UB() - len/2;
00165   }
00166   if(mQuantile95>=mMaxTime) mQuantile95=mMaxTime;
00167 }
00168 
00169 
00170 // get entry, perhaps fake
00171 const DiscreteDensityFunction::Entry DiscreteDensityFunction::EntryAt(tpTime::Type time) const {
00172   CIterator mit= At(time);
00173   if(mit!=End()) return mit->second;
00174   Entry dent;
00175   dent.timeint.SetPositive();
00176   dent.value = 0;
00177   return dent;
00178 }
00179 
00180 
00181 // get value
00182 double DiscreteDensityFunction::Value(tpTime::Type time) const { return EntryAt(time).value; }
00183 const TimeInterval& DiscreteDensityFunction::TimeInt(tpTime::Type time) const { return EntryAt(time).timeint; }
00184 
00185 // pretty string (should resample)
00186 std::string DiscreteDensityFunction::Str(void) const {
00187   std::stringstream ss;
00188   ss << "% Discrete Density \"" << mName <<"\"" <<  " characteristics:" << std::endl;
00189   ss << "% time " << MinTime() << "/" << MaxTime() << std::endl;
00190   ss << "% value " << MinValue() << "/" << MaxValue() << std::endl;
00191   ss << "% quant " << Quantile05() << "/" << Quantile95() << std::endl;
00192   ss << "% stat  " << Average() << "/" << Variance() << std::endl;
00193   for(CIterator mit=Begin();  mit!=End(); mit++) {
00194     if(mit->second.value==0) continue;
00195     ss << "% " << ExpandString(mit->second.timeint.Str(),FD_NAMELEN) << ": " 
00196        << ExpandString(ToStringFloat(mit->second.value), FD_NAMELEN)  << ": ";
00197     double pc=mit->second.value;
00198     double sc= MaxValue()/50.0;
00199     for(; pc>0; pc-=sc) ss << "#";
00200     ss << " " << std::endl;
00201   }
00202   return ss.str();
00203 }
00204 
00205 
00206 /*
00207 ***********************************************************
00208 ***********************************************************
00209 ***********************************************************
00210 
00211 implementation of sampled density function approximattion
00212 
00213 ***********************************************************
00214 ***********************************************************
00215 ***********************************************************
00216 */
00217 
00218 
00219 
00220 // construct
00221 SampledDensityFunction::SampledDensityFunction(void) : DiscreteDensityFunction(), 
00222   mDim(100), mCountSum(0), mCountSquareSum(0) 
00223 { 
00224 }
00225 
00226 
00227 
00228 // clear all
00229 void SampledDensityFunction::Clear(void) {
00230   FD_DX("SampledDensityFunction::Clear()");
00231   DiscreteDensityFunction::Clear(); 
00232   mCount=0; 
00233   mCountSum=0; 
00234   mCountSquareSum=0;
00235   mCountMap.clear();
00236 }
00237 
00238 // add one sample
00239 void SampledDensityFunction::Sample(tpTime::Type duration) {
00240   // report
00241   FD_DX("SampledDensityFunction::Sample(" << Name() << "): duration " << duration);
00242   FD_DX(SStr());
00243   // bail out on negative duration (error)
00244   if(duration<0) return;
00245   // record
00246   mCount++;
00247   mCountSum+=duration;
00248   mCountSquareSum+=duration*duration;
00249   // cases ...
00250   CountIterator mit = mCountMap.lower_bound(duration);
00251   // ... do we have a range? just count
00252   if(mit!=mCountMap.end()) {
00253     if(mit->second.timeint.In(duration)) {
00254       FD_DX("SampledDensityFunction::Sample(): range found, count");
00255       mit->second.count+=1;
00256       return;
00257     }
00258   }
00259   //  insert tailord support
00260   FD_DX("SampledDensityFunction::Sample(): insert tailored support");
00261   CountEntry tent;
00262   tent.timeint.UB(duration);
00263   tent.timeint.LB(duration);
00264   tent.timeint.UBincl(true);
00265   tent.timeint.LBincl(true);
00266   tent.count=1;
00267   mCountMap[duration]=tent;
00268   // dim ok? done 
00269   if(mCountMap.size()<=mDim)
00270     return;
00271   // merge intervals
00272   FD_DX("SampledDensityFunction::Sample(): merge");
00273   CountIterator mit1=mCountMap.begin();
00274   CountIterator mit2=mCountMap.begin();
00275   CountIterator mmit;
00276   double minarea = -1;
00277   for(mit2++; mit2!=mCountMap.end(); mit1++, mit2++) {
00278     tpTime::Type dur  =  mit2->second.timeint.UB() - mit1->second.timeint.LB();
00279     double area =  dur * (mit2->second.count + mit1->second.count);
00280     if(area < minarea || minarea <0) { minarea=area; mmit=mit1;}
00281   }
00282   if(mit2==mCountMap.end()) return; // error!
00283   // merge intervals
00284   mit2=mmit;
00285   mit2++;
00286   mmit->second.timeint.Merge(mit2->second.timeint);
00287   mmit->second.count += mit2->second.count;
00288   mCountMap.erase(mit2);
00289 }
00290 
00291 
00292 // compute (incl normalize)
00293 void SampledDensityFunction::CompileNonConst(void) {
00294   FD_DX("SampledDensityFunction::Compile(" << mName << ")");
00295   FD_DX(SStr());
00296   if(mCountMap.size()<1) return; // error
00297 
00298   // convert count
00299   double count=mCount;
00300 
00301   // clear main data
00302   mValueMap.clear();
00303 
00304   // copy
00305   if(count<=0) return; // error
00306   for(CountIterator mit=mCountMap.begin() ;mit!=mCountMap.end(); mit++) {
00307     Entry tent;
00308     tent.timeint = mit->second.timeint;
00309     tent.value = ((double) mit->second.count); 
00310     mValueMap[tent.timeint.LB()]=tent;
00311   } 
00312 
00313   // fix bounds: insert (assume all closed)
00314   if(mCountMap.size()<mDim/2) 
00315   for(Iterator mit=Begin() ;mit!=End(); mit++) {
00316     Iterator nit=mit;
00317     nit++;
00318     if(nit!=End()) 
00319     if(mit->second.timeint.UB() + 1 != nit->second.timeint.LB()) { // todo: float time
00320       Entry tent;
00321       tent.timeint.LB(mit->second.timeint.UB() + 1);
00322       tent.timeint.UB(nit->second.timeint.LB() - 1);
00323       tent.timeint.LBincl(false);
00324       tent.timeint.UBincl(false);
00325       tent.value = 0;
00326       mValueMap[tent.timeint.LB()]=tent;
00327     }    
00328   }
00329 
00330   // fix bounds: extend over gaps (assume all closed, turn to right open)
00331   for(Iterator mit=Begin() ;mit!=End(); mit++) {
00332     Iterator nit=mit;
00333     nit++;
00334     mit->second.timeint.UBincl(false);
00335     mit->second.timeint.LBincl(true);
00336     mit->second.timeint.UB(mit->second.timeint.UB()+1);
00337     if(nit!=End()) 
00338     if(mit->second.timeint.UB() != nit->second.timeint.LB()) {
00339       double middle = 0.5*(mit->second.timeint.UB() + nit->second.timeint.LB());
00340       tpTime::Type dmiddle=((tpTime::Type) middle);
00341       if(dmiddle <= mit->second.timeint.LB()) dmiddle= nit->second.timeint.LB();
00342       mit->second.timeint.UB(dmiddle);
00343       nit->second.timeint.LB(dmiddle);
00344     }
00345     if(nit==End()) 
00346     if(mit->second.timeint.UB() <= mit->second.timeint.LB())
00347        mit->second.timeint.UB(mit->second.timeint.LB()+1);
00348 
00349     mit->second.value=mit->second.value / 
00350        (mit->second.timeint.UB() - mit->second.timeint.LB());
00351   }
00352 
00353   // compile base
00354   DiscreteDensityFunction::CompileNonConst();
00355 
00356   // fix characteristics
00357   mAverage=mCountSum/count;
00358   mVariance=sqrt(1.0/ count * fabs(
00359          mCountSquareSum - (1.0/count*((double)mCountSum)*((double)mCountSum))) );
00360 
00361   FD_DX(DiscreteDensityFunction::Str());
00362 }
00363 
00364 
00365 
00366 // pretty string
00367 std::string SampledDensityFunction::SStr(void) const {
00368   std::stringstream ss;
00369   ss << "Sampled Density \"" << mName <<"\"";
00370   for(CCountIterator mit=mCountMap.begin();  mit!=mCountMap.end(); mit++) {
00371     ss << "(-- " << mit->second.timeint.Str() << " " << mit->second.count << " --)";
00372   }
00373   return ss.str();
00374 }
00375 
00376 
00377 } // namespace faudes
00378 

libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3