高阶张量元素求和

问题描述 投票:0回答:1

我有一个维度为 $I imes I imes \dots imes I$ ($D$ 次)的 $D$ 路张量 $H$,它表示多项式的系数。为了更好地理解,请参考这篇文章:https://math.stackexchange.com/questions/4718760/higher-order-tensor-computations

我试图对 H 中某个位置的元素以及该位置索引的所有可能的唯一排列求和,并将它们重新排列在向量 $F$ 中。向量 $F$ 首先包含二阶单项式的系数,然后是三阶单项式的系数,依此类推。如何将此代码扩展为任何高阶多项式,而不必编写许多嵌套的 for 循环?

我正在寻找可能的方法,使以下代码适用于任何给定的 $Order$。目前,该代码适用于 $Order = 5$。对于更高的顺序,我必须添加更多嵌套的 for 循环。但这不是最佳解决方案。

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
arrays matlab matrix linear-algebra tensor
1个回答
0
投票

可以预先计算嵌套循环的索引。如果嵌套循环的形式为

for j = i+1:I
nchoosek
可以用来生成索引。因此提供函数
generate_index
来计算这些索引:

for ord = 2:Order
    idx = generate_index (start:I, ord);
    for c = 1: size(idx, 1)
        indices = num2cell(unique(perms([idx(c, :), ones(1,Order-ord)]),'rows'));
        [F,pos] = calcF(indices,F,pos,H);
    end
end


function out = generate_index (N, k)
    v = (1:numel(N)).';
    bl = true;
    for i = 1:k-1
        vtmp = reshape(v, [repmat(1,1,i) numel(v)]);
        bl = bl & (v <= vtmp);
        v = vtmp;
    end
    c = cell (1, k);
    [c{:}] = ind2sub(repmat(numel(N), 1, k), find(bl));
    idx = [c{:}];
    out = N(idx);
end

请注意,如果

(v <= vtmp)
更改为
(v < vtmp)
,输出将与
nchoosek
相同。

© www.soinside.com 2019 - 2024. All rights reserved.