Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JAcoustics/JModel.hh
Go to the documentation of this file.
1 #ifndef __JACOUSTICS__JMODEL__
2 #define __JACOUSTICS__JMODEL__
3 
4 #include <ostream>
5 #include <iomanip>
6 #include <limits>
7 #include <cmath>
8 
9 #include "JMath/JMath.hh"
10 #include "JMath/JZero.hh"
11 #include "JLang/JEquals.hh"
12 #include "JLang/JException.hh"
13 #include "JTools/JHashMap.hh"
15 #include "Jeep/JPrint.hh"
16 
17 #include "JAcoustics/JEKey.hh"
18 
19 
20 /**
21  * \file
22  *
23  * Model for fit to acoutsics data.
24  * \author mdejong
25  */
26 namespace JACOUSTICS {}
27 namespace JPP { using namespace JACOUSTICS; }
28 
29 namespace JACOUSTICS {
30 
33  using JTOOLS::JHashMap;
34 
35 
36  /**
37  * Model for fit to acoustics data.
38  *
39  * The model consists of string parameters and emitter parameters.\n
40  * These parameters relate to the string identifer and emitter key, respectively.
41  */
42  struct JModel :
43  public JMATH::JMath <JModel>,
44  public JLANG::JEquals<JModel>,
46  {
50 
51 
52  /**
53  * Type definition of fit parameter.
54  */
55  typedef size_t parameter_type;
56 
57 
58  /**
59  * String parameters.
60  */
61  struct JString :
62  public JMATH::JMath <JString>,
63  public JLANG::JEquals<JString>
64  {
65  /**
66  * Default constructor.
67  */
68  JString() :
69  tx(0.0),
70  ty(0.0)
71  {}
72 
73 
74  /**
75  * Constructor.
76  *
77  * \param tx slope dx/dz
78  * \param ty slope dy/dz
79  */
80  JString(const double tx,
81  const double ty) :
82  tx(tx),
83  ty(ty)
84  {}
85 
86 
87  /**
88  * Negate string.
89  *
90  * \return this string
91  */
93  {
94  tx = -tx;
95  ty = -ty;
96 
97  return *this;
98  }
99 
100 
101  /**
102  * Add string.
103  *
104  * \param string string
105  * \return this string
106  */
107  JString& add(const JString& string)
108  {
109  tx += string.tx;
110  ty += string.ty;
111 
112  return *this;
113  }
114 
115 
116  /**
117  * Subtract string.
118  *
119  * \param string string
120  * \return this string
121  */
122  JString& sub(const JString& string)
123  {
124  tx -= string.tx;
125  ty -= string.ty;
126 
127  return *this;
128  }
129 
130 
131  /**
132  * Scale string.
133  *
134  * \param factor multiplication factor
135  * \return this string
136  */
137  JString& mul(const double factor)
138  {
139  tx *= factor;
140  ty *= factor;
141 
142  return *this;
143  }
144 
145 
146  /**
147  * Scale string.
148  *
149  * \param factor division factor
150  * \return this string
151  */
152  JString& div(const double factor)
153  {
154  tx /= factor;
155  ty /= factor;
156 
157  return *this;
158  }
159 
160 
161  /**
162  * Check equality.
163  *
164  * \param string string
165  * \param precision precision
166  * \return true if strings are equal; else false
167  */
168  bool equals(const JString& string,
169  const double precision = std::numeric_limits<double>::min()) const
170  {
171  return (fabs(tx - string.tx) <= precision &&
172  fabs(ty - string.ty) <= precision);
173  }
174 
175 
176  /**
177  * Get dot product.
178  *
179  * \param string string
180  * \return dot product
181  */
182  double getDot(const JString& string) const
183  {
184  return (tx * string.tx +
185  ty * string.ty);
186  }
187 
188  /**
189  * Write string parameters to output stream.
190  *
191  * \param out output stream
192  * \param string string
193  * \return output stream
194  */
195  friend inline std::ostream& operator<<(std::ostream& out, const JString& string)
196  {
197  using namespace std;
198  using namespace JPP;
199 
200  return out << FIXED(10,7) << string.tx << ' '
201  << FIXED(10,7) << string.ty;
202  }
203 
204 
205  double tx;
206  double ty;
207  };
208 
209 
210  /**
211  * Emitter parameters.
212  */
213  struct JEmitter :
214  public JMATH::JMath <JEmitter>,
215  public JLANG::JEquals<JEmitter>
216  {
217  /**
218  * Default constructor.
219  */
221  t1(0.0)
222  {}
223 
224 
225  /**
226  * Constructor.
227  *
228  * \param t1 time-of-emission [s]
229  */
230  JEmitter(const double t1) :
231  t1(t1)
232  {}
233 
234 
235  /**
236  * Negate emitter.
237  *
238  * \return this emitter
239  */
241  {
242  t1 = -t1;
243 
244  return *this;
245  }
246 
247 
248  /**
249  * Add emitter.
250  *
251  * \param emitter emitter
252  * \return this emitter
253  */
255  {
256  t1 += emitter.t1;
257 
258  return *this;
259  }
260 
261 
262  /**
263  * Subtract emitter.
264  *
265  * \param emitter emitter
266  * \return this emitter
267  */
269  {
270  t1 -= emitter.t1;
271 
272  return *this;
273  }
274 
275 
276  /**
277  * Scale emitter.
278  *
279  * \param factor multiplication factor
280  * \return this emitter
281  */
282  JEmitter& mul(const double factor)
283  {
284  t1 *= factor;
285 
286  return *this;
287  }
288 
289 
290  /**
291  * Scale emitter.
292  *
293  * \param factor division factor
294  * \return this emitter
295  */
296  JEmitter& div(const double factor)
297  {
298  t1 /= factor;
299 
300  return *this;
301  }
302 
303 
304  /**
305  * Check equality.
306  *
307  * \param emitter emitter
308  * \param precision precision
309  * \return true if emitters are equal; else false
310  */
311  bool equals(const JEmitter& emitter,
312  const double precision = std::numeric_limits<double>::min()) const
313  {
314  return (fabs(t1 - emitter.t1) <= precision);
315  }
316 
317 
318  /**
319  * Write emitter parameters to output stream.
320  *
321  * \param out output stream
322  * \param emitter emitter
323  * \return output stream
324  */
325  friend inline std::ostream& operator<<(std::ostream& out, const JEmitter& emitter)
326  {
327  using namespace std;
328  using namespace JPP;
329 
330  return out << FIXED(20,6) << emitter.t1;
331  }
332 
333 
334  double t1;
335  };
336 
337 
338  /**
339  * Default constructor.
340  */
342  {}
343 
344 
345  /**
346  * Constructor.
347  *
348  * This constructor can be used to set up a default model (i.e. all values at zero) for the given set of hits.\n
349  * The data type corresponding to the hits should provide for the following policy methods.
350  * <pre>
351  * int getString(); // get string identifier
352  * JEkey getEKey(); // get emitter identifier
353  * </pre>
354  *
355  * \param __begin begin of hits
356  * \param __end end of hits
357  */
358  template<class T>
359  JModel(T __begin, T __end)
360  {
361  for (T hit = __begin; hit != __end; ++hit) {
362 
363  if (!this->string.has(hit->getString())) {
364  this->string[hit->getString()] = JString();
365  }
366 
367  if (!this->emitter.has(hit->getEKey())) {
368  this->emitter[hit->getEKey()] = JEmitter();
369  }
370  }
371  }
372 
373 
374  /**
375  * Reset.
376  *
377  * \param zero zero
378  * \return this model
379  */
381  {
382  this->reset();
383 
384  return *this;
385  }
386 
387 
388  /**
389  * Clear parameters.
390  */
391  void clear()
392  {
393  string .clear();
394  emitter.clear();
395  }
396 
397 
398  /**
399  * Reset parameters.
400  */
401  void reset()
402  {
403  reset(string);
404  reset(emitter);
405  }
406 
407 
408  /**
409  * Set parameters.
410  *
411  * \param model model
412  * \param value value
413  */
414  template<class T>
415  void set(const JModel& model, const T& value)
416  {
417  set(this->string, model.string, static_cast<const JString&> (value));
418  set(this->emitter, model.emitter, static_cast<const JEmitter&>(value));
419  }
420 
421 
422  /**
423  * Negate model.
424  *
425  * \return this model
426  */
428  {
429  evaluate(this->string, &JString ::negate);
431 
432  return *this;
433  }
434 
435 
436  /**
437  * Add model.
438  *
439  * \param model model
440  * \return this model
441  */
442  JModel& add(const JModel& model)
443  {
444  evaluate(this->string, model.string, &JString ::add);
445  evaluate(this->emitter, model.emitter, &JEmitter::add);
446 
447  return *this;
448  }
449 
450 
451  /**
452  * Subtract model.
453  *
454  * \param model model
455  * \return this model
456  */
457  JModel& sub(const JModel& model)
458  {
459  evaluate(this->string, model.string, &JString ::sub);
460  evaluate(this->emitter, model.emitter, &JEmitter::sub);
461 
462  return *this;
463  }
464 
465 
466  /**
467  * Scale model.
468  *
469  * \param factor multiplication factor
470  * \return this model
471  */
472  JModel& mul(const double factor)
473  {
474  evaluate(this->string, &JString ::mul, factor);
475  evaluate(this->emitter, &JEmitter::mul, factor);
476 
477  return *this;
478  }
479 
480 
481  /**
482  * Scale model.
483  *
484  * \param factor division factor
485  * \return this model
486  */
487  JModel& div(const double factor)
488  {
489  evaluate(this->string, &JString ::div, factor);
490  evaluate(this->emitter, &JEmitter::div, factor);
491 
492  return *this;
493  }
494 
495 
496  /**
497  * Check equality.
498  *
499  * \param model model
500  * \param precision precision
501  * \return true if models are equal; else false
502  */
503  bool equals(const JModel& model,
504  const double precision = std::numeric_limits<double>::min()) const
505  {
506  return (equals(this->string, model.string, precision) &&
507  equals(this->emitter, model.emitter, precision));
508  }
509 
510 
511  /**
512  * Write model parameters to output stream.
513  *
514  * \param out output stream
515  * \param model model
516  * \return output stream
517  */
518  friend inline std::ostream& operator<<(std::ostream& out, const JModel& model)
519  {
520  using namespace std;
521  using namespace JPP;
522 
523  for (JHashMap<int, JString>::const_iterator i = model.string.begin(); i != model.string.end(); ++i) {
524  out << "string: " << setw(4) << i->first << ' ' << i->second << endl;
525  }
526 
527  for (JHashMap<JEKey, JEmitter>::const_iterator i = model.emitter.begin(); i != model.emitter.end(); ++i) {
528  out << "emitter: " << setw(2) << i->first << ' ' << i->second << endl;
529  }
530 
531  return out;
532  }
533 
534 
535  /**
536  * Get number of fit parameters.
537  *
538  * \return number of parameters
539  */
540  size_t getN() const
541  {
542  return getN(string) + getN(emitter);
543  }
544 
545 
546  /**
547  * Get index of fit parameter for given string.
548  *
549  * \param id string identifier
550  * \param p pointer to data member
551  * \return parameter
552  */
553  size_t getIndex(int id, double JString::*p) const
554  {
555  if (string.has(id))
556  return string.getIndex(id) * getN<JString>() + getIndex(p);
557  else
558  THROW(JValueOutOfRange, "Invalid identifier " << id);
559  }
560 
561 
562  /**
563  * Get index of fir parameter for given emitter.
564  *
565  * \param id emitter identifier
566  * \param p pointer to data member
567  * \return parameter
568  */
569  size_t getIndex(const JEKey& id, double JEmitter::*p) const
570  {
571  if (emitter.has(id))
572  return getN(string) + emitter.getIndex(id) * getN<JEmitter>() + getIndex(p);
573  else
574  THROW(JValueOutOfRange, "Invalid identifier " << id);
575  }
576 
577 
578  /**
579  * Read/write access to fit parameter value by index.
580  *
581  * \param index index
582  * \return value (zero if absent)
583  */
584  inline double operator[](const size_t index) const
585  {
586  size_t i = index;
587 
588  if (i < getN(string)) { return getParameter(string, i); }
589 
590  i -= getN(string);
591 
592  if (i < getN(emitter)) { return getParameter(emitter, i); }
593 
594  THROW(JIndexOutOfRange, "Invalid index " << index << " >= " << getN());
595  }
596 
597 
598  /**
599  * Read/write access to fit parameter value by index.
600  *
601  * \param index index
602  * \return value
603  */
604  inline double& operator[](const size_t index)
605  {
606  size_t i = index;
607 
608  if (i < getN(string)) { return getParameter(string, i); }
609 
610  i -= getN(string);
611 
612  if (i < getN(emitter)) { return getParameter(emitter, i); }
613 
614  THROW(JIndexOutOfRange, "Invalid index " << index << " >= " << getN());
615  }
616 
617 
618  /**
619  * Map string identifier to model parameters of string.
620  */
621  struct string_map :
622  public JHashMap<int, JString>
623  {} string;
624 
625 
626  /**
627  * Map emitter key to model parameters of emitter.
628  */
629  struct emitter_map :
630  public JHashMap<JEKey, JEmitter>
631  {
632  private:
633  /**
634  * Auxiliary class for multiple associative map operators.
635  */
636  struct JHashMapHelper {
637  /**
638  * Constructor.
639  *
640  * \param map map
641  * \param id emitter identifier
642  */
644  map(map),
645  id (id)
646  {}
647 
648 
649  /**
650  * Get value corresponding to event counter (i.e.\ second part of JEKey).
651  *
652  * \param counter event counter
653  * \return emitter
654  */
655  JEmitter& operator[](const int counter)
656  {
657  return map[JEKey(id, counter)];
658  }
659 
660  private:
662  int id;
663  };
664 
665  public:
666 
668 
669 
670  /**
671  * Get helper corresponding to emitter identifier (i.e.\ first part of JEKey).
672  *
673  * \param id emitter identifier
674  * \return helper
675  */
677  {
678  return JHashMapHelper(*this, id);
679  }
680 
681  } emitter;
682 
683 
684  private:
685  /**
686  * Get number of fit parameters corresponding to given data structure.
687  *
688  * \return number of parameters
689  */
690  template<class T>
691  static size_t getN()
692  {
693  return sizeof(T) / sizeof(double);
694  }
695 
696 
697  /**
698  * Get number of fit parameters corresponding to given buffer.
699  *
700  * \param buffer buffer
701  * \return number of parameters
702  */
703  template<class JKey_t, class JValue_t, class JEvaluator_t>
704  static size_t getN(const JHashMap<JKey_t, JValue_t, JEvaluator_t>& buffer)
705  {
706  return buffer.size() * getN<JValue_t>();
707  }
708 
709 
710  /**
711  * Get index of fit parameter in given data structure.
712  *
713  * \param p pointer to data member
714  * \return index
715  */
716  template<class T>
717  static inline size_t getIndex(double T::*p)
718  {
719  T* __p__ = NULL;
720 
721  return ((double*) &(__p__->*p) - (double*) __p__);
722  }
723 
724 
725  /**
726  * Get fit parameter value at given index in buffer.
727  *
728  * \param buffer buffer
729  * \param index index
730  * \return value
731  */
732  template<class JKey_t, class JValue_t, class JEvaluator_t>
733  static double getParameter(const JHashMap<JKey_t, JValue_t, JEvaluator_t>& buffer, const size_t index)
734  {
735  const size_t pos = index / getN<JValue_t>(); // position of element in buffer
736  const size_t offset = index % getN<JValue_t>(); // offset of parameter in element
737 
738  const JValue_t& value = buffer.data()[pos].second; // value of element at given position
739 
740  return ((const double*) &value)[offset]; // parameter at given offset
741  }
742 
743 
744  /**
745  * Get fit parameter value at given index in buffer.
746  *
747  * \param buffer buffer
748  * \param index index
749  * \return value
750  */
751  template<class JKey_t, class JValue_t, class JEvaluator_t>
752  static double& getParameter(JHashMap<JKey_t, JValue_t, JEvaluator_t>& buffer, const size_t index)
753  {
754  const size_t pos = index / getN<JValue_t>(); // position of element in buffer
755  const size_t offset = index % getN<JValue_t>(); // offset of parameter in element
756 
757  JValue_t& value = buffer.data()[pos].second; // value of element at given position
758 
759  return ((double*) &value)[offset]; // parameter at given offset
760  }
761  };
762 }
763 
764 #endif
JString()
Default constructor.
size_t getN() const
Get number of fit parameters.
JModel & negate()
Negate model.
Exceptions.
JEmitter & operator[](const int counter)
Get value corresponding to event counter (i.e. second part of JEKey).
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:26
void clear()
Clear parameters.
Map emitter key to model parameters of emitter.
General purpose class for hash map of unique keys.
Definition: JHashMap.hh:71
JModel & mul(const double factor)
Scale model.
friend std::ostream & operator<<(std::ostream &out, const JEmitter &emitter)
Write emitter parameters to output stream.
General purpose class for hash map of unique elements.
bool equals(const JModel &model, const double precision=std::numeric_limits< double >::min()) const
Check equality.
JModel(T __begin, T __end)
Constructor.
JEmitter & add(const JEmitter &emitter)
Add emitter.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
void set(const JModel &model, const T &value)
Set parameters.
JEmitter(const double t1)
Constructor.
Map string identifier to model parameters of string.
static void evaluate(JHashMap< JKey_t, JValue_t, JEvaluator_t > &buffer, JValue_t &(JValue_t::*f1)())
Evaluate arithmetic operation on buffer.
static const JZero zero
Function object to assign zero value.
Definition: JZero.hh:105
Auxiliary data structure for floating point format specification.
Definition: JPrint.hh:481
int getIndex(const T &value) const
Get index of given value.
Definition of zero value for any class.
double operator[](const size_t index) const
Read/write access to fit parameter value by index.
static void reset(JHashMap< JKey_t, JValue_t, JEvaluator_t > &buffer)
Reset buffer.
static size_t getIndex(double T::*p)
Get index of fit parameter in given data structure.
static size_t getN(const JHashMap< JKey_t, JValue_t, JEvaluator_t > &buffer)
Get number of fit parameters corresponding to given buffer.
JEmitter & mul(const double factor)
Scale emitter.
JACOUSTICS::JModel::emitter_map emitter
Auxiliary class for multiple associative map operators.
friend std::ostream & operator<<(std::ostream &out, const JModel &model)
Write model parameters to output stream.
Model for fit to acoustics data.
size_t parameter_type
Type definition of fit parameter.
JACOUSTICS::JModel::string_map string
static double & getParameter(JHashMap< JKey_t, JValue_t, JEvaluator_t > &buffer, const size_t index)
Get fit parameter value at given index in buffer.
static size_t getN()
Get number of fit parameters corresponding to given data structure.
bool equals(const JEmitter &emitter, const double precision=std::numeric_limits< double >::min()) const
Check equality.
I/O formatting auxiliaries.
Auxiliary class to assign zero value.
Definition: JZero.hh:81
JString(const double tx, const double ty)
Constructor.
static double getParameter(const JHashMap< JKey_t, JValue_t, JEvaluator_t > &buffer, const size_t index)
Get fit parameter value at given index in buffer.
do set_variable OUTPUT_DIRECTORY $WORKDIR T
Template definition of auxiliary base class for comparison of data structures.
Definition: JEquals.hh:24
JEmitter()
Default constructor.
Arithmetic toolkit for hash maps.
size_t getIndex(const JEKey &id, double JEmitter::*p) const
Get index of fir parameter for given emitter.
static void set(JHashMap< JKey_t, JValue_t, JEvaluator_t > &target, const JHashMap< JKey_t, JValue_t, JEvaluator_t > &source, const JValue_t &value)
Set values in target corresponding to keys in source.
JEmitter & sub(const JEmitter &emitter)
Subtract emitter.
size_t getIndex(int id, double JString::*p) const
Get index of fit parameter for given string.
JString & div(const double factor)
Scale string.
double getDot(const JString &string) const
Get dot product.
JModel & sub(const JModel &model)
Subtract model.
Emitter hash key.
JHashMapHelper(JHashMap< JEKey, JEmitter > &map, int id)
Constructor.
JString & add(const JString &string)
Add string.
double & operator[](const size_t index)
Read/write access to fit parameter value by index.
JModel & div(const double factor)
Scale model.
virtual void clear()
Clear.
Definition: JHashMap.hh:106
JModel()
Default constructor.
friend std::ostream & operator<<(std::ostream &out, const JString &string)
Write string parameters to output stream.
JString & negate()
Negate string.
JString & sub(const JString &string)
Subtract string.
JModel & add(const JModel &model)
Add model.
static bool equals(const JHashMap< JKey_t, JValue_t, JEvaluator_t > &first, const JHashMap< JKey_t, JValue_t, JEvaluator_t > &second)
Check equality of buffers.
Emitter key.
Definition: JEKey.hh:29
Toolkit for JHashMap.
Base class for data structures with artithmetic capabilities.
Exception for accessing a value in a collection that is outside of its range.
Definition: JException.hh:162
JEmitter & negate()
Negate emitter.
JEmitter & div(const double factor)
Scale emitter.
Exception for accessing an index in a collection that is outside of its range.
Definition: JException.hh:90
bool equals(const JString &string, const double precision=std::numeric_limits< double >::min()) const
Check equality.
JString & mul(const double factor)
Scale string.
JHashMapHelper operator[](int id)
Get helper corresponding to emitter identifier (i.e. first part of JEKey).
bool has(const T &value) const
Test whether given value is present.
void reset()
Reset parameters.
JModel & operator=(const JMATH::JZero &zero)
Reset.