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(Time::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  std::string res= ss.str();
205  return res;
206 }
207 
208 
209 /*
210 ***********************************************************
211 ***********************************************************
212 ***********************************************************
213 
214 implementation 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;
237  mCountSquareSum=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
370 std::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
Length of strings for text fields in token output.
double Value(Time::Type time) const
std::map< Time::Type, Entry > mValueMap
const TimeInterval & TimeInt(Time::Type time) const
CIterator End(void) const
const Entry & EntryAt(Time::Type time) const
std::map< Time::Type, Entry >::iterator Iterator
const std::string & Name(void) const
CIterator Begin(void) const
void Read(TokenReader &rTr)
std::string ToString(void) const
Time::Type MaxTime(void) const
std::string Str(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
virtual void CompileNonConst(void)
void Sample(Time::Type time)
std::map< Time::Type, CountEntry > mCountMap
Model of a time interval.
void LB(Time::Type time)
Set the lower bound to a given value.
void SetPositive(void)
Set to positive [0, inf)
void UBincl(bool incl)
Configures the upper bound to be inclusive.
void LBincl(bool incl)
Configures the lower bound to be inclusive.
void UB(Time::Type time)
Set the upper bound to a given value.
Int Type
Datatype for point on time axis.
A TokenReader reads sequential tokens from a file or string.
void ReadEnd(const std::string &rLabel)
Close the current section by matching the previous ReadBegin().
void ReadBegin(const std::string &rLabel)
Open a section by specified label.
A TokenWriter writes sequential tokens to a file, a string or stdout.
std::string Str(void)
Retrieve output as string (if in String mode)
void WriteFloat(const double &val)
Write float.
void WriteEnd(const std::string &rLabel)
Write end label.
int Columns(void) const
Get number of columns in a line.
void WriteBegin(const std::string &rLabel)
Write begin label.
Tokens model atomic data for stream IO.
Definition: cfl_token.h:53
libFAUDES resides within the namespace faudes.
std::string ExpandString(const std::string &rString, unsigned int len)
Fill string with spaces up to a given length if length of the string is smaller than given length par...
Definition: cfl_helper.cpp:80
std::string ToStringFloat(Float number)
float to string
Definition: cfl_helper.cpp:64
Discrete density function approximation.
Execute transitions in a timed generator
#define FD_DX(message)
Definition: sp_executor.h:27

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen