Как я могу легко сформировать матрицу Levi-Civita 3x3x3 в MATLAB? - PullRequest
4 голосов
/ 08 декабря 2010

Мне бы особенно хотелось узнать, как его создать, не используя циклы for.Кроме того, как это можно сделать для общей N-мерной матрицы Леви-Чивиты ?

Ответы [ 3 ]

3 голосов
/ 08 декабря 2010

Вот решение без петель, специально для матрицы 3 на 3 на 3 Леви-Чивита , в которой используется линейное индексирование :

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

РЕДАКТИРОВАТЬ:

А вот более общее и сжатое решение без петель для N-мерной матрицы Леви-Чивита :

[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 голос
/ 08 декабря 2010

Я нашел по крайней мере две функции в File Exchange - # 1 и # 2 Вы их проверили? Оба используют петли.

Только для трехмерной матрицы вы можете ввести ее напрямую и избежать петель.

Было бы неплохо включить какое-то объяснение темы в вопрос. Вот ссылка на вики-страницу: http://en.wikipedia.org/wiki/Levi-Civita_symbol

0 голосов
/ 08 декабря 2010

Ладно, мне было скучно, поэтому я выбрал извилистый маршрут.Он не отвечает на вопрос, поскольку это не «просто», но я делюсь этим, так как мне было весело.

Из определения 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;

Вот и все.Он работает для трех измерений, и он должен работать для более высоких измерений, хотя я не проверял это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...