Program Listing for File random.hpp

Return to documentation for file (src/navtk/experimental/random.hpp)

#pragma once

#include <memory>
#include <random>
#include <xtensor/generators/xrandom.hpp>

#include <navtk/not_null.hpp>
#include <navtk/tensors.hpp>

namespace navtk {
// TODO #613: Remove random number generation support from experimental namespace once rng is
// verified.

namespace experimental {

void s_rand(uint64_t seed);

void s_rand_local(uint64_t const seed);

double rand_local();

double as_double(uint64_t v);

inline uint64_t pcg_random_r();

class RandomNumberGenerator {
public:
    RandomNumberGenerator() = default;
    RandomNumberGenerator(const RandomNumberGenerator&) = delete;
    RandomNumberGenerator(RandomNumberGenerator&&) = delete;
    RandomNumberGenerator& operator=(const RandomNumberGenerator&) = delete;
    RandomNumberGenerator& operator=(RandomNumberGenerator&&) = delete;

    virtual ~RandomNumberGenerator() = default;

    virtual void seed(uint64_t seed) = 0;

    virtual double rand() = 0;

    Vector rand(int num);

    Matrix rand(int num_rows, int num_cols);

    virtual double rand_n();

    Vector rand_n(int num);

    Matrix rand_n(int num_rows, int num_cols);

private:
    double spare   = 0.0;
    bool has_spare = false;
};

template <typename TEngine>
class RandomNumberEngineWrapper : public RandomNumberGenerator {
public:
    TEngine engine;

    std::uniform_real_distribution<double> converter;

    RandomNumberEngineWrapper() : RandomNumberGenerator(), engine(), converter(0.0, 1.0) {}

    double rand() override { return converter(engine); }

    void seed(uint64_t seed) override { engine.seed(seed); }
};

class LocalEngineWrapper : public RandomNumberGenerator {
public:
    double rand() override { return rand_local(); }

    void seed(uint64_t seed) override { s_rand_local(seed); }
};

not_null<std::shared_ptr<RandomNumberGenerator>> get_global_rng();


void set_global_rng(not_null<std::shared_ptr<RandomNumberGenerator>> randomness);


template <typename TEngine>
void set_global_rng() {
    set_global_rng(std::make_shared<RandomNumberEngineWrapper<TEngine>>());
}


double rand();


Vector rand(int num);


Matrix rand(int num_rows, int num_cols);


double rand_n();


Vector rand_n(int num);


Matrix rand_n(int num_rows, int num_cols);

}  // namespace experimental
}  // namespace navtk