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 
14 namespace faudes {
15 
16 /*
17 ***********************************************************
18 ***********************************************************
19 ***********************************************************
20 
21 implementation 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 {
33  mEntryZero.value=0;
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()
56 std::string DiscreteDensityFunction::ToString(void) const {
58  Write(tw);
59  return tw.Str();
60 }
61 
62 // Write()
65  Write(tw);
66 }
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;
88  mQuantile05=0;
89  mQuantile95=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
184 double DiscreteDensityFunction::Value(tpTime::Type time) const { return EntryAt(time).value; }
186 
187 // pretty string (should resample)
188 std::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  return ss.str();
205 }
206 
207 
208 /*
209 ***********************************************************
210 ***********************************************************
211 ***********************************************************
212 
213 implementation of sampled density function approximattion
214 
215 ***********************************************************
216 ***********************************************************
217 ***********************************************************
218 */
219 
220 
221 
222 // construct
224  mDim(100), mCountSum(0), mCountSquareSum(0)
225 {
226 }
227 
228 
229 
230 // clear all
232  FD_DX("SampledDensityFunction::Clear()");
234  mCount=0;
235  mCountSum=0;
236  mCountSquareSum=0;
237  mCountMap.clear();
238 }
239 
240 // add one sample
242  // report
243  FD_DX("SampledDensityFunction::Sample(" << Name() << "): duration " << duration);
244  FD_DX(SStr());
245  // bail out on negative duration (error)
246  if(duration<0) return;
247  // record
248  mCount++;
249  mCountSum+=duration;
250  mCountSquareSum+=duration*duration;
251  // cases ...
252  CountIterator mit = mCountMap.lower_bound(duration);
253  // ... do we have a range? just count
254  if(mit!=mCountMap.end()) {
255  if(mit->second.timeint.In(duration)) {
256  FD_DX("SampledDensityFunction::Sample(): range found, count");
257  mit->second.count+=1;
258  return;
259  }
260  }
261  // insert tailord support
262  FD_DX("SampledDensityFunction::Sample(): insert tailored support");
263  CountEntry tent;
264  tent.timeint.UB(duration);
265  tent.timeint.LB(duration);
266  tent.timeint.UBincl(true);
267  tent.timeint.LBincl(true);
268  tent.count=1;
269  mCountMap[duration]=tent;
270  // dim ok? done
271  if(mCountMap.size()<=mDim)
272  return;
273  // merge intervals
274  FD_DX("SampledDensityFunction::Sample(): merge");
275  CountIterator mit1=mCountMap.begin();
276  CountIterator mit2=mCountMap.begin();
277  CountIterator mmit;
278  double minarea = -1;
279  for(mit2++; mit2!=mCountMap.end(); mit1++, mit2++) {
280  tpTime::Type dur = mit2->second.timeint.UB() - mit1->second.timeint.LB();
281  double area = dur * (mit2->second.count + mit1->second.count);
282  if(area < minarea || minarea <0) { minarea=area; mmit=mit1;}
283  }
284  if(mit2==mCountMap.end()) return; // error!
285  // merge intervals
286  mit2=mmit;
287  mit2++;
288  mmit->second.timeint.Merge(mit2->second.timeint);
289  mmit->second.count += mit2->second.count;
290  mCountMap.erase(mit2);
291 }
292 
293 
294 // compute (incl normalize)
296  FD_DX("SampledDensityFunction::Compile(" << mName << ")");
297  FD_DX(SStr());
298  if(mCountMap.size()<1) return; // error
299 
300  // convert count
301  double count=mCount;
302 
303  // clear main data
304  mValueMap.clear();
305 
306  // copy
307  if(count<=0) return; // error
308  for(CountIterator mit=mCountMap.begin() ;mit!=mCountMap.end(); mit++) {
309  Entry tent;
310  tent.timeint = mit->second.timeint;
311  tent.value = ((double) mit->second.count);
312  mValueMap[tent.timeint.LB()]=tent;
313  }
314 
315  // fix bounds: insert (assume all closed)
316  if(mCountMap.size()<mDim/2)
317  for(Iterator mit=Begin() ;mit!=End(); mit++) {
318  Iterator nit=mit;
319  nit++;
320  if(nit!=End())
321  if(mit->second.timeint.UB() + 1 != nit->second.timeint.LB()) { // todo: float time
322  Entry tent;
323  tent.timeint.LB(mit->second.timeint.UB() + 1);
324  tent.timeint.UB(nit->second.timeint.LB() - 1);
325  tent.timeint.LBincl(false);
326  tent.timeint.UBincl(false);
327  tent.value = 0;
328  mValueMap[tent.timeint.LB()]=tent;
329  }
330  }
331 
332  // fix bounds: extend over gaps (assume all closed, turn to right open)
333  for(Iterator mit=Begin() ;mit!=End(); mit++) {
334  Iterator nit=mit;
335  nit++;
336  mit->second.timeint.UBincl(false);
337  mit->second.timeint.LBincl(true);
338  mit->second.timeint.UB(mit->second.timeint.UB()+1);
339  if(nit!=End())
340  if(mit->second.timeint.UB() != nit->second.timeint.LB()) {
341  double middle = 0.5*(mit->second.timeint.UB() + nit->second.timeint.LB());
342  tpTime::Type dmiddle=((tpTime::Type) middle);
343  if(dmiddle <= mit->second.timeint.LB()) dmiddle= nit->second.timeint.LB();
344  mit->second.timeint.UB(dmiddle);
345  nit->second.timeint.LB(dmiddle);
346  }
347  if(nit==End())
348  if(mit->second.timeint.UB() <= mit->second.timeint.LB())
349  mit->second.timeint.UB(mit->second.timeint.LB()+1);
350 
351  mit->second.value=mit->second.value /
352  (mit->second.timeint.UB() - mit->second.timeint.LB());
353  }
354 
355  // compile base
357 
358  // fix characteristics
359  mAverage=mCountSum/count;
360  mVariance=sqrt(1.0/ count * fabs(
361  mCountSquareSum - (1.0/count*((double)mCountSum)*((double)mCountSum))) );
362 
364 }
365 
366 
367 
368 // pretty string
369 std::string SampledDensityFunction::SStr(void) const {
370  std::stringstream ss;
371  ss << "Sampled Density \"" << mName <<"\"";
372  for(CCountIterator mit=mCountMap.begin(); mit!=mCountMap.end(); mit++) {
373  ss << "(-- " << mit->second.timeint.Str() << " " << mit->second.count << " --)";
374  }
375  return ss.str();
376 }
377 
378 
379 } // namespace faudes
380 

libFAUDES 2.26g --- 2015.08.17 --- c++ api documentaion by doxygen