forpy  2
inducedentropy.h
Go to the documentation of this file.
1 /* Author: Christoph Lassner. */
2 #pragma once
3 #ifndef FORPY_IMPURITIES_INDUCEDENTROPY_H_
4 #define FORPY_IMPURITIES_INDUCEDENTROPY_H_
5 
6 #include "../util/serialization/basics.h"
7 
8 #include <limits>
9 #include <vector>
10 
11 #include "../global.h"
12 #include "../util/checks.h"
13 #include "../util/exponentials.h"
14 #include "./ientropyfunction.h"
15 
16 namespace forpy {
17 
43  public:
44  inline explicit InducedEntropy(const float &p) : p(p) {
45  if (p <= 0.f) {
46  throw ForpyException("p must be > 0.f.");
47  }
48  };
49  inline ~InducedEntropy(){};
50 
51  inline virtual float operator()(const float *class_members_numbers,
52  const size_t &n, const float &fsum) const {
53  FASSERT(static_cast<float>(std::accumulate(class_members_numbers,
54  class_members_numbers + n,
55  static_cast<float>(0))) == fsum);
56  if (fsum == 0.f) return 0.f;
57  if (p == 2.f) {
58  float sq_left = 0.f;
59  for (size_t i = 0; i < n; ++i, ++class_members_numbers)
60  sq_left += *class_members_numbers * *class_members_numbers;
61  return 1.f - sq_left / (fsum * fsum);
62  } else {
63  float n_classes_f = static_cast<float>(n);
64  float max_unorder_val = 1.f / n_classes_f;
65  float entropy_sum;
66  if (ceilf(p) == p || floorf(p) == p) {
67  const uint whole_p = static_cast<uint>(p);
68  entropy_sum = fpowi(1.f - max_unorder_val, whole_p) +
69  (n_classes_f - 1.f) * fpowi(max_unorder_val, whole_p);
70  for (size_t i = 0; i < n; ++i) {
71  float quot = *(class_members_numbers++) / fsum;
72  entropy_sum -= fpowi(fabs(quot - max_unorder_val), whole_p);
73  }
74  } else {
75  entropy_sum = powf(1.f - max_unorder_val, p) +
76  (n_classes_f - 1.f) * powf(max_unorder_val, p);
77  for (size_t i = 0; i < n; ++i) {
78  float quot = *(class_members_numbers++) / fsum;
79  entropy_sum -= powf(fabs(quot - max_unorder_val), p);
80  }
81  }
82  return entropy_sum;
83  }
84  };
85 
86  inline friend std::ostream &operator<<(std::ostream &stream,
87  const InducedEntropy &self) {
88  stream << "forpy::InducedEntropy[p=" << self.get_p() << "]";
89  return stream;
90  };
91 
92  inline bool operator==(const IEntropyFunction &rhs) const {
93  const auto *rhs_c = dynamic_cast<InducedEntropy const *>(&rhs);
94  if (rhs_c == nullptr) {
95  return false;
96  } else {
97  bool eq_p = p == rhs_c->p;
98  return eq_p;
99  }
100  };
101 
102  inline float get_p() const { return p; };
103 
104  private:
106 
107  friend class cereal::access;
108  template <class Archive>
109  void serialize(Archive &ar, const uint &) {
110  ar(cereal::make_nvp("base", cereal::base_class<IEntropyFunction>(this)),
111  CEREAL_NVP(p));
112  }
113 
114  float p;
116 };
117 } // namespace forpy
118 
120 /*CEREAL_REGISTER_DYNAMIC_INIT(forpy::InducedEntropy);
121  CEREAL_FORCE_DYNAMIC_INIT(forpy::InducedEntropy);*/
122 #endif // FORPY_IMPURITIES_INDUCEDENTROPY_H_
bool operator==(const IEntropyFunction &rhs) const
float fpowi(float base, unsigned int exp)
Computes a float power by an unsigned int.
Definition: exponentials.h:56
CEREAL_REGISTER_TYPE(forpy::InducedEntropy)
Interface for an entropy calculation functor.
#define FASSERT(condition)
Definition: global.h:124
virtual float operator()(const float *class_members_numbers, const size_t &n, const float &fsum) const
Computes the induced p entropy.
friend std::ostream & operator<<(std::ostream &stream, const InducedEntropy &self)
DISALLOW_COPY_AND_ASSIGN(InducedEntropy)
InducedEntropy(const float &p)
void serialize(Archive &ar, const uint &)
unsigned int uint
Convenience typedef for unsigned int.
Definition: types.h:113