学校网站建设代码,低价网站建设渠道,ppt素材模板,搜索引擎网站推广定义文章目录✅ 步骤 1#xff1a;应用对称置换✅ 步骤 2#xff1a;构造逆排列✅ 步骤 3#xff1a;应用置换并排序 COO#x1f501; 如何“逆置换”#xff1f;✅ 补充说明要对一个 COO 格式#xff08;Coordinate Format#xff09;的稀疏方阵A∈RnnA \in \mathbb{R}^{n …文章目录✅ 步骤 1应用对称置换✅ 步骤 2构造逆排列✅ 步骤 3应用置换并排序 COO 如何“逆置换”✅ 补充说明要对一个COO 格式Coordinate Format的稀疏方阵A ∈ R n × n A \in \mathbb{R}^{n \times n}A∈Rn×n应用对称置换symmetric permutation即计算A ′ P A P T A P A P^TA′PAPT其中 ( P ) 是由给定的一维排列数组perm长度为 ( n )所定义的置换矩阵其作用为P [ i , perm [ i ] ] 1 P[i, \text{perm}[i]] 1P[i,perm[i]]1等价地对向量x xx有( P x ) i x perm [ i ] (Px)_i x_{\text{perm}[i]}(Px)ixperm[i]那么对矩阵的对称置换等价于行重排行i ii变为原来的行perm [ i ] \text{perm}[i]perm[i]列重排列j jj变为原来的列perm [ j ] \text{perm}[j]perm[j]对 COO 格式的三元组(row, col, val)操作非常直接✅ 步骤 1应用对称置换对每一个非零元素(r, c, v)新行号 inv_perm[r]新列号 inv_perm[c]为什么是inv_perm因为perm[i] j表示“新位置 i 来自旧位置 j”即新矩阵的第 i 行 原矩阵的第perm[i]行 原矩阵的第 r 行 → 出现在新矩阵的inv_perm[r]行所以要将原(r, c)映射到新位置(inv_perm[r], inv_perm[c])结论对称置换P A P T P A P^TPAPT对应于将每个 COO 元素的行/列索引通过逆排列映射。✅ 步骤 2构造逆排列给定perm0-based其逆排列inv_perm满足inv_perm[perm[i]]i;代码std::vectorintinv_perm(n);for(inti0;in;i){inv_perm[perm[i]]i;}✅ 步骤 3应用置换并排序 COOCOO 格式通常要求按(row, col)字典序排序便于后续转换为 CSR 或其他格式。C 实现如下假设使用 0-based 索引#includevector#includealgorithm#includetuplestructCOOMatrix{intn;// dimensionstd::vectorintrow,col;// row/col indicesstd::vectordoubleval;// values (or use template)};COOMatrixapply_symmetric_permutation(constCOOMatrixA,conststd::vectorintperm){intnnzA.row.size();intnA.n;// Step 1: build inverse permutationstd::vectorintinv_perm(n);for(inti0;in;i){inv_perm[perm[i]]i;}// Step 2: apply permutation to each entrystd::vectorintnew_row(nnz),new_col(nnz);std::vectordoublenew_valA.val;// copy valuesfor(intk0;knnz;k){new_row[k]inv_perm[A.row[k]];new_col[k]inv_perm[A.col[k]];}// Step 3: sort by (row, col)std::vectorstd::tupleint,int,doubleentries(nnz);for(intk0;knnz;k){entries[k]std::make_tuple(new_row[k],new_col[k],new_val[k]);}std::sort(entries.begin(),entries.end());// Step 4: unpack backCOOMatrix A_perm;A_perm.nn;A_perm.row.resize(nnz);A_perm.col.resize(nnz);A_perm.val.resize(nnz);for(intk0;knnz;k){std::tie(A_perm.row[k],A_perm.col[k],A_perm.val[k])entries[k];}returnA_perm;} 如何“逆置换”如果你已经对A AA应用了对称置换得到A ′ P A P T A P A P^TA′PAPT那么恢复原矩阵只需应用逆排列的对称置换原排列为perm则逆操作的排列是inv_perm即A P^T A P apply_symmetric_permutation(A_prime, inv_perm)或者更简单对A再次用perm作为排列调用上述函数❌ 不行正确做法要撤销P A P T P A P^TPAPT应使用P T A ′ P ( P − 1 ) A ′ ( P − 1 ) T P^T A P (P^{-1}) A (P^{-1})^TPTA′P(P−1)A′(P−1)T而P − 1 P^{-1}P−1对应的排列就是inv_perm。所以COOMatrix A_restoredapply_symmetric_permutation(A_perm,inv_perm_of_perm);但注意inv_perm_of_perm就是原始的perm因为inv_perm的逆是perm。因此正向A1 apply(..., perm)逆向A0 apply(..., inv_perm)其中inv_perm由perm构造✅ 补充说明该方法适用于任意稀疏结构包括非对称矩阵但对称置换常用于对称矩阵如刚度矩阵以改善数值性质。COO 输出已按(row, col)排序可直接用于Eigen::SparseMatrix::setFromTriplets或其他库。若你使用的是size_t或int64_t索引请相应调整类型。