映射"下对角线"矩阵的张量,作为将矩阵的下三角部分提取到向量中的推广

时间:2018-06-07 04:28:20

标签: c++ tensor

给定等级-4张量(每个等级具有维度K),例如T(p,q,r,s),我们可以1对1将所有张量元素映射到维度{{1}的矩阵中},例如K^2 x K^2,其中两个第一张量索引M(i,j)和最后两个索引p,q以列主要方式组合:

r,s

利用给定张量的一些(反)对称性,例如i = p + K * q j = r + K * s T(p,q,r,s) = -T(q,p,r,s) = -T(p,q,s,r) = T(q,p,s,r),我们希望能够构造一个仅包含唯一元素的矩阵T(p,q,r,s) = T(r,s,p,q) (即那些与先前定义的对称性无关的那些),使H(m,n)p>q进入矩阵r>s,然后是H(m,n)维。

我们怎样才能找到一种算法(甚至更好:我们如何使用C ++库Eigen)来完成这些索引转换?此外,我们可以用K(K-1)/2 x K(K-1)/2m代数地写下np,q,就像我们想要提取严格下三角形的情况一样矩阵(无对角线)到矢量?

1 个答案:

答案 0 :(得分:0)

作为参考,给定方阵Eigen::MatrixXd M (K,K),这里有一个算法,使用C ++ Eigen库将给定方阵M的严格下三角提取到大小为的向量m中:< / p>

    Eigen::VectorXd strictLowerTriangle(const Eigen::MatrixXd& M) {

    auto K = static_cast<size_t>(M.cols());  // the dimension of the matrix
    Eigen::VectorXd m = Eigen::VectorXd::Zero((K*(K-1)/2));  // strictly lower triangle has K(K-1)/2 parameters

    size_t vector_index = 0;
    for (size_t q = 0; q < K; q++) {  // "column major" ordering for, so we do p first, then q
        for (size_t p = q+1; p < K; p++) {
            m(vector_index) = M(p,q);
            vector_index++;
        }
    }

    return m;
}

我们能够将此算法扩展到所请求的一般情况:

Eigen::MatrixXd strictLowerTriangle(const Eigen::Tensor<double, 4>& T) {

    auto K = static_cast<size_t> (dims[0]);

    Eigen::MatrixXd M (K*(K-1)/2, K*(K-1)/2);

    size_t row_index = 0;
    for (size_t j = 0; j < K; j++) {  // "column major" ordering for row_index<-i,j so we do j first, then i
        for (size_t i = j+1; i < K; i++) {  // in column major indices, columns are contiguous, so the first of two indices changes more rapidly
                                                  // require i > j

            size_t column_index = 0;
            for (size_t l = 0; l < K; l++) {  // "column major" ordering for column_index<-k,l so we do l first, then k
                for (size_t k = l+1; k < K; k++) {  // in column major indices, columns are contiguous, so the first of two indices changes more rapidly
                                                          // require l > k

                    M(row_index,column_index) = T(i,j,k,l);

                    column_index++;
                }
            }

            row_index++;
        }
    }

    return M;
}