Матричная блочная индексация - PullRequest
2 голосов
/ 07 апреля 2019

Я использую Julia версии 1.1.Я много работаю с матрицами, которые могут быть построены из меньших матриц, например, матрицы Паули.Мне не ясно, как эффективно построить большие матрицы с помощью набора меньших матриц в Юлии, то есть напрямую записать меньшую матрицу в определенную позицию индекса.

Юлия kron не является удовлетворительным, так как япотребуется получить несколько «больших матриц», чтобы получить мой конечный результат.Например, я хотел бы создать что-то вроде этого (это только очень маленький пример)

sy = [[0 -im]; [im 0]]
M = [[0 sy adjoint(sy)]; 
     [adjoint(sy) 0 sy];
     [sy adjoint(sy) 0]]

Это можно было бы сделать, выполнив два продукта kronecker, добавив два результата.Однако это было бы огромной тратой, особенно если матрицы стали больше.

Я также уже пытался работать с пакетом BlockArrays.jl, но понял, что он не полностью удовлетворяет мои потребности.

ВВ конце я хочу иметь возможность обратиться к «матричным блокам» моей большой матрицы, чтобы я мог напрямую назначить строительные матрицы правильной позиции, для приведенного выше примера это будет выглядеть следующим образом (я не использовал цикл здесь дляпроясните мою точку зрения):

M[1, 2] = sy
M[1, 3] = adjoint(sy)
M[2, 1] = adjoint(sy)
M[2, 3] = sy
M[3, 1] = sy
M[3, 2] = adjoint(sy)

Я понимаю, что это означает, что мои исходные индексы большого массива сводятся к чему-то вроде массива "блочные индексы".

Я думал об этом с помощью представлений, гдеЯ создаю матрицу SubArrays, которую затем могу адресовать с помощью индексной нотации матричного блока, например

S0 = view(M, 1:2, 1:2)
S1 = view(M, 1:2, 2:4)
S2 = view(M, 1:2, 4:6)
...

Viewmatrix = [[S0 S1 S2]; [S3 S4 S5]; [S6 S7 S8]]
Viewmatrix[1, 2] .= sy
Viewmatrix[1, 3] .= adjoint(sy)
...

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

1 Ответ

2 голосов
/ 08 апреля 2019

BlockArrays.jl не только поддерживает блокированные массивы 2 × 2, хотя раньше они использовали только их в своей документации.Вы можете легко создать желаемый массив размером 3 × 3 с блокировкой 6 × 6 следующим образом:

M = BlockArray(fill(0im, 6, 6), [2, 2, 2], [2, 2, 2])
M[Block(1, 2)] = sy
M[Block(1, 3)] = adjoint(sy)
M[Block(2, 1)] = adjoint(sy)
M[Block(2, 3)] = sy
M[Block(3, 1)] = sy
M[Block(3, 2)] = adjoint(sy)

julia> M
3×3-blocked 6×6 BlockArray{Complex{Int64},2}:
 0+0im  0+0im  │  0+0im  0-1im  │  0+0im  0-1im
 0+0im  0+0im  │  0+1im  0+0im  │  0+1im  0+0im
 ──────────────┼────────────────┼──────────────
 0+0im  0-1im  │  0+0im  0+0im  │  0+0im  0-1im
 0+1im  0+0im  │  0+0im  0+0im  │  0+1im  0+0im
 ──────────────┼────────────────┼──────────────
 0+0im  0-1im  │  0+0im  0-1im  │  0+0im  0+0im
 0+1im  0+0im  │  0+1im  0+0im  │  0+0im  0+0im

Но будьте осторожны: блоки хранятся по ссылке.Поэтому, если вы потом измените sy, все блоки, содержащие его, также будут изменены, и наоборот.Если вы хотите избежать этого, используйте широковещательное присваивание (.= вместо =).

Если ваша проблема на самом деле так же проста, как в примере, а на более плотной стороне, может быть прощеиспользуйте функцию mortar, чтобы «склеить» доступные блоки:

julia> mortar(reshape([z, sy, sy', sy', z, sy, sy, sy', z], (3, 3)))
3×3-blocked 6×6 BlockArray{Complex{Int64},2,Array{AbstractArray{Complex{Int64},2},2},BlockArrays.BlockSizes{2,Array{Int64,1}}}:
 0+0im  0+0im  │  0+0im  0-1im  │  0+0im  0-1im
 0+0im  0+0im  │  0+1im  0+0im  │  0+1im  0+0im
 ──────────────┼────────────────┼──────────────
 0+0im  0-1im  │  0+0im  0+0im  │  0+0im  0-1im
 0+1im  0+0im  │  0+0im  0+0im  │  0+1im  0+0im
 ──────────────┼────────────────┼──────────────
 0+0im  0-1im  │  0+0im  0-1im  │  0+0im  0+0im
 0+1im  0+0im  │  0+1im  0+0im  │  0+0im  0+0im

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

...