在 C++ 中,如何使用向量视图和 gsl_stats_mean 计算整数向量的平均值?

发布于 2024-10-15 06:29:59 字数 1049 浏览 3 评论 0原文

我的程序操作整数的STL向量,但是,有时,我需要计算它们的一些统计数据。因此我使用GSL 函数。为了避免将 STL 向量复制到 GSL 向量中,我创建了一个 GSL 向量视图,并将其提供给 GSL 函数,如这段代码所示:

#include <iostream>
#include <vector>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_statistics.h>
using namespace std;

int main( int argc, char* argv[] )
{
  vector<int> stl_v;
  for( int i=0; i<5; ++i )
    stl_v.push_back( i );

  gsl_vector_int_const_view gsl_v = gsl_vector_int_const_view_array( &stl_v[0], stl_v.size() );

  for( int i=0; i<stl_v.size(); ++i )
    cout << "gsl_v_" << i << "=" << gsl_vector_int_get( &gsl_v.vector, i ) << endl;

  cout << "mean=" << gsl_stats_mean( (double*) gsl_v.vector.data, 1, stl_v.size() ) << endl;
}

一旦编译 (gcc -lstdc++ -lgsl -lgslcblas test.cpp),此代码输出:

gsl_v_0=0
gsl_v_1=1
gsl_v_2=2
gsl_v_3=3
gsl_v_4=4
mean=5.73266e-310

矢量视图已正确创建,但我不明白为什么平均值是错误的(它应该等于 10/5=2)。有什么想法吗?提前致谢。

my program manipulates STL vectors of integers but, from time to time, I need to calculate a few statistics on them. Therefore I use the GSL functions. To avoid copying the STL vector into a GSL vector, I create a GSL vector view, and give it to the GSL functions, as in this piece of code:

#include <iostream>
#include <vector>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_statistics.h>
using namespace std;

int main( int argc, char* argv[] )
{
  vector<int> stl_v;
  for( int i=0; i<5; ++i )
    stl_v.push_back( i );

  gsl_vector_int_const_view gsl_v = gsl_vector_int_const_view_array( &stl_v[0], stl_v.size() );

  for( int i=0; i<stl_v.size(); ++i )
    cout << "gsl_v_" << i << "=" << gsl_vector_int_get( &gsl_v.vector, i ) << endl;

  cout << "mean=" << gsl_stats_mean( (double*) gsl_v.vector.data, 1, stl_v.size() ) << endl;
}

Once compiled (gcc -lstdc++ -lgsl -lgslcblas test.cpp), this code outputs this:

gsl_v_0=0
gsl_v_1=1
gsl_v_2=2
gsl_v_3=3
gsl_v_4=4
mean=5.73266e-310

The vector view is properly created but I don't understand why the mean is wrong (it should be equal to 10/5=2). Any idea? Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

╭⌒浅淡时光〆 2024-10-22 06:29:59

转换为 double* 非常可疑。

每当您想使用演员表时,请三思而后行。然后寻找一种无需强制转换的方法(如果转换是隐式的,则可以通过引入临时变量)。然后在施法之前再三考虑。

由于内存区域实际上并不包含 double 值,因此代码只是将其中的位模式解释为表示双精度数,这会产生可预见的不良影响。将 int* 转换为 double* 与转换数组的每个元素非常不同。

The cast to double* is very suspicious.

Any time you are tempted to use a cast, think again. Then look for a way to do it without a cast (maybe by introducing a temporary variable if the conversion is implicit). Then think a third time before you cast.

Since the memory region does not actually contain double values, the code is simply interpreting the bit patterns there as if they represented doubles, with predictably undesired effects. Casting an int* to double* is VERY different from casting each element of the array.

执笏见 2024-10-22 06:29:59

使用整数统计函数:

cout << "mean=" << gsl_stats_int_mean( gsl_v.vector.data, 1, stl_v.size() ) << endl;

请注意 gsl_stats_int_mean 而不是 gsl_stats_mean

Use the integer statistics functions:

cout << "mean=" << gsl_stats_int_mean( gsl_v.vector.data, 1, stl_v.size() ) << endl;

Note the gsl_stats_int_mean instead of gsl_stats_mean.

溺ぐ爱和你が 2024-10-22 06:29:59

除非你做的统计数据比平均值复杂得多,否则我会忽略 gsl 并只使用标准算法:

double mean = std::accumulate(stl_v.begin(), stl_v.end(), 0.0) / stl_v.size();

当/如果使用统计库是合理的,你的第一选择可能应该是寻找其他更好的东西设计(例如,升压累加器)。

如果您出于某种原因决定确实需要使用 gsl,那么看起来您必须将 int 数组复制到 double 数组首先,然后对结果使用 gsl。这显然效率很低,尤其是当您处理大量数据时——因此之前的建议是使用其他东西来代替。

Unless you're doing a lot of statistics considerably more complex than the mean, I'd ignore gsl and just use standard algorithms:

double mean = std::accumulate(stl_v.begin(), stl_v.end(), 0.0) / stl_v.size();

When/if using a statistical library is justified, your first choice should probably be to look for something else that's better designed (e.g., Boost Accumulators).

If you decide, for whatever reason, that you really need to use gsl, it looks like you'll have to copy your array of ints to an array of doubles first, then use gsl on the result. This is obvious quite inefficient, especially if you're dealing with a lot of data -- thus the previous advice to use something else instead.

野の 2024-10-22 06:29:59

虽然我不熟悉 GSL,但表达式 (double*) gsl_v.vector.data 看起来非常可疑。您确定reinterpret_cast该指针来获取double数据是正确的吗?

Although I'm not familiar with GSL, the expression (double*) gsl_v.vector.data looks extremely suspicious. Are you sure it's correct to reinterpret_cast that pointer to get double data?

吃→可爱长大的 2024-10-22 06:29:59

转换为 double* 会弄乱您的数据。它并不是将数据转换为 double ,而只是将 int 二进制数据用作 double 。

Casting to double* is messing up your data. It is not converting data into double, but just using int binary data as double

演多会厌 2024-10-22 06:29:59

根据 http://www .gnu.org/software/gsl/manual/html_node/Mean-and-standard-deviation-and-variance.html gsl_stats_mean 函数采用一个 double 数组.您正在获取 int 的向量并告诉它使用原始字节作为double,这是无法正常工作的。

您需要设置一个临时的 double 向量来传入:

// Assumes that there's at least one item in stl_v.
std::vector<double> tempForStats(stl_v.begin(), stl_v.end());
gsl_stats_mean(&tempForStats[0], 1, tempForStats.size());

编辑:您还可以使用标准库算法自己执行 int 表示:

// Assumes that there's at least one item in stl_v.
double total = std::accumulate(stl_v.begin(), stl_v.end(), 0);
double mean = total / stl_v.size();

According to http://www.gnu.org/software/gsl/manual/html_node/Mean-and-standard-deviation-and-variance.html the gsl_stats_mean function takes an array of double. You're taking a vector of int and telling it to use the raw bytes as double which isn't going to work right.

You'll need to set up a temporary vector of double to pass in:

// Assumes that there's at least one item in stl_v.
std::vector<double> tempForStats(stl_v.begin(), stl_v.end());
gsl_stats_mean(&tempForStats[0], 1, tempForStats.size());

EDIT: You could also use standard library algorithms to do the int mean yourself:

// Assumes that there's at least one item in stl_v.
double total = std::accumulate(stl_v.begin(), stl_v.end(), 0);
double mean = total / stl_v.size();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文