Lightmetrica  0.0.1.50dbee3 (yosakoi)
 All Classes Functions Variables Typedefs Enumerations Enumerator
math.distribution.h
1 /*
2  Lightmetrica : A research-oriented renderer
3 
4  Copyright (c) 2014 Hisanari Otsu
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 #ifndef LIB_LIGHTMETRICA_MATH_DISTRIBUTION_H
22 #define LIB_LIGHTMETRICA_MATH_DISTRIBUTION_H
23 
24 #include "math.types.h"
25 #include "logger.h"
26 #include <vector>
27 
28 LM_NAMESPACE_BEGIN
29 LM_MATH_NAMESPACE_BEGIN
30 
36 {
37 public:
38 
39  DiscreteDistribution1D() { Clear(); }
40 
41 public:
42 
43  void Add(const Math::Float& v)
44  {
45  cdf.push_back(cdf.back() + v);
46  }
47 
48  void Normalize()
49  {
50  auto sum = cdf.back();
51  if (sum > Math::Float(0))
52  {
53  auto invSum = Math::Float(1) / sum;
54  for (auto& v : cdf)
55  {
56  v *= invSum;
57  }
58  }
59  else
60  {
61  LM_LOG_WARN("Unable to normalize. Sum is zero.")
62  }
63  }
64 
65  size_t Sample(const Math::Float& u) const
66  {
67  size_t v = static_cast<size_t>(std::upper_bound(cdf.begin(), cdf.end(), u) - cdf.begin()) - 1;
68  return Math::Clamp<size_t>(v, 0, cdf.size() - 2);
69  }
70 
71  Math::Float EvaluatePDF(int i) const
72  {
73  return (i < 0 || i + 1 >= static_cast<int>(cdf.size())) ? Math::Float(0) : cdf[i + 1] - cdf[i];
74  }
75 
76  void Clear()
77  {
78  cdf.clear();
79  cdf.push_back(Math::Float(0));
80  }
81 
82  bool Empty() const
83  {
84  return cdf.size() == 1;
85  }
86 
87 private:
88 
89  std::vector<Math::Float> cdf;
90 
91 };
92 
93 LM_MATH_NAMESPACE_END
94 LM_NAMESPACE_END
95 
96 #endif // LIB_LIGHTMETRICA_MATH_DISTRIBUTION_H
Definition: math.distribution.h:35