gpt4 book ai didi

c++ - 大数组大小 C++ 的问题

转载 作者:行者123 更新时间:2023-11-28 05:49:38 25 4
gpt4 key购买 nike

我有一个硕士类(class)的任务,涉及通过蒙特卡罗方法对概率分布进行抽样。我之前想运行一些测试,所以我用 2 自由度对卡方分布进行采样(可以用逆方法完成)。无论如何,我遇到了数组大小的问题,任何超过 ~30000 个元素的元素都会导致概率分布的所有点累积为 1,甚至导致程序崩溃。

文末可以看到10000分的结果截图和我写的代码。我用过很多版本的 g++ 编译器,最高到 4.9.2,但都没有用。操作系统是 Windows 7。Aaa 和相同的代码在 friend 的 gentoo 计算机上完美运行。有什么建议吗?

提前致谢!

曼努埃尔·J。

Sampling with 10000 points

这是我使用的代码:

I've removed it to keep the post shorter. Please see edited code

编辑:我对代码做了几处更改,主要是从普通数组到 vector 的转换,但问题仍然存在:超过 ~10000 个元素的任何内容都不起作用。问题肯定是 histograma 函数:histo.dat 文件的内容当你给它一个太大的 vector 时:

inf 100000
inf 0
inf 0
inf 0
...
inf 0

现在的代码如下。问题肯定是 max 和 min 函数,但我完全不知道问题出在哪里。

#include <iostream>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <vector>
#define PI 3.14159265359
#define NHISTOMAX 100
#define N 100000
#define GNUPLOT_PATH "D:\\gnuplot\\bin\\gnuplot.exe -persist"
using namespace std;
double max (vector<double> v);
double min (vector<double> v);
void histoplot (string name1);
void histograma (string name, vector<double> v, size_t num2);

vector<double> v(N);

int main (void)
{
srand(time(NULL));

for(size_t i=0;i<N;i++)
v[i]=-2*log(1.0*rand()/RAND_MAX);

histograma("hist.dat",v,NHISTOMAX);

histoplot("hist.dat");

system("pause");
return 0;
}

void histograma (string name, vector<double> v, size_t num2)
{
ofstream fileout;
double max1, min1, delta;
size_t i, j, num=v.size();
vector<int> histo(NHISTOMAX);

if(num2>NHISTOMAX) cout << "Too many intervals. " << endl;

else
{
for(i=0;i<num2;i++)
histo[i]=0;

max1=max(v);
min1=min(v);
delta=(max1-min1)/num2;

for(i=0;i<num;i++)
{
j=(size_t)((v[i]-min1)/delta);
if(j==NHISTOMAX) j--;
histo[j]++;
}

fileout.open(name.c_str());
for(i=0;i<num2;i++)
fileout << min1+(i+0.5)*delta << "\t" << histo[i] << endl;
fileout.close();

cout << "Histogram generated! Output file: " << name << endl << endl;
}

return;
}

void histoplot (string name1)
{
FILE *gp1;
gp1=popen(GNUPLOT_PATH,"w");

if(gp1==NULL)
cout << "Unable to open pipe. Check gnuplot.exe's path" << endl;

else
{
fprintf(gp1,"unset key\n");
fprintf(gp1,"set term wxt\n");
fprintf(gp1,"set output\n");
fprintf(gp1,"plot '");
fprintf(gp1,name1.c_str());
fprintf(gp1,"' w histeps\n");
fflush(gp1);
pclose(gp1);
}

return;
}

double max (vector<double> v)
{
double aux=v[0];
size_t i, num=v.size();
for(i=1;i<num;i++)
if(aux<v[i])
aux=v[i];
return aux;
}

double min (vector<double> v)
{
double aux=v[0];
size_t i, num=v.size();
for(i=1;i<num;i++)
if(aux>v[i])
aux=v[i];
return aux;
}

编辑 2:v vector 中值的典型图。所有这些都是阳性且年龄在 25 岁以下。

Plot of a typical vector obtained.

最佳答案

使用std::vector :

#include <vector>
#define N 10000
int main (void)
{
std::vector<double> v(N);
//...
histograma("hist.dat",v.data(), N, NHISTOMAX);
// or
// histograma("hist.dat", &v[0], N, NHISTOMAX);

注意 histograma 没有变化函数本身是必需的。通话中唯一的区别是 v.data() (或 &v[0] )用于返回指向存储 double 数组的内部缓冲区开始的指针.

另外,不要写minmax函数,使用 std::min_elementstd::max_element<algorithm> 中找到 header :

    max1 = *std::max_element(v.begin(), v.end());
min1 = *std::min_element(v.begin(), v.end());

或者如果使用 C++ 11,std::minmax_element获得两者:

    auto pr = std::minmax_element(v.begin(), v.end());
min1 = *(pr.first);
max1 = *(pr.second);

此外,如果如其他答案所建议的那样,并且您有内存覆盖,我建议您更改使用 operator [ ]使用 vector::at()访问您的元素。使用 at()会抛出 out_of_range一旦您进行越界访问,就会出现异常。然后在转换回使用 [ ] 之前修复这些错误对于载体。

例如,这段代码:

        j=(size_t)((v[i]-min1)/delta); 
if(j==NHISTOMAX) j--;
histo[j]++;

如果 j 会怎样是一个巨大的数字,远远超出了 histo 的范围 vector ?递减 j by 1 不会有帮助。要查看这是否是一个问题,at()可以在这里使用:

        j=(size_t)((v[i]-min1)/delta); 
if(j==NHISTOMAX) j--;
histo.at(j)++;

如果你运行程序,如果j超出范围,一旦您尝试增加 histo[j] 就会抛出异常.然后您可以检查问题并修复错误。

关于c++ - 大数组大小 C++ 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35527061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com