我是新手,我有一个卷积程序,它接收一个数据文件,卷积它并输出另一个文件。我在这里附上代码。
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 :(得分:0)
由于嵌套的for循环,只进行卷积的代码部分的运行时间为T(n)= 5n 2 + ....这显然是相当低效的。 n很大的文件。
要解决此问题,您需要减少只有一行代码的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*/);
...
}
看看这有多简单?使用正确的数据类型可以极大地简化您的生活。另外,为了便于阅读,请将操作放在下一行的for循环中。这使得更明显的是那里有一些东西,你仍然不需要使用括号(只要代码只有一行)。
答案 1 :(得分:0)
我试图删除你的一些循环。 请随意询问我的评论是否不充分。
#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();
}
我无法测试它 - 所以这取决于你。