[英]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.#INF
, 1.#IND
或1.#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: 更多信息:
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.