我特别想知道如何在不使用for循环的情况下创建它。另外,对于一般的N维Levi-Civita matrix怎么办呢?
答案 0 :(得分:3)
这是一个非循环解决方案,专门用于使用Levi-Civita matrix的3乘3乘3 linear indexing:
lcMat = zeros(3,3,3);
lcMat([8 12 22]) = 1;
lcMat([6 16 20]) = -1;
修改强>
这是N-dimensional Levi-Civita matrix的更通用,更简洁的非循环解决方案:
[mats{1:N}] = ndgrid(1:N);
pairsIndex = nchoosek(1:N,2);
lcMat = sign(prod(cat(N+1,mats{pairsIndex(:,2)})-...
cat(N+1,mats{pairsIndex(:,1)}),N+1));
当然,需要权衡利弊。虽然它不使用循环,但是可能会创建大的临时变量。 N
越大,此内存成本就越高。
答案 1 :(得分:1)
我在文件交换中找到了至少两个函数 - #1和#2。你检查过了吗?两者都在使用循环。
对于3D矩阵,您可以直接输入并避免循环。
在问题中包含对主题的某种解释会很好。这是Wiki页面的链接:http://en.wikipedia.org/wiki/Levi-Civita_symbol
答案 2 :(得分:0)
好吧,我很无聊所以我采取了扭曲的路线。它没有回答这个问题,因为这不是“容易”,但我分享了这个,因为我玩得很开心。
从wikipedia定义,您可以构建一个函数,从索引中为您提供Cevi-Levita符号的值:
LC_value = @(v) round(prod(prod(triu(repmat(v,[numel(v) 1])-repmat(v',[1 numel(v)]),1) ...
./repmat(factorial([1:numel(v)]'),[1 numel(v)])+tril(ones(numel(v))))));
这实现了一般的n维嵌套产品定义。小心,因子功能可能会导致高维问题。 round
函数存在,因为您正在执行浮点运算以生成整数。
下一步是将此函数应用于所有可能的索引组合。然而,将它仅应用于[1 2 3]
的排列更快。
sites = perms([1 2 3]);
values = arrayfun(@(i)LC_value(sites(i,:)),(1:size(sites,1))');
lcMat = zeros(3,3,3);
lcMat(sub2ind(size(lcMat),sites(:,1),sites(:,2),sites(:,3))) = values;
就是这样。它适用于三维,它应该适用于更高的尺寸,虽然我还没有测试过。