2010-12-07 6 views

答えて

0

[OK]を私は退屈していたので、私はねじれたルートを取った。これは "簡単"ではないので、質問に答えませんが、私は楽しんでいたので、これを共有しています。

wikipedia定義から、あなたはあなたのインデックスからCEVI-レビータシンボルの値を与える機能を構築することができます。

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; 

これだけです。それは三次元のために働いています、そして、私はそれをテストしていませんが、より高次元のために動作するはずです。

+0

あなたのメソッドは4-dでも使えます。しかし、5-dで失敗した。何か特別な理由? –

1

ファイル交換 - #1#2の少なくとも2つの機能が見つかりました。あなたはそれらをチェックしましたか?どちらもループを使用しています。

3Dマトリックスの場合は、直接入力してループを避けることができます。

トピックに何らかの種類の説明を含めるとよいでしょう。ここでWikiページへのリンクです:http://en.wikipedia.org/wiki/Levi-Civita_symbol

3

ここで非ループソリューションは、3×3×3 Levi-Civita matrixlinear indexingを使用のために特別です:

lcMat = zeros(3,3,3); 
lcMat([8 12 22]) = 1; 
lcMat([6 16 20]) = -1; 

はEDIT:

そして、ここでは、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

+0

@Adrien:潜在的な一般的な解決策を理解するのに少し時間がかかったので、まず質問の簡単な部分に答えました。 ;) – gnovice

+0

素敵な、gnovice!ところで、lcMatを印刷するときに、非ゼロの2次元行列のみを表示する簡単な方法はありますか? –

関連する問題