00001
00004
00005
00006
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
00022
00023
00024
00025
00026
00027
00028
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
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
00053 std::string DiscreteDensityFunction::ToString(void) const {
00054 TokenWriter tw(TokenWriter::String);
00055 Write(tw);
00056 return tw.Str();
00057 }
00058
00059
00060 void DiscreteDensityFunction::Write(void) const {
00061 TokenWriter tw(TokenWriter::Stdout);
00062 Write(tw);
00063 }
00064
00065
00066 void DiscreteDensityFunction::Read(TokenReader& rTr) {
00067 Clear();
00068 rTr.ReadBegin("Density");
00069 rTr.ReadEnd("Density");
00070 }
00071
00072
00073
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
00091 void DiscreteDensityFunction::Compile(void) const {
00092 DiscreteDensityFunction* fakeconst = const_cast<DiscreteDensityFunction*>(this);
00093 fakeconst->CompileNonConst();
00094 }
00095
00096
00097 void DiscreteDensityFunction::CompileNonConst(void) {
00098 FD_DX("DiskreteDensityFunction::Compile(" << mName << ")");
00099 if(mValueMap.size()<1) return;
00100
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;
00106 double norm=1/integral;
00107 for(Iterator mit=Begin() ;mit!=End(); mit++) {
00108 mit->second.value*= norm;
00109 };
00110
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;
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
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;
00128
00129 mAverage= mSum;
00130 mVariance=sqrt(fabs(mSquareSum - mSum*mSum));
00131
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
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
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
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
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
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 SampledDensityFunction::SampledDensityFunction(void) : DiscreteDensityFunction(),
00222 mDim(100), mCountSum(0), mCountSquareSum(0)
00223 {
00224 }
00225
00226
00227
00228
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
00239 void SampledDensityFunction::Sample(tpTime::Type duration) {
00240
00241 FD_DX("SampledDensityFunction::Sample(" << Name() << "): duration " << duration);
00242 FD_DX(SStr());
00243
00244 if(duration<0) return;
00245
00246 mCount++;
00247 mCountSum+=duration;
00248 mCountSquareSum+=duration*duration;
00249
00250 CountIterator mit = mCountMap.lower_bound(duration);
00251
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
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
00269 if(mCountMap.size()<=mDim)
00270 return;
00271
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;
00283
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
00293 void SampledDensityFunction::CompileNonConst(void) {
00294 FD_DX("SampledDensityFunction::Compile(" << mName << ")");
00295 FD_DX(SStr());
00296 if(mCountMap.size()<1) return;
00297
00298
00299 double count=mCount;
00300
00301
00302 mValueMap.clear();
00303
00304
00305 if(count<=0) return;
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
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()) {
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
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
00354 DiscreteDensityFunction::CompileNonConst();
00355
00356
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
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 }
00378