В Джулии несколько точек заставляют одинаковое количество элементов массива? - PullRequest
0 голосов
/ 11 сентября 2018

Итак, я смотрю на такой код code :

vx = angle.(
    conj.(psi1).*view(psi1, ixp,:,:) .+
    conj.(psi2).*view(psi2, ixp,:,:)
);

Его оригинальная версия Matlab:

vx = angle(conj(psi1).*psi1(ixp,:,:) ...
                  +conj(psi2).*psi2(ixp,:,:));

psi - это трехмерные массивы комплексных чисел, ixp являются массивами int

И помощником article Мне интересно две вещи:

  1. является результатом "view" того же размера, что и psi?Если да, то здесь будет смысл view здесь?
  2. Если нет, то как это выражение будет развернуто в [i,j,k] и for терминах цикла?

Что я пробовал: Я пытаюсь перевести его на CSharp и получил что-то вроде этого:

//fassuming psi are a square
double[,,] vx = new double[psi1.Length,psi1[0].Length,psi1[0][0].Length];

for (int index1 = 0; index1 < psi1.Length; ++index1) {
    for (int index2 = 0; index2 < psi1[index1].Length; ++index2) {
        for (int index3 = 0; index3 < psi1[index1][index2].Length; ++index3) {
            var c1 = Complex.Conjugate(psi1[index1][index2][index3]);
            var c2 = Complex.Conjugate(psi2[index1][index2][index3]);
            var mul1 = psi1[index1][index2][ixp[index3]];
            var mul2 = psi1[index1][index2][ixp[index3]];
            var summ = (c1 * mul1 + c2 * mul2);
            var result = summ.Phase;
            vx[index1, index2, index3] = result;
        }
    }
}

Теперь мне интересно, насколько далек от правильного результата в моем понимании языка Юлии.

1 Ответ

0 голосов
/ 12 сентября 2018

.* и .+ не требуют, чтобы его операнды имели одинаковую форму. При необходимости и совпадении размеров они могут транслироваться. Если, например, ixp является массивом с одной записью , эта строка все равно должна вычисляться без ошибки. Смотрите следующий пример:

julia> a = rand(1:5, 4, 4, 2)
4×4×2 Array{Int64,3}:
[:, :, 1] =
 1  4  3  5
 2  1  1  1
 3  4  1  2
 3  5  1  3

[:, :, 2] =
 4  4  1  5
 3  4  4  4
 5  3  2  3
 5  3  4  4

julia> a[[1], :, :]
1×4×2 Array{Int64,3}:
[:, :, 1] =
 1  4  3  5

[:, :, 2] =
 4  4  1  5

julia> a .* a[[1], :, :]
4×4×2 Array{Int64,3}:
[:, :, 1] =
 1  16  9  25
 2   4  3   5
 3  16  3  10
 3  20  3  15

[:, :, 2] =
 16  16  1  25
 12  16  4  20
 20  12  2  15
 20  12  4  20

julia> a .* a[[1,1,1,1], :, :] # should give the same results as the prev. command
4×4×2 Array{Int64,3}:
[:, :, 1] =
 1  16  9  25
 2   4  3   5
 3  16  3  10
 3  20  3  15

[:, :, 2] =
 16  16  1  25
 12  16  4  20
 20  12  2  15
 20  12  4  20

Размер результирующего view зависит от аргумента индексации ixp. Если ixp имеет тот же размер, что и размер первого измерения psi, то результирующее представление будет той же формы, что и psi, но, возможно, с другим порядком в первом измерении, поскольку ixp может быть [2,3,4,1] или [2,3,1,1]. Если это так, то поведение такое же, как в вашем коде C # . Другой случай, когда эта строка все еще должна вычисляться без ошибки, - это случай, когда ixp является массивом с одной записью, и поведение такое же, как в приведенном выше фрагменте. Если ixp является одной записью, результаты будут такими же, как если бы эта же запись повторялась столько же раз, сколько и размер первого измерения psi (как в последней команде фрагмента выше). Итак, поскольку вы реализовали В первом случае поведение в другом случае (одиночная запись ixp) также может быть легко реализовано.

В других размерах ixp должна быть ошибка из-за DimensionMismatch.

Кажется, ваш код C # правильно реализует поведение в первом случае.

Если вы пытаетесь перевести этот проект Julia на другой язык, то было бы полезно, если бы у вас было больше информации о лежащей в основе проблеме, может быть ixp всегда должен иметь размер, равный psi в первом измерении , Рассматривая примеры и другой код в этом репозитории Github, я думаю, что это так. ixp используется только для изменения порядка первого измерения psi. Даже если это не так, нет большой проблемы, поскольку есть только два жизнеспособных случая, как упомянуто выше.

...