从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布



我有一个函数,可以从C++和Python中的偏斜正态分布估计alpha参数。Python 函数使用 NumPy 编写,C++ 函数使用 STL。我的问题是我的C++实现给了我不正确的结果。这两个函数本质上是相同的,但 Python 版本给了我正确的结果,而C++没有 - 我已经对此进行了一些详细的调查,我无法得出导致错误的原因的结论,任何帮助都会很棒。

蟒蛇函数

import numpy as np
def convert_to_alpha(skew):
a = np.pi/2 
skew_ = abs(skew)
numerator = np.power(skew_, (2/3)) 
b = (4-np.pi)/2
b = np.power(b, (2/3))
denom = numerator + b
delta = np.sqrt(a * (numerator/denom))
a = delta/np.sqrt((1-np.power(delta, 2)))
return a * np.sign(skew)

C++功能

double convert_to_alpha(double skew)
{
double pi = 3.141592653589793;
double a = pi / 2;
double skew_ = std::abs(skew);
double numerator = std::pow(skew_, (2 / 3));
double b = (4 - pi) / 2;
b = std::pow(b, (2 / 3));
double denom = numerator + b;
double delta = std::sqrt(a * (numerator / denom));
double alpha = delta / std::sqrt((1 - std::pow(delta, 2)));
if (skew == 0) { return 0; }
else if (std::signbit(skew) == 1) { return -1 * alpha; } 
else return alpha; 
}

Python 函数返回我期望的值,而 C++ 函数则没有,作为输入 0.99 的示例,我期望 27.85xxxx 或输入 0.5 我希望 2.17xxxx,这正是我从 Python 实现中得到的,C++给了我 1.91306。

此外,奇怪的是 - 无论输入如何,C++实现似乎都返回 1.91306。

C++的驱动程序代码

#include <cmath>
#include <math.h>
#include <iostream>
int main()
{
double convert_to_alpha(double skew);
std::cout << "skew: " << convert_to_alpha(0.99);
return 0;
}
double convert_to_alpha(double skew)
{
double pi = 3.141592653589793;
double a = pi / 2;
double skew_ = std::abs(skew);
double numerator = std::pow(skew_, (2 / 3));
double b = (4 - pi) / 2;
b = std::pow(b, (2 / 3));
double denom = numerator + b;
double delta = std::sqrt(a * (numerator / denom));
double alpha = delta / std::sqrt((1 - std::pow(delta, 2)));
if (skew == 0) { return 0; } // if skew is 0 return 0 
else if (std::signbit(skew) == 1) { return -1 * alpha; } // if skew is negative return -alpha
else return alpha; // if skew is positive return alpha
}

我希望结果非常相似,绝对不像现在那么不同。我以前没有遇到过这样的问题,因此任何帮助找出导致与C++实现不一致的原因都将非常有帮助。

你在我只能假设是浮点运算的情况下使用了很多整数。

诸如

double numerator = std::pow(skew_, (2 / 3));

将解析为

double numerator = std::pow(skew_, 0);

因为整数中的 2/3 只是被下限到 0

如果要确保这些类型的除法保持其正确的值,请确保至少有一个操作数是浮点型或双精度型:

double numerator = std::pow(skew_, (2.0 / 3.0));

最新更新