Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何优化c++;用于卷积程序_C++_For Loop_Convolution - Fatal编程技术网

C++ 如何优化c++;用于卷积程序

C++ 如何优化c++;用于卷积程序,c++,for-loop,convolution,C++,For Loop,Convolution,我是新手,我有一个卷积程序,它接收一个数据文件,卷积并输出另一个文件。我在这里附上代码 void convolute() { ifstream fin; ofstream fout; int count = 0; double a=0,b=0; string input_file_string = "maxclus_500000node_3M_5000ens_666.dat"; string output_file_string = "1co

我是新手,我有一个卷积程序,它接收一个数据文件,卷积并输出另一个文件。我在这里附上代码

void convolute()
{
    ifstream fin;
    ofstream fout;

    int count = 0;
    double a=0,b=0;

    string input_file_string = "maxclus_500000node_3M_5000ens_666.dat";

    string output_file_string = "1convolute_"+input_file_string;

    fin.open(input_file_string.c_str());

    while(fin) //to know the size of array to initialize
    {
        fin>>a>>b;
        count++;

    }

    fin.close();
    double* c = NULL;
    c = new double[count+1];
    double* d = NULL;
    d = new double[count+1];

    for(int i=0;i<count+1;i++)
    {
        c[i] = 0;
        d[i] = 0;
    }

    fin.open(input_file_string.c_str());

    int n = 1;

    while(fin) //takes in data
    {
        fin>>a>>b;
        c[n] = a;
        d[n] = b;
        n++;
    }

    fin.close();

    double* binom = NULL;
    binom = new double[count];

    double* summ = NULL;
    summ = new double[count+1];

    for(int i=0;i<count+1;i++) summ[i] = 0;

    for(int i=0;i<count;i++) binom[i] = 0;

    for(int j=1;j<count;++j) //main convolution of data takes place
    {
        int x,y;
        double prob = j*1.0/(count-1);
        binom[j] = 1;

        for(int i=j+1;i<count;++i)
            binom[i] = binom[i-1]*((count-1)-i+1)*1.0/i*prob/(1-prob);

        for(int i=j-1;i>=0;--i)
            binom[i] = binom[i+1]*(i+1)*1.0/((count-1)-i)*(1-prob)/prob;

        double sum = 0;

        for(int i=0;i<count;++i) sum += binom[i];
        for(int i=0;i<count;++i) binom[i] /= sum;

        sum = 0;

        for(int i=1;i<count;++i) sum += d[i]*binom[i];

        summ[j] = sum;

        //fout<<c[j]<<'\t'<<sum<<endl;
        if(j%1000==0)
            cout<<count-1<<'\t'<<j<<endl;

    }

    cout<<"writing to file "<<endl;

    fout.open(output_file_string.c_str());

    for(int i=1;i<count;i++) fout<<c[i]<<'\t'<<summ[i]<<endl;

        fout.close();

    delete [] c;
    c = NULL;
    delete [] d;
    d = NULL;

    delete [] binom;
    binom = NULL;

    delete [] summ;
    summ = NULL;

}
无效卷积()
{
流鳍;
流式流量计;
整数计数=0;
双a=0,b=0;
字符串输入_file_string=“maxclus_500000node_3M_5000ens_666.dat”;
字符串输出\u文件\u字符串=“1Convolume”+输入\u文件\u字符串;
打开(输入_文件_string.c_str());
while(fin)//知道要初始化的数组的大小
{
fin>>a>>b;
计数++;
}
fin.close();
double*c=NULL;
c=新的双精度[计数+1];
double*d=NULL;
d=新的双精度[计数+1];
对于(inti=0;i>a>>b;
c[n]=a;
d[n]=b;
n++;
}
fin.close();
double*binom=NULL;
binom=新的双精度[计数];
double*sum=NULL;
总和=新的双精度[计数+1];

对于(int i=0;i由于嵌套的for循环,仅代码中进行卷积的部分的运行时间为T(n)=5n2+…对于n较大的文件,这显然是相当低效的

要解决这一问题,您需要减少只有一行代码的for循环的数量。如果您遍历整个数组,请在一次遍历中执行尽可能多的操作。要优化这一点,您需要重新构造执行逻辑的方式,以使for循环尽可能少

您需要使用数组吗?向量的用途与您在读取文件时添加元素的用途相同(而且更有效)。因此

vector.size();
为您提供向量的大小。此外,仅当您要递增元素时,才需要使用整个循环将数组初始化为0。如果您只是简单地分配元素,则将数组初始化为0没有任何意义

如果所有这些都在一个函数中,那么您真的需要将其拆分。整个函数的风格很糟糕,因为有许多不必要的操作,大量的for循环,函数太长,并且函数本身做的事情太多,超出了卷积输入的范围

#include <vector>
#include <fstream>

void convolute(/*data you need*/);

int main() {
  string input_file_string = "maxclus_500000node_3M_5000ens_666.dat";
  string output_file_string = "1convolute_"+input_file_string;

  ifstream fin (input_file_string);
  ofstream fout (output_file_string);

  int count = 0;
  double a=0,b=0;
  vector<double> c;
  vector<double> d;

  while (fin >> a >> b) {
    c.push_back(a);
    d.push_back(d);
  }
  fin.close();

  vector<double> binom;
  vector<double> summ;

  convolute(/*Pass the Data you need*/);
  ...
}
#包括
#包括
无效卷积(/*您需要的数据*/);
int main(){
字符串输入_file_string=“maxclus_500000node_3M_5000ens_666.dat”;
字符串输出\u文件\u字符串=“1Convolume”+输入\u文件\u字符串;
ifstream fin(输入文件\字符串);
ofstream fout(输出文件\字符串);
整数计数=0;
双a=0,b=0;
载体c;
载体d;
而(fin>>a>>b){
c、 推回(a);
d、 推回(d);
}
fin.close();
向量二项式;
向量求和;
卷积(/*传递所需的数据*/);
...
}

看看这有多简单?使用正确的数据类型大大简化了您的生活。此外,为了可读性,请将操作放在下一行的for循环中。这使得这里发生的事情更加明显,您仍然不需要使用括号(只要代码只有一行).

我试图删除你们中的一些循环。 请随意询问我的意见是否不足

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <tuple>
#include <algorithm>

using std::cout;
using std::endl;

using std::ifstream;
using std::ofstream;

using std::string;
using std::vector;
using std::pair;

void convolute()
{

    string input_file_string = "maxclus_500000node_3M_5000ens_666.dat";
    string output_file_string = "1convolute_" + input_file_string;


    double a = 0, b = 0;
    vector<pair<double, double>> coordinates;

    ifstream fin;
    fin.open(input_file_string.c_str());
    while (fin)
    {
        fin >> a >> b;
        coordinates.push_back({ a,b });
    }
    fin.close();

    static int count = (int)coordinates.size();
    vector<double> binom(coordinates.size(), 0);
    vector<double> summ(coordinates.size(), 0);

    const double probMul = 1.0 / (coordinates.size() - 1); //Probability multiplicator

    for (int j = 1; j< coordinates.size(); ++j) //main convolution of data takes place
    {
        const double prob = j*probMul;

        binom[j] = 1;

        double sum = binom[j];
        double sum_x = binom[j] * coordinates[j].second; // <- (A/X) + (B/X) +... <=> (A+B+C+...)/X
        for (int i = j + 1; i < count; ++i) //from j+1 to end
        {
            binom[i] = binom[i - 1] * ((count - 1) - i + 1)*1.0 / i*prob / (1 - prob);
            sum += binom[i];
            sum_x += binom[i] * coordinates[i].second;
        }
        for (int i = j - 1; i >= 0; --i)  //from j-1 to front
        {
            binom[i] = binom[i + 1] * (i + 1)*1.0 / ((count - 1) - i)*(1 - prob) / prob;
            sum += binom[i];
            sum_x += binom[i] * coordinates[i].second;
        }

        summ[j] = sum_x / sum;

        if (j % 1000 == 0)
        {
            cout << count - 1 << '\t' << j << endl;
        }
    }


    cout << "writing to file " << endl;

    ofstream fout;
    fout.open(output_file_string.c_str());
    for (int i = 1; i < count; i++)
    {
        fout << coordinates[i].first << '\t' << summ[i] << endl;
    }
    fout.close();
}
#包括
#包括
#包括
#包括
#包括
#包括
使用std::cout;
使用std::endl;
使用std::ifstream;
使用std::of流;
使用std::string;
使用std::vector;
使用std::pair;
虚空卷积()
{
字符串输入_file_string=“maxclus_500000node_3M_5000ens_666.dat”;
字符串输出\u文件\u字符串=“1Convolume”+输入\u文件\u字符串;
双a=0,b=0;
矢量坐标;
流鳍;
打开(输入_文件_string.c_str());
而(财务)
{
fin>>a>>b;
坐标。推回({a,b});
}
fin.close();
静态整数计数=(int)坐标.size();
向量binom(坐标.size(),0);
向量总和(坐标.size(),0);
const double probMul=1.0/(coordinates.size()-1);//概率乘法器
对于(int j=1;j应该询问是否可以改进工作代码,有一件事您可能会做,那就是展开您在那里的一些循环(int i=0;i@MariusBancila你不应该把循环展开留给编译器吗?我怀疑这会使程序显著加快…计算时间占多少,IO时间占多少?与伪写时间相比,按原样计算时间。(循环可能有它自己的功能,这将帮助探查器告诉您需要花费的时间。)我不怀疑O(n**2)循环是一个主要因素,但IO也经常被低估。我有一些想法,但不确定是否按照其他人的建议将它们发布到这里,以将此线程移动到CodeReview。你打算这样做吗?