C++ 稀疏矩阵中对数熵的优化计算

C++ 稀疏矩阵中对数熵的优化计算,c++,c,math,C++,C,Math,我有一个3007 x 1644维的术语和文档矩阵。我试图为每个文档中的术语频率分配权重,所以我使用这个对数熵公式(参见最后一行的熵公式) 我正在成功地执行此操作,但我的代码运行时间>7分钟。 代码如下: int N = mat.cols(); for(int i=1;i<=mat.rows();i++){ double gfi = sum(mat(i,colon()))(1,1); //sum of occurrence of terms double g =0;

我有一个3007 x 1644维的术语和文档矩阵。我试图为每个文档中的术语频率分配权重,所以我使用这个对数熵公式(参见最后一行的熵公式)

我正在成功地执行此操作,但我的代码运行时间>7分钟。 代码如下:

int N = mat.cols();
for(int i=1;i<=mat.rows();i++){
    double gfi = sum(mat(i,colon()))(1,1); //sum of occurrence of terms
    double g =0;
    if(gfi != 0){// to avoid divide by zero error

        for(int j = 1;j<=N;j++){
            double tfij = mat(i,j);
            double pij = gfi==0?0.0:tfij/gfi;
            pij = pij + 1; //avoid log0
            double G = (pij * log(pij))/log(N);
            g = g + G;
        }
    }

    double gi = 1 - g;
    for(int j=1;j<=N;j++){
        double tfij = mat(i,j) + 1;//avoid log0
        double aij = gi * log(tfij);
        mat(i,j) = aij;
    }
}
int N=mat.cols();

对于(int i=1;i,这里有一个非常简单的重写,删除了一些冗余:

int const N = mat.cols();
double const logN = log(N);

for (int i = 1; i <= mat.rows(); ++i)
{
    double const gfi = sum(mat(i, colon()))(1, 1);  // sum of occurrence of terms
    double g = 0;

    if (gfi != 0)
    {
        for (int j = 1; j <= N; ++j)
         {
            double const pij = mat(i, j) / gfi + 1;
            g += pij * log(pij);
        }
        g /= logN;
    }

    for (int j = 1; j <= N; ++j)
    {
        mat(i,j) = (1 - g) * log(mat(i, j) + 1);
    }
}
实际上,您甚至可以像这样为
循环编写第一个内部
,避免在不需要时进行除法:

        for (int j = 1; j <= N; ++j)
        {
            if (double pij = mat(i, j))
            {
                pij /= gfi;
                g += pij * log(pij);
            }
        }

用于(int j=1;j停止复制周围的所有数据!只有~5M个操作,在普通计算机中应该需要几秒钟。您是否使用-O3优化编译?您使用的是什么矩阵库?我目前正在使用O2进行优化,但让我试试。@Kerrek Goood point也感谢我使用amlpp它有类似的语法使用matlab,但我不确定它有多快。@Aki我已经更新了它。但是速度还是一样。+1它现在只需要4.2秒就可以运行了。太棒了!谢谢。我包括了O3标志though@unekwu请用您最初的优化发布时间,谢谢“x->x*log(x)”不会未定义,因为您已将1添加到pij@unekwu当前位置我是说去掉“+1”,这在数学上很奇怪。请参阅添加的建议。
        for (int j = 1; j <= N; ++j)
        {
            if (double pij = mat(i, j))
            {
                pij /= gfi;
                g += pij * log(pij);
            }
        }