我编写了一些数学函数供我的程序使用,它们将得到大量使用。我想提供代码以查看 a) 是否有逻辑改进,以及 b) 是否有更好的方法来执行这些操作。它是一个头文件,包含在需要的地方。
我不是为 c++11 编译的,所以请记住这一点。 - 我也知道负数的 rootDouble 在数学上是不正确的。
我认为可能首先想到的是将 vector 输入转换为按引用传递,欢迎对此发表评论。
就我接受答案而言,我想知道可以改进哪些功能以及如何改进这些功能以提高速度。
++ 我很快就发布了这个,希望我没有在里面留下任何令人尴尬的错误!
#ifndef MATHSFUNCTIONS_H_
#define MATHSFUNCTIONS_H_
#include <algorithm>
#include <vector>
#include <numeric>
#include <cmath>
class MathsFunctions {
public:
MathsFunctions();
virtual ~MathsFunctions();
inline static double squareDouble(double input) {
return input * input;
}
inline static double rootDouble(double input) {
if (input == 0.0) {
return 0.0;
} else if ( input < 0.0) {
input = flipDouble(input);
input = sqrt(input);
return flipDouble(input);
}
return sqrt(input);
}
inline static double flipDouble(double input) {
return input * -1;
}
inline static double rangeInVec(std::vector<double> inputs) {
return maxInVec(inputs) - minInVec(inputs);
}
inline static double stdDevInVec(std::vector<double> inputs) {
if (inputs.size() < 2) {return 0.0;}
double mean = meanInVec(inputs);
double sq_sum = std::inner_product(inputs.begin(), inputs.end(), inputs.begin(), 0.0);
return std::sqrt(sq_sum / inputs.size() - mean * mean);
}
inline static double meanInVec(std::vector<double> inputs) {
double sum = std::accumulate(inputs.begin(), inputs.end(), 0.0);
return sum / inputs.size();
}
inline static double sumOfVec(std::vector<double> inputs) {
double total = 0.0;
for (unsigned int var = 0; var < inputs.size(); ++var) {
total += inputs[var];
}
return total;
}
inline static double maxInVec(std::vector<double> inputs) {
bool first = true;
double max;
for (unsigned int var = 0; var < inputs.size(); ++var) {
if (first) {
max = inputs[var];
first = false;
} else {
if (inputs[var] > max) {
max = inputs[var];
}
}
}
return max;
}
inline static double minInVec(std::vector<double> inputs) {
bool first = true;
double min;
for (unsigned int var = 0; var < inputs.size(); ++var) {
if (first) {
min = inputs[var];
first = false;
} else {
if (inputs[var] < min) {
min = inputs[var];
}
}
}
return min;
}
inline static std::vector<double> weightValueVector(std::vector<double> inputs,std::vector<double> weights) {
std::vector<double> results;
for (unsigned x = 0; x < inputs.size(); ++x) {
results.push_back(inputs[x] * weights[x]);
}
return results;
}
};
#endif /* MATHSFUNCTIONS_H_ */
最佳答案
也许速度和开发时间的最大收获是 使用现有的线性代数库而不是重新发明 轮子,看
使用 BLAS和 LAPACK已针对您的机器架构进行调整。在 特别是,您机器上可用的 vector 指令和 缓存大小对性能有很大影响。
如果你的 vector 足够小,你可能会得到显着的 通过在堆栈上分配它们来提高性能。现在你是 在堆上分配它们。
通过使用 template metaprogramming techniques你可以消除 许多临时和不必要的循环在编译时。到 在这里重复维基百科的例子:
假设你有
Vec x = alpha*(u - v);
其中alpha
是标量,u
和v
是Vecs
。如果你 以您正在做的方式实现它,它将花费您 至少 2 个临时 vector (一个用于
u-v
,一个用于 乘以alpha
) 和 2 通过内存 (2 或 3 个循环:一个用于u-v
,一个用于 与alpha
相乘,如果没有被优化掉,再为赋值加一个)。如果你进行模板元编程,
Vec x = alpha*(u - v);
将归结为没有临时变量的单个循环,这是你能得到的最好的。表达式越复杂, yield 就越大。在 你没有这些操作的那一刻,但我想这只是一个问题 您需要它们的时间(
weightValueVector()
是一个指示)。
当然,如果您使用线性代数库,您不必了解/担心这些,而是可以专注于您的应用程序并获得超快的代码。
关于c++ - 改进数学函数类以提高速度 c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19328697/