LArDiscreteProbabilityVector.h
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArObjects/LArDiscreteProbabilityVector.h
3  *
4  * @brief Header file for the lar discrete probability vector class
5  *
6  * $Log: $
7  */
8 #ifndef LAR_DISCRETE_PROBABILITY_VECTOR_H
9 #define LAR_DISCRETE_PROBABILITY_VECTOR_H 1
10 
11 #include "Pandora/PandoraInternal.h"
12 #include "Pandora/StatusCodes.h"
13 
14 #include <limits>
15 #include <random>
16 #include <utility>
17 #include <vector>
18 
19 namespace lar_content
20 {
21 
22 /**
23  * @brief DiscreteProbabilityVector class
24  */
26 {
27 public:
28  template <typename TX, typename TY>
29  using InputDatum = std::pair<TX, TY>;
30 
31  template <typename TX, typename TY>
32  using InputData = std::vector<InputDatum<TX, TY>>;
33 
35 
37 
38  /**
39  * @brief Constructor
40  *
41  * @param inputData the data used to construct the probability vector
42  * @param xUpperBound the upper bound of the probability vector
43  * @param useWidths bool controlling whether the bin widths are used in calculations
44  */
45  template <typename TX, typename TY>
46  DiscreteProbabilityVector(const InputData<TX, TY> &inputData, const TX xUpperBound, const bool useWidths);
47 
48  /**
49  * @brief Constructor
50  *
51  * @param discreteProbabilityVector a discrete probability vector to resample from
52  * @param resamplingPoints the points to resample the discrete probability vector with
53  */
54  DiscreteProbabilityVector(const DiscreteProbabilityVector &discreteProbabilityVector, const ResamplingPoints &resamplingPoints);
55 
56  /**
57  * @brief Constructor
58  *
59  * @param discreteProbabilityVector a discrete probability vector to randomly rearrange
60  * @param randomNumberGenerator the random number generator for the random reshuffling
61  */
62  DiscreteProbabilityVector(const DiscreteProbabilityVector &discreteProbabilityVector, std::mt19937 &randomNumberGenerator);
63 
64  /**
65  * @brief Evaluate the cumulative probability at arbitrary x
66  *
67  * @param x the x value
68  *
69  * @return the cumulative probability
70  */
71  float EvaluateCumulativeProbability(const float x) const;
72 
73  /**
74  * @brief Get the size of the probability vector
75  *
76  * @return the probability vector size
77  */
78  unsigned int GetSize() const;
79 
80  /**
81  * @brief Get the x value of the element in the vector
82  *
83  * @param index the index in the vector
84  *
85  * @return the x value
86  */
87  float GetX(const unsigned int index) const;
88 
89  /**
90  * @brief Get the probability value of the element in the vector
91  *
92  * @param index the index in the vector
93  *
94  * @return the probability
95  */
96  float GetProbability(const unsigned int index) const;
97 
98  /**
99  * @brief Get the probability density value of the element in the vector
100  *
101  * @param index the index in the vector
102  *
103  * @return the probability density
104  */
105  float GetProbabilityDensity(const unsigned int index) const;
106 
107  /**
108  * @brief Get the cumulative probability value of the element in the vector
109  *
110  * @param index the index in the vector
111  *
112  * @return the cumulative probability
113  */
114  float GetCumulativeProbability(const unsigned int index) const;
115 
116  /**
117  * @brief Get the width of the element in the vectorr
118  *
119  * @param index the index in the vector
120  *
121  * @return the width of the probability bin
122  */
123  float GetWidth(const unsigned int index) const;
124 
125  /**
126  * @brief Get all information stored at a particular index
127  *
128  * @param index the index in the vector
129  * @param x the x value
130  * @param probabilityDensity the probability density value
131  * @param cumulativeProbability the cumulative probability value
132  * @param width the width of the probability bin
133  */
134  void GetAllAtIndex(const unsigned int index, float &x, float &probabilityDensity, float &cumulativeProbability, float &width) const;
135 
136 private:
137  /**
138  * @brief DiscreteProbabilityData class
139  */
141  {
142  public:
143  /**
144  * @brief Constructor
145  *
146  * @param x the x value
147  * @param densityDatum the probability density for the corresponding x
148  * @param cumulativeDatum the cumulative probability for the corresponding x
149  * @param width the width of the bin
150  */
151  DiscreteProbabilityDatum(const float x, const float densityDatum, const float cumulativeDatum, const float width);
152 
153  /**
154  * @brief Get the x value for the datum
155  *
156  * @return the x value
157  */
158  float GetX() const;
159 
160  /**
161  * @brief Get the probability density for the datum
162  *
163  * @return the probability density
164  */
165  float GetDensityDatum() const;
166 
167  /**
168  * @brief Get the cumulative probability for the datum
169  *
170  * @return the cumulative probability
171  */
172  float GetCumulativeDatum() const;
173 
174  /**
175  * @brief Get the width of the datum
176  *
177  * @return the width
178  */
179  float GetWidth() const;
180 
181  private:
182  float m_x; ///< The x coordinate
183  float m_densityDatum; ///< The probability density value
184  float m_cumulativeDatum; ///< The cumulative probability value
185  float m_width; ///< The width of the probability bin
186  };
187 
188  typedef std::vector<DiscreteProbabilityDatum> DiscreteProbabilityData;
189 
190  /**
191  * @brief Get a initialised probability data vector from the input data
192  *
193  * @param inputData the input data
194  *
195  * @return a fully-initialised discrete probability data vector
196  */
197  template <typename TX, typename TY>
198  DiscreteProbabilityData InitialiseDiscreteProbabilityData(InputData<TX, TY> inputData) const;
199 
200  /**
201  * @brief Get a resampled probability data vector by resampling another probability data vector
202  *
203  * @param discreteProbabilityVector another discrete probability vector
204  * @param resamplingPoints the points to resample the discrete probability vector with
205  *
206  * @return a resampled probability data vector
207  */
208  DiscreteProbabilityData ResampleDiscreteProbabilityData(
209  const DiscreteProbabilityVector &discreteProbabilityVector, const ResamplingPoints &resamplingPoints) const;
210 
211  /**
212  * @brief Get a randomised probability data vector in which the x values are unchanged, the probability density is
213  * randomised and the cumulative probability is recalculated
214  *
215  * @param discreteProbabilityVector another discrete probability vector
216  * @param randomNumberGenerator the random number generator for the random reshuffling
217  *
218  * @return a resampled probability data vector
219  */
220  DiscreteProbabilityData RandomiseDiscreteProbabilityData(
221  const DiscreteProbabilityVector &discreteProbabilityVector, std::mt19937 &randomNumberGenerator) const;
222 
223  /**
224  * @brief Sort the input data according to their x value
225  *
226  * @param lhs the first InputDatum
227  * @param lhs the second InputDatum
228  *
229  * @return a bool dictacting swapping the two InputDatums
230  */
231  template <typename TX, typename TY>
232  static bool SortInputDataByX(const InputDatum<TX, TY> &lhs, const InputDatum<TX, TY> &rhs);
233 
234  /**
235  * @brief Calculate the probability normalisation
236  *
237  * @param inputData the input data
238  *
239  * @return the probability normalisation
240  */
241  template <typename TX, typename TY>
242  float CalculateNormalisation(const InputData<TX, TY> &inputData) const;
243 
244  /**
245  * @brief Verify the integrity of the complete probability vector
246  */
247  void VerifyCompleteData() const;
248 
249  /**
250  * @brief Verify the integrity of the element request
251  *
252  * @param index the index in the probability vector
253  */
254  void VerifyElementRequest(const unsigned int index) const;
255 
256  float m_xUpperBound; ///< the upper bound of the probability vector
257  bool m_useWidths; ///< controls whether bin widths are used in calculations
258  DiscreteProbabilityData m_discreteProbabilityData; ///< the probability data
259 };
260 
261 //------------------------------------------------------------------------------------------------------------------------------------------
262 
263 inline unsigned int DiscreteProbabilityVector::GetSize() const
264 {
265  return m_discreteProbabilityData.size();
266 }
267 
268 //------------------------------------------------------------------------------------------------------------------------------------------
269 
270 inline float DiscreteProbabilityVector::GetX(const unsigned int index) const
271 {
272  this->VerifyElementRequest(index);
273 
274  return m_discreteProbabilityData.at(index).GetX();
275 }
276 
277 //------------------------------------------------------------------------------------------------------------------------------------------
278 
279 inline float DiscreteProbabilityVector::GetProbability(const unsigned int index) const
280 {
281  this->VerifyElementRequest(index);
282 
283  return m_discreteProbabilityData.at(index).GetDensityDatum() * (m_useWidths ? m_discreteProbabilityData.at(index).GetWidth() : 1.f);
284 }
285 
286 //------------------------------------------------------------------------------------------------------------------------------------------
287 
288 inline float DiscreteProbabilityVector::GetProbabilityDensity(const unsigned int index) const
289 {
290  this->VerifyElementRequest(index);
291 
292  return m_discreteProbabilityData.at(index).GetDensityDatum();
293 }
294 
295 //------------------------------------------------------------------------------------------------------------------------------------------
296 
297 inline float DiscreteProbabilityVector::GetCumulativeProbability(const unsigned int index) const
298 {
299  this->VerifyElementRequest(index);
300 
301  return m_discreteProbabilityData.at(index).GetCumulativeDatum();
302 }
303 
304 //------------------------------------------------------------------------------------------------------------------------------------------
305 
306 inline float DiscreteProbabilityVector::GetWidth(const unsigned int index) const
307 {
308  this->VerifyElementRequest(index);
309 
310  return m_discreteProbabilityData.at(index).GetWidth();
311 }
312 
313 //------------------------------------------------------------------------------------------------------------------------------------------
314 
316  const unsigned int index, float &x, float &probabilityDensity, float &cumulativeProbability, float &width) const
317 {
318  this->VerifyElementRequest(index);
319 
320  const DiscreteProbabilityDatum &theDatum(m_discreteProbabilityData.at(index));
321  x = theDatum.GetX();
322  probabilityDensity = theDatum.GetDensityDatum();
323  cumulativeProbability = theDatum.GetCumulativeDatum();
324  width = theDatum.GetWidth();
325 }
326 
327 //------------------------------------------------------------------------------------------------------------------------------------------
328 
330  const float x, const float densityDatum, const float cumulativeDatum, const float width) :
331  m_x(x),
332  m_densityDatum(densityDatum),
333  m_cumulativeDatum(cumulativeDatum),
334  m_width(width)
335 {
336 }
337 
338 //------------------------------------------------------------------------------------------------------------------------------------------
339 
341 {
342  return m_x;
343 }
344 
345 //------------------------------------------------------------------------------------------------------------------------------------------
346 
348 {
349  return m_densityDatum;
350 }
351 
352 //------------------------------------------------------------------------------------------------------------------------------------------
353 
355 {
356  return m_cumulativeDatum;
357 }
358 
359 //------------------------------------------------------------------------------------------------------------------------------------------
360 
362 {
363  return m_width;
364 }
365 
366 //------------------------------------------------------------------------------------------------------------------------------------------
367 
369 {
370  if (2 > m_discreteProbabilityData.size())
371  throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_INITIALIZED);
372 
373  if (m_discreteProbabilityData.back().GetX() - m_xUpperBound > std::numeric_limits<float>::epsilon())
374  throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
375 
376  return;
377 }
378 
379 //------------------------------------------------------------------------------------------------------------------------------------------
380 
381 inline void DiscreteProbabilityVector::VerifyElementRequest(const unsigned int index) const
382 {
383  if (this->GetSize() < index)
384  throw pandora::StatusCodeException(pandora::STATUS_CODE_OUT_OF_RANGE);
385 
386  return;
387 }
388 
389 } // namespace lar_content
390 
391 #endif // #ifndef LAR_DISCRETE_PROBABILITY_VECTOR_H
std::vector< InputDatum< TX, TY >> InputData
float GetProbabilityDensity(const unsigned int index) const
Get the probability density value of the element in the vector.
void VerifyCompleteData() const
Verify the integrity of the complete probability vector.
float GetX(const unsigned int index) const
Get the x value of the element in the vector.
float EvaluateCumulativeProbability(const float x) const
Evaluate the cumulative probability at arbitrary x.
DiscreteProbabilityData ResampleDiscreteProbabilityData(const DiscreteProbabilityVector &discreteProbabilityVector, const ResamplingPoints &resamplingPoints) const
Get a resampled probability data vector by resampling another probability data vector.
std::vector< DiscreteProbabilityDatum > DiscreteProbabilityData
float CalculateNormalisation(const InputData< TX, TY > &inputData) const
Calculate the probability normalisation.
DiscreteProbabilityDatum(const float x, const float densityDatum, const float cumulativeDatum, const float width)
Constructor.
DiscreteProbabilityData InitialiseDiscreteProbabilityData(InputData< TX, TY > inputData) const
Get a initialised probability data vector from the input data.
float GetWidth(const unsigned int index) const
Get the width of the element in the vectorr.
void VerifyElementRequest(const unsigned int index) const
Verify the integrity of the element request.
float GetDensityDatum() const
Get the probability density for the datum.
void GetAllAtIndex(const unsigned int index, float &x, float &probabilityDensity, float &cumulativeProbability, float &width) const
Get all information stored at a particular index.
DiscreteProbabilityData RandomiseDiscreteProbabilityData(const DiscreteProbabilityVector &discreteProbabilityVector, std::mt19937 &randomNumberGenerator) const
Get a randomised probability data vector in which the x values are unchanged, the probability density...
static bool SortInputDataByX(const InputDatum< TX, TY > &lhs, const InputDatum< TX, TY > &rhs)
Sort the input data according to their x value.
float GetCumulativeProbability(const unsigned int index) const
Get the cumulative probability value of the element in the vector.
float GetProbability(const unsigned int index) const
Get the probability value of the element in the vector.
DiscreteProbabilityVector(const InputData< TX, TY > &inputData, const TX xUpperBound, const bool useWidths)
Constructor.
DiscreteProbabilityData m_discreteProbabilityData
the probability data
float m_xUpperBound
the upper bound of the probability vector
bool m_useWidths
controls whether bin widths are used in calculations
unsigned int GetSize() const
Get the size of the probability vector.
list x
Definition: train.py:276
float GetCumulativeDatum() const
Get the cumulative probability for the datum.
Dft::FloatVector FloatVector