Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem for random seed #71

Closed
linlll opened this issue Aug 17, 2020 · 8 comments
Closed

Problem for random seed #71

linlll opened this issue Aug 17, 2020 · 8 comments
Assignees
Labels
question Further information is requested

Comments

@linlll
Copy link

linlll commented Aug 17, 2020

nc::random::seed(unsigned int(time(NULL)));
cout << nc::random::randFloat<float>(0, 1) << endl;

Here is my code, but the final executable program products the same number every time it starts. However, the following code can generate different numbers each time.

mt19937_64 generator;
generator.seed(unsigned int(time(NULL)));
boost::random::uniform_real_distribution<float> rand(0, 1);
cout << rand(generator) << endl;
@dpilger26
Copy link
Owner

dpilger26 commented Aug 17, 2020

Sorry but I'm not able to reproduce your issue. Can you confirm that the below code doesn't work for you (same value every time)?

#include "NumCpp.hpp"

#include <cstdlib>
#include <ctime>
#include <iostream>

int main()
{
    auto seed = static_cast<nc::uint32>(std::time(NULL));
    nc::random::seed(seed);
    auto randValue = nc::random::randFloat<float>(0, 1);
    std::cout << "seed = " << seed << " value = " << randValue << '\n';

    return EXIT_SUCCESS;
}

I've tried with both GCC-10 and Clang-9, and Boost 1.73. What compiler and Boost version are you using?

@dpilger26 dpilger26 self-assigned this Aug 19, 2020
@dpilger26 dpilger26 added question Further information is requested bug Something isn't working and removed bug Something isn't working labels Aug 19, 2020
@dpilger26
Copy link
Owner

Closing due to inactivity. I will open again if you still believe there is an issue.

@CiaranWelsh
Copy link

CiaranWelsh commented Sep 11, 2020

I'm also having trouble with seeds. It seems that your code:

    auto seed = static_cast<nc::uint32>(std::time(NULL));
    nc::random::seed(seed);
    auto randValue = nc::random::randFloat<float>(0, 1);
    std::cout << "seed = " << seed << " value = " << randValue << '\n';

works, while

    auto seed = static_cast<nc::uint32>(std::time(NULL));
    nc::random::seed(seed);
    auto randValue = nc::random::uniform<double>(0, 1);
    std::cout << "seed = " << seed << " value = " << randValue << '\n';

is deterministic.

Could be my use of double rather than float?

@dpilger26
Copy link
Owner

dpilger26 commented Sep 11, 2020

Can you tell me the compiler and boost versions you are using? I'm once again not able to reproduce an issue. I've tried gcc and clang on Ubuntu, and VS2019 on Windows all appear to be working as expected (non-deterministic when seeding with std::time).

Also, random::uniform is just a convenience wrapper around random::randFloat so it doesn't make any sense that one would work and the other wouldn't...

template<typename dtype>
dtype uniform(dtype inLow, dtype inHigh)
{
    STATIC_ASSERT_FLOAT(dtype);

    return randFloat(inLow, inHigh);
}

@CiaranWelsh
Copy link

Interesting, I'm using MSVC 2019. It may just be my that my program has a bug then - it must be something to do with the way I'm using the seed. Thanks for verifying.

@CiaranWelsh
Copy link

CiaranWelsh commented Sep 12, 2020

I wrote my own basic random number generator for now - and it works as expected. Then I got curious to see whether I could reproduce my problem in a MWE, which apparently I can. This example closely replicates what I'm doing in my project and the strategy works with my own RNG.


#include <chrono>
#include "NumCpp.hpp"

class RNGOptions{
private:
    unsigned long long seed_ = std::chrono::high_resolution_clock::now().time_since_epoch().count();

public:
    RNGOptions() {
        setSeed(seed_);
    }
    explicit RNGOptions(unsigned long long seed) {
        setSeed(seed);
    }
    unsigned long long int getSeed() const {
        return seed_;
    }
    void setSeed(unsigned long long int seed) {
        seed_ = seed;
    }
};


class ClassThatUsesRandomNumberGenerator {
    RNGOptions options_;

public:
    ClassThatUsesRandomNumberGenerator() = default;

    explicit ClassThatUsesRandomNumberGenerator(RNGOptions options)
            : options_(options){};

    const RNGOptions &getOptions() const {
        return options_;
    }
    void setOptions(const RNGOptions &options) {
        options_ = options;
    }

    double randomUniformDouble(double low, double high){
        return nc::random::uniform<double>(low, high);
    }

    int randomUniformInt(int low, int high){
        return nc::random::randInt(low, high);
    }
};


int main(){

    // no seed being set, so uses high res clock time
    ClassThatUsesRandomNumberGenerator generator;
    std::cout << generator.getOptions().getSeed() << std::endl; // outputs a different number each time I run the program
    std::cout << generator.randomUniformDouble(0, 100) << std::endl; // outputs 78.6821 each time I run the program
}

@dpilger26
Copy link
Owner

It looks like you forgot to set the NumCpp random seed in your example code above. I made some slight modifications to your ClassThatUsesRandomNumberGenerator class and everything works correctly on my end.

class ClassThatUsesRandomNumberGenerator {
    RNGOptions options_;

public:
    ClassThatUsesRandomNumberGenerator()
    {
        setSeed();
    }

    explicit ClassThatUsesRandomNumberGenerator(RNGOptions options)
            : options_(options)
    {
        setSeed();
    }

    const RNGOptions &getOptions() const {
        return options_;
    }
    void setOptions(const RNGOptions &options) {
        options_ = options;
        setSeed();
    }

    double randomUniformDouble(double low, double high){
        return nc::random::uniform<double>(low, high);
    }

    int randomUniformInt(int low, int high){
        return nc::random::randInt(low, high);
    }

private:
    void setSeed()
    {
        nc::random::seed(options_.getSeed());
    }
};

@CiaranWelsh
Copy link

Yep, that does indeed work as expected. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants