我正在尝试在Halide中实现Cholesky分解。诸如crout之类的常见算法的一部分包括在三角矩阵上的迭代。以这种方式,通过从输入矩阵的对角线元素中减去部分列和来计算分解的对角元素。列总和是在输入矩阵的三角形部分的平方元素上计算的,不包括对角元素。
使用BLAS,C ++中的代码如下所示:
double* a; /* input matrix */
int n; /* dimension */
const int c__1 = 1;
const double c_b12 = 1.;
const double c_b10 = -1.;
for (int j = 0; j < n; ++j) {
double ajj = a[j + j * n] - ddot(&j, &a[j + n], &n, &a[j + n], &n);
ajj = sqrt(ajj);
a[j + j * n] = ajj;
if (j < n) {
int i__2 = n - j;
dgemv("No transpose", &i__2, &j, &c_b10, &a[j + 1 + n], &n, &a[j + n], &b, &c_b12, &a[j + 1 + j * n], &c__1);
double d__1 = 1. / ajj;
dscal(&i__2, &d__1, &a[j + 1 + j * n], &c__1);
}
}
我的问题是,这样的模式是否一般由Halide表达?如果是这样,它会是什么样子?
答案 0 :(得分:1)
我认为Andrew可能有更完整的答案,但为了及时响应,您可以使用RDom谓词(通过RDom :: where引入)来枚举三角形区域(或将它们推广到更多维度)。该模式的草图是:
Halide::RDom triangular(0, extent, 0, extent);
triangular.where(triangular.x < triangular.y);
然后使用triangular
进行缩减。
答案 1 :(得分:0)
我曾经用Halide写过快速的Cholesky。不幸的是我无法找到代码。我将外部循环放在C中并编写了一个很好的块面板更新例程,它一次只能操作32个面板。这是在Halide进行三角迭代之前,所以也许你现在可以做得更好。