2010-12-07 98 views

回答

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; 

就是这样。它在三个维度上工作,它应该适用于更高维度,尽管我没有测试过它。

1

我在文件交换中发现至少两个函数 - #1#2。你检查过他们吗?两者都使用循环。

对于3D矩阵,您可以直接输入并避免循环。

这将是很好,包括对该问题的主题的某种解释。这里是一个链接到Wiki页面:http://en.wikipedia.org/wiki/Levi-Civita_symbol

3

这里有一个非循环解决方案,专为3×3×3 Levi-Civita matrix使用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是,这种内存成本将越高禁止。

+0

我不认为这是他所希望的答案,但它符合要求。 – Adrien 2010-12-07 23:33:44

+0

@Adrien:找出一个潜在的通用解决方案需要我多一点时间,所以我首先回答了问题中较​​简单的部分。 ;) – gnovice 2010-12-08 04:10:28