我具有从C ++和Python中的偏态正态分布估计alpha参数的功能。 Python函数使用NumPy编写,而C ++函数使用STL。我的问题是我的C ++实现给我错误的结果。这两个函数在本质上是相同的,但是Python版本给了我正确的结果,而C ++却没有给我-我已经详细研究了这个问题,而且我不能得出导致错误的原因的结论,任何帮助都是很大的。
Python函数
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));