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

Posted

技术标签:

【中文标题】从 C++ 函数与 Python 函数返回的值不一致,用于偏斜正态分布【英文标题】:Inconsistent value returned from C++ function vs Python function for skew normal distribution 【发布时间】: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++ 实现不一致的原因都会非常有帮助。

【问题讨论】:

【参考方案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));

【讨论】:

这完美地解决了问题 - 我犯了一个愚蠢的错误。非常感谢!

以上是关于从 C++ 函数与 Python 函数返回的值不一致,用于偏斜正态分布的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 从预定义的 C++ 函数中获取变量的值?

从lua的c源码了解lua栈结构和函数调用流程

PyObject_GetAttrString C++ 函数返回 NULL:无法从 C++ 调用 Python 函数

如何使用 ctypes 将数组从 C++ 函数返回到 Python

如何将数组从 c++ 传递给 python 函数并将 python 返回的数组检索到 c++

在 SWIG 中将结构从 C++ 函数返回到 Python