summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/include/gnuradio/random.h
blob: ba216f311774db23f12adba828cae2060697edbf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* -*- c++ -*- */
/*
 * Copyright 2002, 2015 Free Software Foundation, Inc.
 *
 * This file is part of GNU Radio
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 */

#ifndef INCLUDED_GR_RANDOM_H
#define INCLUDED_GR_RANDOM_H

#include <gnuradio/api.h>
#include <gnuradio/gr_complex.h>
#include <gnuradio/xoroshiro128p.h>

#include <limits>
#include <random>

namespace gr {

/*!
 * \brief wrapper for XOROSHIRO128+ PRNG for use in std::distributions
 * Fulfills C++ named requirements for UniformRandomBitGenerator
 * \ingroup math_blk
 */
class GR_RUNTIME_API xoroshiro128p_prng
{
public:
    using result_type = uint64_t; //! \brief value type is uint64

private:
    result_type state[2];

public:
    /*!
     * \brief minimum value
     */
    static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
    /*!
     * \brief maximum value
     */
    static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }

    /*!
     * \brief constructor. Expects a seed.
     */
    xoroshiro128p_prng(uint64_t init) { seed(init); }


    /*!
     * \brief yield a random value and advance state
     */
    result_type operator()() { return xoroshiro128p_next(state); }

    /*!
     * \brief set new seed
     */
    void seed(uint64_t seed) { xoroshiro128p_seed(state, seed); }
};
/*!
 * \brief pseudo random number generator
 * \ingroup math_blk
 */
class GR_RUNTIME_API random
{
protected:
    long d_seed;
    bool d_gauss_stored;
    float d_gauss_value;

    xoroshiro128p_prng d_rng; // mersenne twister as random number generator
    std::uniform_real_distribution<float>
        d_uniform; // choose uniform distribution, default is [0,1)
    std::uniform_int_distribution<int64_t> d_integer_dis;

public:
    random(uint64_t seed = 0, int64_t min_integer = 0, int64_t max_integer = 2);
    ~random();

    /*!
     * \brief Change the seed for the initialized number generator. seed = 0 initializes
     * the random number generator with the system time.
     */
    void reseed(uint64_t seed);

    /*!
     * set minimum and maximum for integer random number generator.
     * Limits are [minimum, maximum)
     * Default: [0, std::numeric_limits< IntType >::max)]
     */
    void set_integer_limits(int64_t minimum, int64_t maximum);

    /*!
     * Uniform random integers in the range set by 'set_integer_limits' [min, max).
     */
    int64_t ran_int();

    /*!
     * \brief Uniform random numbers in the range [0.0, 1.0)
     */
    float ran1();

    /*!
     * \brief Normally distributed random numbers (Gaussian distribution with zero mean
     * and variance 1)
     */
    float gasdev();

    /*!
     * \brief Laplacian distributed random numbers with zero mean and variance 1
     */
    float laplacian();

    /*!
     * \brief Rayleigh distributed random numbers (zero mean and variance 1 for the
     * underlying Gaussian distributions)
     */
    float rayleigh();

    /*!
     * \brief Exponentially distributed random numbers with values less than or equal
     * to factor replaced with zero. The underlying exponential distribution has
     * mean sqrt(2) and variance 2.
     */
    float impulse(float factor);

    /*!
     * \brief Normally distributed random numbers with zero mean and variance 1 on real
     * and imaginary part. This results in a Rayleigh distribution for the amplitude and
     * an uniform distribution for the phase.
     */
    gr_complex rayleigh_complex();
};

} /* namespace gr */

#endif /* INCLUDED_GR_RANDOM_H */