如何在 MATLAB 中轻松形成 Levi-Civita 3x3x3 矩阵?

发布于 2024-10-06 11:57:35 字数 147 浏览 2 评论 0原文

我特别想知道如何在不使用 for 循环的情况下创建它。另外,对于一般的 N 维 Levi-Civita 矩阵,如何做到这一点?

I'd specifically like to know how to create it without using for loops. Also, how could it be done for a general N-dimensional Levi-Civita matrix?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情稳全场 2024-10-13 11:57:35

这是专门针对 3×3×3 Levi-Civita 矩阵<的非循环解决方案/a> 使用线性索引

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

<强>编辑:

这是一个更通用和简洁的非循环解决方案 N 维 Levi-Civita 矩阵

[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 越大,内存成本就越高。

Here's a non-loop solution specifically for a 3-by-3-by-3 Levi-Civita matrix that uses linear indexing:

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

EDIT:

And here is a more general and succinct non-loop solution for an 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));

There is a trade-off, of course. Although it doesn't use loops, there are potentially large temporary variables created. The larger N is, the more prohibitive this memory cost will be.

半世蒼涼 2024-10-13 11:57:35

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

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

最好在问题中包含对该主题的某种解释。以下是 Wiki 页面的链接: http://en.wikipedia.org/wiki/Levi-Civita_symbol

I found at least two functions on File Exchange - #1 and #2. Have you checked them? Both are using loops.

For just 3D matrix, you can input it directly and avoid loop.

It would be nice to include some kind of explanation of the topic into the question. Here is a link to Wiki page: http://en.wikipedia.org/wiki/Levi-Civita_symbol

相权↑美人 2024-10-13 11:57:35

好吧,我实在是太无聊了,所以就走了一条弯路。它没有回答这个问题,因为这并不“容易”,但我分享这个是因为我玩得很开心。

根据 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;

就是这样。它适用于三个维度,并且应该适用于更高的维度,尽管我还没有测试过。

Ok, I was bored so I took a twisted route. It does not answer the question since this is not "easy" but i'm sharing this since i had fun.

From the wikipedia definition, you can build a function give you the value of the Cevi-Levita symbol from the indices:

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))))));

This implements the general n-dimensional nested product definition. Be careful, the factorial function might lead to problems in high dimensions. The round function is there because you're doing floating point operations to generate integers.

The next step is to apply this function to all the possible indices combinations. Nevertheless, it is faster to apply it only to the permutations of [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;

That's it. It's working for three dimensions, and it should work for higher dimensions, although i haven't tested it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文