|
libFAUDES
Sections
Index
|
sp_densityfnct.cppGo 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