c++ - 改进数学函数类以提高速度 c++

标签 c++ math inline vectormath

我编写了一些数学函数供我的程序使用,它们将得到大量使用。我想提供代码以查看 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_ */

最佳答案

  1. 也许速度和开发时间的最大收获是 使用现有的线性代数库而不是重新发明 轮子,看

  2. 使用 BLASLAPACK已针对您的机器架构进行调整。在 特别是,您机器上可用的 vector 指令和 缓存大小对性能有很大影响。

  3. 如果你的 vector 足够小,你可能会得到显着的 通过在堆栈上分配它们来提高性能。现在你是 在堆上分配它们。

  4. 通过使用 template metaprogramming techniques你可以消除 许多临时和不必要的循环在编译时。到 在这里重复维基百科的例子:

    假设你有 Vec x = alpha*(u - v); 其中 alpha 是标量,uvVecs

    如果你 以您正在做的方式实现它,它将花费您 至少 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/

相关文章:

c++传递数组而不是可变长度参数列表

c++ - 使用 .at(int) 检查字符串是否仅包含唯一字符

c++ - (C++,Qt,Linux) 将游戏 map 坐标转换为图像坐标

java - 计算圆弧平移多远以避免相交

c++ - 我如何使用 gcc 的内联报告 (-Winline)

CSS。删除溢出-y。现在好了。保持元素内联

c++ - C++ 中的快速函数对象?

math - 从带有 x 轴的向量计算角度(梯度)

c# - 我可以检查 C# 编译器是否内联方法调用吗?

c++ - 如何在 C++ 中使用 cin 隐藏用户输入?