sp_densityfnct.cpp
Go to the documentation of this file.
1/** @file sp_densityfnct.cpp Discrete density function approximation */
2
3
4/*
5 Copyright (C) 2008 Thomas Moor
6 Exclusive copyright is granted to Klaus Schmidt
7*/
8
9#include "sp_densityfnct.h"
10#include "sp_executor.h"
11
12#include <cmath>
13
14namespace faudes {
15
16/*
17***********************************************************
18***********************************************************
19***********************************************************
20
21implementation of density function approximattion
22
23***********************************************************
24***********************************************************
25***********************************************************
26*/
27
28// construct
30 mCount(0), mMaxValue(0), mMinValue(0), mMaxTime(0), mMinTime(0), mSum(0), mSquareSum(0), mAverage(0), mVariance(0), mQuantile05(0), mQuantile95(0)
31{
34}
35
36
37//Write(rTw);
39 Token token;
40 rTw.WriteBegin("Density");
41 rTw << Name();
42 int oldcolumns = rTw.Columns();
43 rTw.Columns(3);
44 rTw << "\n";
45 for(CIterator mit=Begin(); mit!=End(); mit++) {
46 if(mit->second.value==0) continue;
47 rTw.WriteFloat(mit->second.timeint.LB());
48 rTw.WriteFloat(mit->second.timeint.UB());
49 rTw.WriteFloat(mit->second.value);
50 }
51 rTw.Columns(oldcolumns);
52 rTw.WriteEnd("Density");
53}
54
55// ToString()
56std::string DiscreteDensityFunction::ToString(void) const {
58 Write(tw);
59 return tw.Str();
60}
61
62// Write()
67
68//Read(rTr)
70 Clear();
71 rTr.ReadBegin("Density");
72 rTr.ReadEnd("Density");
73}
74
75
76// reset all
78 FD_DX("DiscreteDensityFunction::Clear()");
79 mValueMap.clear();
80 mMinValue=0;
81 mMaxValue=0;
82 mMinTime=0;
83 mMaxTime=0;
84 mSum=0;
85 mSquareSum=0;
86 mAverage=0;
87 mVariance=0;
90 mCount=0;
91}
92
93// const fake version
95 DiscreteDensityFunction* fakeconst = const_cast<DiscreteDensityFunction*>(this);
96 fakeconst->CompileNonConst();
97}
98
99// compute (assume right open intervals)
101 FD_DX("DiskreteDensityFunction::Compile(" << mName << ")");
102 if(mValueMap.size()<1) return; // error
103 // normalize
104 double integral=0;
105 for(Iterator mit=Begin() ;mit!=End(); mit++) {
106 integral+= (mit->second.timeint.UB()-mit->second.timeint.LB())* mit->second.value;
107 };
108 if(integral==0) return; // error
109 double norm=1/integral;
110 for(Iterator mit=Begin() ;mit!=End(); mit++) {
111 mit->second.value*= norm;
112 };
113 // find min, max, and sums
114 mMinValue=-1;
115 mMaxValue=-1;
116 mMinTime=-1;
117 mMaxTime=-1;
118 mSum=0;
119 mSquareSum=0;
120 for(Iterator mit=Begin() ;mit!=End(); mit++) {
121 if(mMinValue<0 || (mit->second.value < mMinValue)) mMinValue=mit->second.value;
122 if(mMaxValue<0 || (mit->second.value > mMaxValue)) mMaxValue=mit->second.value;
123 double time = (mit->second.timeint.UB() -1 + mit->second.timeint.LB()) / 2.0; // discrete time
124 double prob = (mit->second.timeint.UB() - mit->second.timeint.LB()) * mit->second.value;
125 mSum=mSum + time * prob;
126 mSquareSum=mSquareSum + time*time*prob;
127 }
128 // min and max
129 if(mMinValue<0) mMinValue=0;
130 if(mMaxValue<0) mMaxValue=0;
131 mMinTime=Begin()->second.timeint.LB();
132 mMaxTime=(--End())->second.timeint.UB() -1; // discrete time;
133 // avaerage and variance
134 mAverage= mSum;
135 mVariance=sqrt(fabs(mSquareSum - mSum*mSum)); // fix!!
136 // quantile 05 (todo: inspect/test/fix)
138 integral=0;
139 double len=0, area=0;
140 Iterator mit;
141 for(mit=Begin() ;mit!=End(); mit++) {
142 len = mit->second.timeint.UB()-mit->second.timeint.LB();
143 area=len* mit->second.value;
144 if(integral + area >= 0.05) break;
145 integral = integral + area;
146 }
147 if((mit!=End()) && (integral + area >= 0.05)) {
148 if(mit->second.value>0.01)
149 mQuantile05 = mit->second.timeint.LB() + (0.05-integral)/mit->second.value;
150 else
151 mQuantile05 = mit->second.timeint.LB() + len/2;
152 }
154 // quantile 95 (todo: inspect/test/fix)
156 integral=0;
157 len=0, area=0;
158 for(mit=End();mit!=Begin(); ) {
159 mit--;
160 len = mit->second.timeint.UB()-mit->second.timeint.LB();
161 area=len* mit->second.value;
162 if(integral + area >= 0.05) break;
163 integral = integral + area;
164 }
165 if(integral +area >= 0.05) {
166 if(mit->second.value>0.01)
167 mQuantile95 = mit->second.timeint.UB() - (0.05-integral)/mit->second.value;
168 else
169 mQuantile95 = mit->second.timeint.UB() - len/2;
170 }
172}
173
174
175// get entry, perhaps fake
177 CIterator mit= At(time);
178 if(mit!=End()) return mit->second;
179 return mEntryZero;
180}
181
182
183// get value
184double DiscreteDensityFunction::Value(Time::Type time) const { return EntryAt(time).value; }
186
187// pretty string (should resample)
188std::string DiscreteDensityFunction::Str(void) const {
189 std::stringstream ss;
190 ss << "% Discrete Density \"" << mName <<"\"" << " characteristics:" << std::endl;
191 ss << "% time " << MinTime() << "/" << MaxTime() << std::endl;
192 ss << "% value " << MinValue() << "/" << MaxValue() << std::endl;
193 ss << "% quant " << Quantile05() << "/" << Quantile95() << std::endl;
194 ss << "% stat " << Average() << "/" << Variance() << std::endl;
195 for(CIterator mit=Begin(); mit!=End(); mit++) {
196 if(mit->second.value==0) continue;
197 ss << "% " << ExpandString(mit->second.timeint.Str(),FD_NAMELEN) << ": "
198 << ExpandString(ToStringFloat(mit->second.value), FD_NAMELEN) << ": ";
199 double pc=mit->second.value;
200 double sc= MaxValue()/50.0;
201 for(; pc>0; pc-=sc) ss << "#";
202 ss << " " << std::endl;
203 }
204 std::string res= ss.str();
205 return res;
206}
207
208
209/*
210***********************************************************
211***********************************************************
212***********************************************************
213
214implementation of sampled density function approximattion
215
216***********************************************************
217***********************************************************
218***********************************************************
219*/
220
221
222
223// construct
225 mDim(100), mCountSum(0), mCountSquareSum(0)
226{
227}
228
229
230
231// clear all
233 FD_DX("SampledDensityFunction::Clear()");
235 mCount=0;
236 mCountSum=0;
238 mCountMap.clear();
239}
240
241// add one sample
243 // report
244 FD_DX("SampledDensityFunction::Sample(" << Name() << "): duration " << duration);
245 FD_DX(SStr());
246 // bail out on negative duration (error)
247 if(duration<0) return;
248 // record
249 mCount++;
250 mCountSum+=duration;
251 mCountSquareSum+=duration*duration;
252 // cases ...
253 CountIterator mit = mCountMap.lower_bound(duration);
254 // ... do we have a range? just count
255 if(mit!=mCountMap.end()) {
256 if(mit->second.timeint.In(duration)) {
257 FD_DX("SampledDensityFunction::Sample(): range found, count");
258 mit->second.count+=1;
259 return;
260 }
261 }
262 // insert tailord support
263 FD_DX("SampledDensityFunction::Sample(): insert tailored support");
264 CountEntry tent;
265 tent.timeint.UB(duration);
266 tent.timeint.LB(duration);
267 tent.timeint.UBincl(true);
268 tent.timeint.LBincl(true);
269 tent.count=1;
270 mCountMap[duration]=tent;
271 // dim ok? done
272 if(mCountMap.size()<=mDim)
273 return;
274 // merge intervals
275 FD_DX("SampledDensityFunction::Sample(): merge");
276 CountIterator mit1=mCountMap.begin();
277 CountIterator mit2=mCountMap.begin();
278 CountIterator mmit;
279 double minarea = -1;
280 for(mit2++; mit2!=mCountMap.end(); mit1++, mit2++) {
281 Time::Type dur = mit2->second.timeint.UB() - mit1->second.timeint.LB();
282 double area = dur * (mit2->second.count + mit1->second.count);
283 if(area < minarea || minarea <0) { minarea=area; mmit=mit1;}
284 }
285 if(mit2==mCountMap.end()) return; // error!
286 // merge intervals
287 mit2=mmit;
288 mit2++;
289 mmit->second.timeint.Merge(mit2->second.timeint);
290 mmit->second.count += mit2->second.count;
291 mCountMap.erase(mit2);
292}
293
294
295// compute (incl normalize)
297 FD_DX("SampledDensityFunction::Compile(" << mName << ")");
298 FD_DX(SStr());
299 if(mCountMap.size()<1) return; // error
300
301 // convert count
302 double count=mCount;
303
304 // clear main data
305 mValueMap.clear();
306
307 // copy
308 if(count<=0) return; // error
309 for(CountIterator mit=mCountMap.begin() ;mit!=mCountMap.end(); mit++) {
310 Entry tent;
311 tent.timeint = mit->second.timeint;
312 tent.value = ((double) mit->second.count);
313 mValueMap[tent.timeint.LB()]=tent;
314 }
315
316 // fix bounds: insert (assume all closed)
317 if(mCountMap.size()<mDim/2)
318 for(Iterator mit=Begin() ;mit!=End(); mit++) {
319 Iterator nit=mit;
320 nit++;
321 if(nit!=End())
322 if(mit->second.timeint.UB() + 1 != nit->second.timeint.LB()) { // todo: float time
323 Entry tent;
324 tent.timeint.LB(mit->second.timeint.UB() + 1);
325 tent.timeint.UB(nit->second.timeint.LB() - 1);
326 tent.timeint.LBincl(false);
327 tent.timeint.UBincl(false);
328 tent.value = 0;
329 mValueMap[tent.timeint.LB()]=tent;
330 }
331 }
332
333 // fix bounds: extend over gaps (assume all closed, turn to right open)
334 for(Iterator mit=Begin() ;mit!=End(); mit++) {
335 Iterator nit=mit;
336 nit++;
337 mit->second.timeint.UBincl(false);
338 mit->second.timeint.LBincl(true);
339 mit->second.timeint.UB(mit->second.timeint.UB()+1);
340 if(nit!=End())
341 if(mit->second.timeint.UB() != nit->second.timeint.LB()) {
342 double middle = 0.5*(mit->second.timeint.UB() + nit->second.timeint.LB());
343 Time::Type dmiddle=((Time::Type) middle);
344 if(dmiddle <= mit->second.timeint.LB()) dmiddle= nit->second.timeint.LB();
345 mit->second.timeint.UB(dmiddle);
346 nit->second.timeint.LB(dmiddle);
347 }
348 if(nit==End())
349 if(mit->second.timeint.UB() <= mit->second.timeint.LB())
350 mit->second.timeint.UB(mit->second.timeint.LB()+1);
351
352 mit->second.value=mit->second.value /
353 (mit->second.timeint.UB() - mit->second.timeint.LB());
354 }
355
356 // compile base
358
359 // fix characteristics
360 mAverage=mCountSum/count;
361 mVariance=sqrt(1.0/ count * fabs(
362 mCountSquareSum - (1.0/count*((double)mCountSum)*((double)mCountSum))) );
363
365}
366
367
368
369// pretty string
370std::string SampledDensityFunction::SStr(void) const {
371 std::stringstream ss;
372 ss << "Sampled Density \"" << mName <<"\"";
373 for(CCountIterator mit=mCountMap.begin(); mit!=mCountMap.end(); mit++) {
374 ss << "(-- " << mit->second.timeint.Str() << " " << mit->second.count << " --)";
375 }
376 return ss.str();
377}
378
379
380} // namespace faudes
381
#define FD_NAMELEN
double Value(Time::Type time) const
std::map< Time::Type, Entry > mValueMap
const TimeInterval & TimeInt(Time::Type time) const
const std::string & Name(void) const
const Entry & EntryAt(Time::Type time) const
std::map< Time::Type, Entry >::iterator Iterator
CIterator Begin(void) const
std::string ToString(void) const
Time::Type MaxTime(void) const
CIterator At(Time::Type time) const
Time::Type MinTime(void) const
std::map< Time::Type, Entry >::const_iterator CIterator
std::map< Time::Type, CountEntry >::iterator CountIterator
std::map< Time::Type, CountEntry >::const_iterator CCountIterator
std::string SStr(void) const
std::map< Time::Type, CountEntry > mCountMap
void LB(Time::Type time)
void UBincl(bool incl)
void LBincl(bool incl)
void UB(Time::Type time)
void ReadEnd(const std::string &rLabel)
void ReadBegin(const std::string &rLabel)
std::string Str(void)
void WriteFloat(const double &val)
void WriteEnd(const std::string &rLabel)
int Columns(void) const
void WriteBegin(const std::string &rLabel)
std::string ExpandString(const std::string &rString, unsigned int len)
Definition cfl_utils.cpp:80
std::string ToStringFloat(Float number)
Definition cfl_utils.cpp:64
#define FD_DX(message)
Definition sp_executor.h:27

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen