就地乔列斯基逆
In-place Cholesky inverse
我想知道是否有可能在不需要临时数组的情况下通过 Cholesky 分解获得矩阵的逆。到目前为止,我可以在不使用临时数组的情况下获得 cholesky 因式分解,但从那里我还没有找到一种方法来获得原始矩阵的逆矩阵,而无需重复到与原始矩阵相同维度的临时矩阵。即求解系统
A x_i = e_i, where e_i is the i-th column if the identity matrix.
我实际上遵循了一种稍微好一点的方法,如 http://arxiv.org/abs/1111.4144
中所述一些背景:
我正在编写一个 (C/C++) CUDA 程序,其中每个线程计算相对较小的(20x20,在某些情况下为 40x40)协方差矩阵的逆函数和行列式,以及其他任务。在 CUDA 中使用数组不是很快,这就是为什么我想尽量减少它们的使用。当我编码就地 cholesky 分解并限制仅使用矩阵的较低条目时,我已经看到了一些重大改进,这就是为什么如果我设法摆脱方程求解部分中的临时数组,我希望会有一些改进,即如果算法使用临时变量作为至少更小的数组,那就可以了。
我知道,计算x = A^{-1} b,
这正是我最终所做的,通过解决系统A x = b
比反向计算更有效。但是由于我也需要行列式,在Cholesky分解中获得,我认为计算逆数会更好。
我不确定我要说的话是否会对你有所帮助。但是在 CUDA 中访问数组的成本可能为 16 倍,而成本仅为 1 倍。 这取决于内存排列和每个线程将执行的访问模式。
对我来说,假设我有 100 个线程,每个线程需要一个大小为 20x20 的整数/浮点数的矩阵。如果我是,你会毫不犹豫地只使用一个在所有线程之间共享的数组,每个线程将像这样访问第一个元素:
int iFirstElement = gArray[tid]; // where tid is the thread idx assuming this 1D,2D, or 3D I am sure you can calculate the tid easily.
//to access the second element you can use this:
int iSecondElement = gArray[numOfThreads * 1 + tid];
// to access the third element you can use this
int iSecondElement = gArray[numOfThreads * 2 + tid];
这样,您将增强内存访问模式,并且仅消耗 1X 而不是 16X 来访问内存。你可能认为全局内存是个坏主意,但相信我,事实并非如此。 你可以回到我发表的论文,在GPU上进行人脸检测,阅读更多关于内存访问模式的信息。
http://ijces.org/media/1Iss8-IJCES0402603_v4_iss2_47-55.pdf
最后,广泛使用局部变量将导致调度程序在多个周期中运行块,因为每个块的寄存器文件不足以同时运行整个块。
- 具有N列和N行的矩阵,列必须具有N-1、N-2等值
- 如何从棋盘上的箱号中找到行和列
- 在Linux和C++中的Windows上,散列字符串值会产生不同的输出
- 打印第二列时的2d字符矢量打印空间
- 使用QTreeView,如何通过调用函数只突出显示特定的行/列
- 查找矩阵C++中每一列和每一行的最小和最大元素
- C++ 乔列斯基因式分解
- 如何删除给定矩阵中的特定行和列以进行C++?
- 对对应于矩阵的行和列的对向量进行排序
- 如何在C++中获取二维数组中最少的一列数?
- 如何在 c++ 中仅循环访问特定列?
- 是否可以在 QAbstractItemModel 中返回正数行数和零列数?
- 使用 GDAL 获取矢量数组中的所有行数和列数
- 如何修复CMFCPropertyListCtrl的列宽?
- 莱克斯没有返回我想要的东西
- 提升用于解析标题列的精神语法
- 如何读取没有数组或结构的 3 列文件
- 按列随机播放 2D 矢量
- 部分透视/高斯消除 - 交换列而不是产生错误输出的行
- 就地乔列斯基逆