简体   繁体   English

本征:log()的计算限制是什么? (Windows和Linux)

[英]Eigen: What is the computational limitation for log()? (Windows vs. Linux)

I have a strange problem with my Eigen code. 我的Eigen代码有一个奇怪的问题。 It works well on Linux (64 bit) and Mac OSX (64 bit), but it fails on Windows (32 bit) with an 1.#INF value. 它在Linux(64位)和Mac OSX(64位)上运行良好,但在Windows(32位)上具有1.#INF值时失败。

I traced down the problem to this function, where I implemented the Box-Muller-transform: 我将问题归结为该函数,在其中实现了Box-Muller-transform:

Eigen::MatrixXd box_muller ( const Eigen::VectorXd vRand )
{
    unsigned long n = vRand.rows();
    unsigned long m = n/2;

    Eigen::ArrayXd rand1 = vRand.head ( m );
    Eigen::ArrayXd rand2 = vRand.tail ( m );

    /* Implemented according to
     * http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
     */

    for ( unsigned long i=0; i<rand1.cols(); i++ )
    {
        if ( rand1 ( i ) < 1e-8 )
        {
            rand1 ( i ) = 1e-8;
        }
    }

    rand1 = (-2 * rand1.log()).sqrt(); // something must be wrong here

    std::cout << rand1.mean() << std::endl; // prints 1.#INF

    rand2 = rand2*2*M_PI;

    Eigen::MatrixXd result ( 2*m, 1 );
    Eigen::MatrixXd res1 = ( rand1 *rand2.cos() ).matrix();
    Eigen::MatrixXd res2 = ( rand1 *rand2.sin() ).matrix();
    result << res1, res2;

    return result;
}

This piece of code fails, but only on Windows and only for large input vectors vRand. 这段代码失败,但仅在Windows上且仅对于较大的输入向量vRand。 It fails because in rand1 there are unexpected values that generate 1.#INF , -1.#INF , 1.#IND or 1.#QNAN values in subsequent computations. 之所以失败,是因为在rand1有意外的值在随后的计算中生成1.#INF-1.#INF1.#IND1.#QNAN值。 When I set the number of elements in vRand to a small number, say, 10000 , it works fine. 当我将vRand的元素数设置为较小的数字(例如10000 ,它可以正常工作。 But when the number is large (eg 100000 ) it fails. 但是,如果数量很大(例如100000 ),它将失败。

I tried everything I could think of and now I am out of ideas. 我尝试了所有我能想到的,但现在我没主意了。 What can I try to eliminate this problem? 我该如何解决这个问题?

More info: 更多信息:

  • We're building this with MS Visual Studio 12.0. 我们正在使用MS Visual Studio 12.0构建它。 It runs on a buildserver, therefore I cannot find out the exact version easily. 它在构建服务器上运行,因此我无法轻松找到确切的版本。
  • We are using C++0x, as far as I know. 据我所知,我们正在使用C ++ 0x。

I suggest replacing this loop: 我建议替换此循环:

for ( unsigned long i=0; i<rand1.cols(); i++ )
{
    if ( rand1 ( i ) < 1e-8 )
    {
        rand1 ( i ) = 1e-8;
    }
}

with: 与:

rand1 = rand1.max(1e-8); // limit min value to 1e-8
rand1 = rand1.min(1.0);  // limit max value to 1.0

This would then guarantee that the values of rand1.log() will be <= 0 and the subsequent sqrt() should not then fail. 然后,这将确保rand1.log()的值将<= 0 ,并且随后的sqrt()应该不会失败。 If this fixes the problem then you might want to work backwards to identify where the out-of-range input values are coming from. 如果这解决了问题,则您可能需要向后工作以识别超出范围的输入值的来源。

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

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