You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

行主序下多维度张量间索引转换公式咨询

行主序下多维度张量间索引转换公式咨询

嗨,这个问题的核心其实是行主序(row-major)存储规则下的多维索引与线性索引的双向转换,不管两个张量的维度数谁多谁少,都可以通过「先转线性索引,再转目标多维索引」的两步法搞定,咱们一步步说清楚:

核心思路

因为两个张量的元素总数完全相同,所以它们的元素在内存里的行主序排列是一一对应的——先把原张量的多维索引转换成全局的线性索引(也就是元素在内存中的位置偏移,从0开始计数),再把这个线性索引转换成目标张量的多维索引即可。


第一步:从原张量A的多维索引计算线性索引

假设A是m维张量,维度为 m₁ × m₂ × ... × mₖ,给定的多维索引是 (i₁, i₂, ..., iₖ)(索引从0开始),行主序下的线性索引idx计算公式为:

idx = i₁ × (m₂×m₃×...×mₖ) + i₂ × (m₃×...×mₖ) + ... + iₖ₋₁ × mₖ + iₖ

简单来说,就是每个维度的索引,乘以它右侧所有维度的乘积(这个乘积也叫该维度的「步长」),最后把所有项相加。

拿你的例子验证:
A的维度是2×2×2,索引是(1,0,0)

  • 第一个维度的步长:2×2=4
  • 第二个维度的步长:2
  • 第三个维度的步长:1
    计算得:idx = 1×4 + 0×2 + 0×1 = 4

第二步:把线性索引转换成目标张量B的多维索引

假设B是n维张量,维度为 n₁ × n₂ × ... × nₜ,现在要把线性索引idx转换成多维索引(j₁, j₂, ..., jₜ),需要从最右侧的维度开始,依次取余和整除

  1. 计算最右侧维度的索引:jₜ = idx % nₜ,然后更新idx = idx // nₜ(整除,向下取整)
  2. 往左推一个维度:jₜ₋₁ = idx % nₜ₋₁,更新idx = idx // nₜ₋₁
  3. 重复这个过程,直到所有维度的索引都计算完成,最后剩下的idx就是最左侧的j₁

再拿你的例子验证:
B的维度是2×4,线性索引是4

  • 先算右侧的j₂:4 % 4 = 0,更新idx = 4 // 4 = 1
  • 再算左侧的j₁:1 % 2 = 1,更新idx = 1 // 2 = 0
    最终得到B的索引是(1, 0),和预期一致。

关于维度数m和n的差异

不管是m > n(原张量维度更多)还是m < n(目标张量维度更多),这个两步法都是通用的:

  • 如果m > n:比如A是3维,B是2维,第一步转线性索引,第二步分解成2维即可
  • 如果m < n:比如A是1维(线性索引就是本身),B是3维,直接用第二步把线性索引分解成3维索引就行

小补充:索引从1开始的情况

如果你的张量索引是从1开始计数的,只需要在计算前把每个索引减1(转成0基索引),完成转换后再把结果加1即可,核心逻辑不变。

备注:内容来源于stack exchange,提问作者user366312

火山引擎 最新活动