forpy  2
renyientropy.h
Go to the documentation of this file.
1 /* Author: Christoph Lassner. */
2 #pragma once
3 #ifndef FORPY_IMPURITIES_RENYIENTROPY_H_
4 #define FORPY_IMPURITIES_RENYIENTROPY_H_
5 
6 #include "../global.h"
7 
8 #include "../util/serialization/basics.h"
9 
10 #include <limits>
11 #include <numeric>
12 #include <vector>
13 
14 #include "../types.h"
15 #include "../util/checks.h"
16 #include "../util/exponentials.h"
17 #include "./classificationerror.h"
18 #include "./ientropyfunction.h"
19 #include "./inducedentropy.h"
20 #include "./shannonentropy.h"
21 
22 namespace forpy {
35  public:
36  explicit RenyiEntropy(const float &alpha);
37  inline ~RenyiEntropy(){};
38 
39  inline virtual float operator()(const float *class_members_numbers,
40  const size_t &n, const float &fsum) const {
41  if (q == 1.f) {
42  return shannon_entropy->operator()(class_members_numbers, n, fsum);
43  }
44  if (q == std::numeric_limits<float>::infinity()) {
45  return -logf(
46  -(classification_error->operator()(class_members_numbers, n, fsum) -
47  1.f));
48  }
49  // In debug mode, run checks.
50  FASSERT(static_cast<float>(std::accumulate(class_members_numbers,
51  class_members_numbers + n,
52  static_cast<float>(0))) == fsum);
53  // Deal with the special case quickly.
54  if (fsum == 0.f) return 0.f;
55  // Cast only once and save time.
56  float entropy_sum = 0.f;
57  float quot;
58  if (ceilf(q) == q || floorf(q) == q) {
59  // q is a whole number. Use a faster implementation.
60  const uint whole_q = static_cast<uint>(q);
61  for (size_t i = 0; i < n; ++i) {
62  quot = *(class_members_numbers++) / fsum;
63  entropy_sum += fpowi(quot, whole_q);
64  }
65  } else {
66  // p is not a whole number.
67  // Calculate.
68  for (size_t i = 0; i < n; ++i) {
69  quot = *(class_members_numbers++) / fsum;
70  entropy_sum += powf(quot, q);
71  }
72  }
73  return logf(entropy_sum) / (1.f - q);
74  }
75 
76  inline friend std::ostream &operator<<(std::ostream &stream,
77  const RenyiEntropy &self) {
78  stream << "forpy::RenyiEntropy[alpha=" << self.get_alpha() << "]";
79  return stream;
80  };
81  bool operator==(const IEntropyFunction &rhs) const;
82 
84  float get_alpha() const;
85 
86  private:
89  inline RenyiEntropy(){};
90 
91  friend class cereal::access;
92  template <class Archive>
93  void serialize(Archive &ar, const uint &) {
94  ar(cereal::make_nvp("base", cereal::base_class<IEntropyFunction>(this)),
95  CEREAL_NVP(q), CEREAL_NVP(shannon_entropy), CEREAL_NVP(induced_p),
96  CEREAL_NVP(classification_error));
97  };
98 
99  float q;
100  std::unique_ptr<ShannonEntropy> shannon_entropy;
101  std::unique_ptr<InducedEntropy> induced_p;
102  std::unique_ptr<ClassificationError> classification_error;
104 };
105 } // namespace forpy
106 
108 #endif // FORPY_IMPURITIES_RENYIENTROPY_H_
std::unique_ptr< ShannonEntropy > shannon_entropy
Definition: renyientropy.h:100
virtual float operator()(const float *class_members_numbers, const size_t &n, const float &fsum) const
Definition: renyientropy.h:39
float fpowi(float base, unsigned int exp)
Computes a float power by an unsigned int.
Definition: exponentials.h:56
RenyiEntropy()
DON&#39;T USE. Non-initializing constructor for serialization purposes.
Definition: renyientropy.h:89
bool operator==(const IEntropyFunction &rhs) const
DISALLOW_COPY_AND_ASSIGN(RenyiEntropy)
Interface for an entropy calculation functor.
#define FASSERT(condition)
Definition: global.h:124
std::unique_ptr< ClassificationError > classification_error
Definition: renyientropy.h:102
CEREAL_REGISTER_TYPE(forpy::RenyiEntropy)
Computes the Renyi entropy.
Definition: renyientropy.h:34
void serialize(Archive &ar, const uint &)
Definition: renyientropy.h:93
float get_alpha() const
friend std::ostream & operator<<(std::ostream &stream, const RenyiEntropy &self)
Definition: renyientropy.h:76
unsigned int uint
Convenience typedef for unsigned int.
Definition: types.h:113
std::unique_ptr< InducedEntropy > induced_p
Definition: renyientropy.h:101