简体   繁体   English

如何在不重新发明轮子的情况下为自定义类型生成均匀分布的随机实数?

[英]How to generate uniformly distributed random reals for custom types without reinventing the wheel?

I was going to use std::uniform_real_distribution with some non-builtin floating-point-like types, eg half_float::half or boost::multiprecision::float128 . 我将使用std::uniform_real_distribution与一些非内置类似浮点类型,例如half_float::halfboost::multiprecision::float128 But what I get is 但我得到的是

/opt/gcc-5.2/include/c++/5.2.0/bits/random.h:1868:7: error: static assertion failed: template argument not a floating point type /opt/gcc-5.2/include/c++/5.2.0/bits/random.h:1868:7:错误:静态断言失败:模板参数不是浮点类型

from g++ 5.2. 来自g ++ 5.2。 Here's the example program (compile with g++ -std=c++11 -fext-numeric-literals test.cpp -o test ): 这是示例程序(使用g++ -std=c++11 -fext-numeric-literals test.cpp -o test ):

#include <random>
#include <boost/multiprecision/float128.hpp>
#include <half.hpp>

template<typename Float>
void test()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<Float> rnd(Float(1),Float(10));
}

int main()
{
    test<float>();
    test<double>();
    test<long double>();
    test<boost::multiprecision::float128>(); // doesn't compile
    test<half_float::half>(); // doesn't compile
}

So, how is one supposed to generate uniformly distributed random reals for such custom types? 那么,如何为这样的自定义类型生成均匀分布的随机实数呢? Is there a way to go without reinventing the wheel? 有没有办法不重新发明轮子?

As you can see from here , uniform_real_distribution is defined as: 这里可以看出, uniform_real_distribution定义为:

template< class RealType = double >
class uniform_real_distribution;

Where RealType is: RealType是:

The result type generated by the generator. 生成器生成的结果类型。 The effect is undefined if this is not one of float, double, or long double. 如果这不是float,double或long double之一,则效果未定义。

It seems that your compiler explicitly forbids to use a custom type as a solution to deal with (let me say) unaccepted types . 您的编译器似乎明确禁止使用自定义类型作为解决方案来处理(让我说)未接受的类型 Therefore I would say that you have no chance to get it working. 因此我会说你没有机会让它发挥作用。

The standard random number facilities which work with RealType type as defined in the Standard, must have float , double or long double as type template argument, as in 26.5.1.1.d: 使用标准中定义的RealType类型的标准随机数工具必须具有floatdoublelong double作为类型模板参数,如26.5.1.1.d中所示:

Throughout this subclause 26.5, the effect of instantiating a template: 在本子条款26.5中,实例化模板的效果:

<...> <...>

d) that has a template type parameter named RealType is undefined unless the corresponding template argument is cv-unqualified and is one of float , double , or long double . d)具有名为RealType的模板类型参数是未定义的,除非相应的模板参数是cv-unqualified并且是floatdoublelong double

One solution is to replace std::uniform_real_distribution with boost::random::uniform_real_distribution . 一种解决方案是用boost::random::uniform_real_distribution替换std::uniform_real_distribution boost::random::uniform_real_distribution The latter does accept non-builtin float types. 后者确实接受非内置浮点类型。 Here's an example with a reasonable type * : 这是一个合理类型*的示例:

#include <random>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/multiprecision/float128.hpp>

template<typename Float>
void test()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    boost::random::uniform_real_distribution<Float> rnd(Float(1),Float(10));
}

int main()
{
    test<float>();
    test<double>();
    test<long double>();
    test<boost::multiprecision::float128>();
}

* half_float::half doesn't work because its multiplication by a constant results in a float , while half_float::half(float) constructor is explicit, and Boost's implementation doesn't call it explicitly * half_float::half不起作用,因为它乘以常量会导致float ,而half_float::half(float)构造函数是显式的,而Boost的实现并没有明确地调用它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM