Turi Create  4.0
alias.hpp
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 #ifndef TURI_RANDOM_ALIAS_HPP
7 #define TURI_RANDOM_ALIAS_HPP
8 
9 #include <vector>
10 #include <string>
11 #include <utility>
12 
13 namespace turi { namespace random {
14 
15 /**
16  * \ingroup random
17  * This is a standard algorithm for sampling from probability mass functions.
18  * It is also known as the Walker Method.
19  * Typically sampling from general discrete functions requires the inverse CDF
20  * method, which means each sample is O(K) where K is the number of outcomes in
21  * the pmf. The alias method, on the other hand, requires O(K) setup but requires
22  * only O(1) for each sample. To be specific, each sample only requires a
23  * uniformly generated float and a uniformly generated integer.
24  *
25  * For more details, see
26  * http://www.cs.toronto.edu/~gdahl/papers/aliasMethod.pdf
27  * http://luc.devroye.org/chapter_three.pdf, p. 107
28  */
30  public:
31  alias_sampler() = default;
32  alias_sampler(const alias_sampler&) = default;
33 
34  /**
35  * Constructor.
36  *
37  * \param p Vector representing the probability mass function with K
38  * outcomes, where K is the size of the vector. Values should be
39  * nonnegative, but they need not sum to 1.
40  */
41  explicit alias_sampler(const std::vector<double>& p);
42 
43  /**
44  * Sample from the PMF using the alias method.
45  *
46  * \returns an integer between 0 and K-1, where K is the number of outcomes
47  * in the provided pmf. A value i is returned with probability
48  *
49  * p_i / sum_{j=0}^{K-1} p_j
50  */
51  size_t sample();
52 
53  private:
54  std::vector<size_t> J;
55  std::vector<double> q;
56  size_t K;
57 };
58 
59 } // end of random
60 } // end of turicreate
61 
62 
63 #endif