eigen - 使用 Eigen 进行指数平均
问题描述
考虑以下代码。
const int N = 100;
const float alpha = 0.9;
Eigen::MatrixXf myVec = Eigen::MatrixXf::Random(N,1);
Eigen::MatrixXf symmetricMatrix(N, N);
for(int i=0; i<N; i++)
for(int j=0; j<=i; j++)
symmetricMatrix(i,j) = symmetricMatrix(j,i) = i+j;
symmetricMatrix *= alpha;
symmetricMatrix += ((1-alpha)*myVec*myVec.adjoint());
它本质上实现了指数平均。我知道最后一行可以通过以下方式进行优化。
symmetricMatrix_copy.selfadjointView<Eigen::Upper>().rankUpdate(myVec, 1-alpha);
我想知道我是否可以有效地结合最后两行。简而言之,我想计算 A = alpha*A+(1-alpha)*(x*x')
.
解决方案
最重要的是,你应该声明myVec
as Eigen::VectorXf
,如果它保证是一个向量。并确保您使用-O3 -march=native -DNDEBUG
.
您可以尝试这些替代方案(我正在使用A
并v
节省打字),哪个最快可能取决于您的问题大小和您的 CPU:
A.noalias() = alpha * A + (1.0f-alpha)*v*v.adjoint();
A.noalias() = alpha * A + (1.0f-alpha)*v.lazyProduct(v.adjoint());
A.noalias() = alpha * A + ((1.0f-alpha)*v).lazyProduct(v.adjoint());
A.noalias() = alpha * A + v.lazyProduct((1.0f-alpha)*v.adjoint());
A.triangularView<Eigen::Upper>() = alpha * A + (1.0f-alpha)*v*v.adjoint();
// or any `lazyProduct` as above.
很遗憾,.noalias()
目前.triangularView()
无法合并。
你也可以考虑计算这个:
A.selfadjointView<Eigen::Upper>().rankUpdate(v, (1.0f-alpha)/alpha);
并且每次N
迭代都会按比例缩放您的A
矩阵pow(alpha, N)
推荐阅读
- java - 无法从中获取标识符
- firebase - Firebase 存储管理员 - 未指定存储桶 -
- ruby-on-rails - 使用 Rspec 3 测试 ActiveAdmin - 一些控制器操作未命中
- java - 在 Android Studio 2.3.2 中使用 Java 8 不起作用
- gulp - 服务器端包括使用 browserSync-SSI 和 gulp?
- android - TypeError:无法读取 ionic 4 for android 中未定义的属性“openDatabase”
- python-3.x - 如何在 Google Colab 中从源文件(Google Drive)创建 zipfiles
- c# - OleDbCommand ExecuteNonQuery() 性能问题
- angular - 如何取消订阅观察者?
- postgresql-9.1 - 将远程 postgresql 9.1 数据库迁移到本地 postgresql 11