在得知可以计算存储在std::vector< std::vector<double> > data
中的数据平均值后,可以通过以下方式完成:
void calculate_mean(std::vector<std::vector<double>>::iterator dataBegin,
std::vector<std::vector<double>>::iterator dataEnd,
std::vector<double>& rowmeans) {
auto Mean = [](std::vector<double> const& vec) {
return std::accumulate(vec.begin(), vec.end(), 0.0) / vec.size(); };
std::transform(dataBegin, dataEnd, rowmeans.begin(), Mean);
}
我创建了一个函数,它接受数据向量的迭代器的开始和结束来计算平均值,std::vector<double>
是我存储结果的位置。
我的第一个问题是,在使用向量时如何处理函数的返回值。我的意思是在这种情况下我创建一个Alias并以这种方式修改我在调用此函数之前初始化的向量,因此没有复制回来这很好。这是一个很好的编程实践吗?
其次我的主要问题是,如何调整这个功能,以便以类似的方式计算每一行的标准差。我真的很努力,但它只是给了一个很大的混乱,没有什么工作正常。因此,如果有人立即看到它如何做到这一点,我会很高兴,以获得洞察力。谢谢。
编辑:解决方案
所以这是我解决问题的方法。给定std::vector< vector<double> > data (rows, std::vector<double>(columns))
,数据存储在行中。以下函数同时计算每行的样本标准差。
auto begin = data.begin();
auto end = data.end();
std::vector<double> std;
std.resize(data.size());
void calculate_std(std::vector<std::vector<double>>::iterator dataBegin,
std::vector<std::vector<double>>::iterator dataEnd,
std::vector<double>& rowstds){
auto test = [](std::vector<double> const& vec) {
double sum = std::accumulate(vec.begin(), vec.end(), 0.0);
double mean = sum / vec.size();
double stdSum = 0.0;
auto Std = [&](const double x) { stdSum += (x - mean) * (x - mean); };
std::for_each(vec.begin(), vec.end(), Std);
return sqrt(stdSum / (vec.size() - 1));
};
std::transform(dataBegin, dataEnd, rowstds.begin(), test);
}
我测试了它,它工作得很好。因此,如果有人有一些改进建议,请告诉我。这段代码是否具有良好的性能?
答案 0 :(得分:0)
您会找到相对常见的惯例,用输入参数优先编写函数,然后是输入/输出参数。 输出参数(使用函数的返回值写入)通常是指向数据或引用的指针。 从这个角度来看,你的解决方案看起来很完美。
答案 1 :(得分:0)
我的意思是在这种情况下我创建一个Alias并以这种方式修改我在调用此函数之前初始化的向量,因此没有复制回来这很好。这是一个很好的编程实践吗?
不,您应该使用本地vector<double>
变量并按值返回。任何值得使用的编译器都是optimize away the copying/moving,并且如果由于某种原因它无法完全忽略复制/移动,则需要任何符合要求的C ++ 11编译器来执行移动。
您编写的代码对调用者施加了不明显的附加要求。例如,rowmeans
必须包含足够的元素来存储均值或未定义的行为结果。