You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高阶张量元素求和:适配任意阶多项式的代码优化问询

问题描述

现有一个$D$维张量$H$,维度为$I \times I \times \dots \times I$(共$D$个$I$),用于表示多项式系数。需要将张量$H$中某位置元素及其所有唯一排列位置的元素求和,结果整理到向量$F$中——$F$先存储二阶单项式的系数,再依次存储三阶及更高阶的系数。

当前代码仅支持最高5阶多项式,更高阶需要添加大量嵌套循环,扩展性差。现寻求无需编写大量嵌套循环、可扩展到任意阶多项式的实现方法。

原代码实现
pos = 1; start = 2; Memory = 3; Order = 3; I = Memory+2; H = randn(I*ones(1,Order));
F = zeros(1,1000);

if Memory > 0
    if Order > 1
        for i = start:I
            for j = i:I
                indices = num2cell(unique(perms([j,i,ones(1,Order-2)]),'rows'));
                [F,pos] = calcF(indices,F,pos,H);
            end
        end
    end
    if Order > 2
        for k = start:I
            for i = k:I
                for j = i:I
                    indices = num2cell(unique(perms([j,i,k,ones(1,Order-3)]),'rows'));
                    [F,pos] = calcF(indices,F,pos,H);
                end
            end
        end
    end
    if Order > 3
        for m = start:I
            for k = m:I
                for i = k:I
                    for j = i:I
                        indices = num2cell(unique(perms([j,i,k,m,ones(1,Order-4)]),'rows'));
                        [F,pos] = calcF(indices,F,pos,H);
                    end
                end
            end
        end
    end
    if Order > 4
        for n = start:I
            for m = n:I
                for k = m:I
                    for i = k:I
                        for j = i:I
                            indices = num2cell(unique(perms([j,i,k,m,n,ones(1,Order-5)]),'rows'));
                            [F,pos] = calcF(indices,F,pos,H);
                        end
                    end
                end
            end
        end
    end
end

function [F,pos] = calcF(indices,F,pos,H)
    for l = 1:size(indices,1)
        F(pos) = F(pos) + H(indices{l,:});
    end
    pos = pos + 1;
end
通用实现方案

核心思路是生成非降序的索引组合(避免重复处理相同排列的等价类),然后对每个组合生成所有唯一排列,再累加对应张量元素的值。无需手动嵌套循环,通过动态生成组合实现任意阶扩展。

实现代码

pos = 1; start = 2; Memory = 3; Order = 3; I = Memory+2; H = randn(I*ones(1,Order));
F = zeros(1, 1000); % 可根据实际需求调整大小,或改为动态扩容

if Memory > 0
    % 遍历从2阶到Order阶的所有单项式阶数
    for degree = 2:Order
        % 生成非降序的索引组合:元素范围start到I,共degree个元素
        combos = generate_non_decreasing_combos(start, I, degree);
        
        for c = 1:size(combos, 1)
            current_indices = combos(c, :);
            % 生成该组合的所有唯一排列
            unique_perms = unique(perms(current_indices), 'rows');
            % 将排列转换为张量线性索引并求和
            linear_idx = sub2ind(size(H), unique_perms(:,1), unique_perms(:,2), unique_perms(:,3:end)...);
            F(pos) = sum(H(linear_idx));
            pos = pos + 1;
        end
    end
end

% 递归生成非降序组合的辅助函数
function combos = generate_non_decreasing_combos(start, end_val, degree)
    if degree == 1
        combos = (start:end_val)';
        return;
    end
    prev_combos = generate_non_decreasing_combos(start, end_val, degree-1);
    combos = [];
    for i = start:end_val
        % 筛选出前degree-1个元素最大值<=i的组合,保证非降序
        valid = prev_combos(:, end) <= i;
        temp = [prev_combos(valid, :), repmat(i, sum(valid), 1)];
        combos = [combos; temp];
    end
end

方案说明

  1. 非降序组合生成:通过递归函数generate_non_decreasing_combos生成所有满足a1 <= a2 <= ... <= ad的索引组合,每个组合对应一个单项式的等价类(所有排列属于同一单项式),避免重复计算。
  2. 唯一排列处理:对每个非降序组合,用unique(perms(...))获取所有唯一排列,确保不重复累加张量元素。
  3. 高效求和:使用sub2ind将多维索引转换为张量的线性索引,直接调用sum完成累加,替代原calcF函数,代码更简洁高效。
  4. 任意阶扩展:只需修改Order参数即可支持任意阶多项式,无需手动添加嵌套循环。

内容的提问来源于stack exchange,提问作者Neuling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:40:37