给定等级-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)/2
和m
代数地写下n
和p,q
,就像我们想要提取严格下三角形的情况一样矩阵(无对角线)到矢量?
答案 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;
}