优化稀疏矩阵中的对数熵计算
Optimize log entropy calculation in sparse matrix
我有一个 3007 x 1644 维的术语和文档矩阵。我正在尝试为每个文档中的术语频率分配权重,因此我 http://en.wikipedia.org/wiki/Latent_semantic_indexing#Term_Document_Matrix 使用此对数熵公式(请参阅最后一行中的熵公式)。
我成功地做到了这一点,但我的代码运行了>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;
}
}
有人知道我如何优化它以使其更快吗?Oh and mat 是来自 amlpp 矩阵库的 RealSparseMatrix。
更新代码在具有4gb RAM和AMD Athlon II双核的Linux mint上运行
。更换前运行时间:>7分钟
@Kereks回答后:4.1秒
这是一个非常幼稚的重写,删除了一些冗余:
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);
}
}
还要确保矩阵数据结构是理智的(例如,大步访问的平面数组;不是一堆动态分配的行)。
另外,我认为第一个+ 1
有点愚蠢。你知道x -> x * log(x)
在零处是连续的,极限为零,所以你应该写:
double const pij = mat(i, j) / gfi;
if (pij != 0) { g += pij + log(pij); }
事实上,您甚至可以像这样编写第一个内部for
循环,避免在不需要时进行除法:
for (int j = 1; j <= N; ++j)
{
if (double pij = mat(i, j))
{
pij /= gfi;
g += pij * log(pij);
}
}
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- 空基优化子对象的地址
- 什么是使用 opencv::Mat 优化 c++ 矩阵计算
- 优化递归问题以计算超级数字
- C/C++编译器是否会通过重用最近计算的函数结果来优化代码?
- 优化三角矩阵计算的 CUDA 内核执行
- 从第二个导数计算的曲线的SIMD优化
- 只有当循环中更新的变量是局部变量时,计算才会优化
- 优化标志会导致计算错误
- 优化稀疏矩阵中的对数熵计算
- 用于并行计算的C++代码优化示例
- 行列式计算函数的优化
- 我如何优化高斯pdf的计算
- 重复相同计算的优化
- 优化了数组元素的计算和设置
- 如何优化计算除数
- 为什么优化标志 (-O3) 不能加快四倍精度计算的速度?
- 在高度优化的代码中计算代码运行时
- 计算乘数和除数值的优化算法