【问题标题】:Inconsistent value returned from C++ function vs Python function for skew normal distribution从 C++ 函数与 Python 函数返回的值不一致,用于偏斜正态分布
【发布时间】:2020-05-25 01:23:57
【问题描述】:

我有一个函数可以根据 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++ 实现不一致的原因都会非常有帮助。

【问题讨论】:

    标签: python c++ python-3.x c++11 stl


    【解决方案1】:

    您在我只能假设为浮点运算的情况下使用了大量整数。

    行如

      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));
    

    【讨论】:

    • 这完美地解决了问题 - 我犯了一个愚蠢的错误。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 2020-02-24
    相关资源
    最近更新 更多