Iâm just going to go through a few manipulations in script form first and perhaps this will give you some ideas. Letâs initialize a vector numbered 1 to 16 for clarity.
julia> xi = collect(1:16)
16-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Iâm going to assume it is known apriori that there are two complex matrices and that they are square. Additionally the expanded matrix you need is one greater in each dimension.
In case those assumptions are incorrect, you can recode the following. Please do explain what your assumptions are when asking a question or that there are no assumptions.
julia>
n_matrices = 2
# divide by two below because we need two entries for complex numbers
n_rows = Int64(sqrt(length(xi)/n_matrices/2))
n_cols = n_rows
n_rows_expanded = n_rows+1
n_cols_expanded = n_cols+1
p = params = (nm=n_matrices,nr=n_rows,nc=n_cols,nre=n_rows_expanded,nce=n_cols_expanded)
(nm = 2, nr = 2, nc = 2, nre = 3, nce = 3)
Using the params above, we are now going to interpret xi
:
julia> xir = reshape(xi,(2,p.nr,p.nc,p.nm))
2Ă2Ă2Ă2 Array{Int64,4}:
[:, :, 1, 1] =
1 3
2 4
[:, :, 2, 1] =
5 7
6 8
[:, :, 1, 2] =
9 11
10 12
[:, :, 2, 2] =
13 15
14 16
julia> A = xir[1,:,:,1] + im*xir[2,:,:,1]
2Ă2 Array{Complex{Int64},2}:
1+2im 5+6im
3+4im 7+8im
julia> B = xir[1,:,:,2] + im*xir[2,:,:,2]
2Ă2 Array{Complex{Int64},2}:
9+10im 13+14im
11+12im 15+16im
Now letâs add zeros around the matrices. The term for this is called padding. There are several options for this such padarray
or PaddedView
. Letâs use the latter:
julia > using PaddedViews
julia> Ae = PaddedView(0,A,(p.nre,p.nce))
3Ă3 PaddedView(0 + 0im, ::Array{Complex{Int64},2}, (Base.OneTo(3), Base.OneTo(3))) with eltype Complex{Int64}:
1+2im 5+6im 0+0im
3+4im 7+8im 0+0im
0+0im 0+0im 0+0im
julia> Be = PaddedView(0,B,(p.nre,p.nce))
3Ă3 PaddedView(0 + 0im, ::Array{Complex{Int64},2}, (Base.OneTo(3), Base.OneTo(3))) with eltype Complex{Int64}:
9+10im 13+14im 0+0im
11+12im 15+16im 0+0im
0+0im 0+0im 0+0im
If we ever needed plain old complex arrays, we can use collect
.
julia> collect(Ae)
3Ă3 Array{Complex{Int64},2}:
1+2im 5+6im 0+0im
3+4im 7+8im 0+0im
0+0im 0+0im 0+0im
julia> collect(Be)
3Ă3 Array{Complex{Int64},2}:
9+10im 13+14im 0+0im
11+12im 15+16im 0+0im
0+0im 0+0im 0+0im
Now letâs go the other way and attempt to compact Ae
and Be
down back to a vector.
julia> X0 = cat(Ae,Be,dims=3)
3Ă3Ă2 Array{Complex{Int64},3}:
[:, :, 1] =
1+2im 5+6im 0+0im
3+4im 7+8im 0+0im
0+0im 0+0im 0+0im
[:, :, 2] =
9+10im 13+14im 0+0im
11+12im 15+16im 0+0im
0+0im 0+0im 0+0im
julia> X0 = cat(real.(X0),imag.(X0),dims=4)
3Ă3Ă2Ă2 Array{Int64,4}:
[:, :, 1, 1] =
1 5 0
3 7 0
0 0 0
[:, :, 2, 1] =
9 13 0
11 15 0
0 0 0
[:, :, 1, 2] =
2 6 0
4 8 0
0 0 0
[:, :, 2, 2] =
10 14 0
12 16 0
0 0 0
julia> X0 = permutedims(X0,(4,1,2,3))
2Ă2Ă3Ă3 Array{Int64,4}:
[:, :, 1, 1] =
1 2
9 10
[:, :, 2, 1] =
3 4
11 12
[:, :, 3, 1] =
0 0
0 0
[:, :, 1, 2] =
5 6
13 14
[:, :, 2, 2] =
7 8
15 16
[:, :, 3, 2] =
0 0
0 0
[:, :, 1, 3] =
0 0
0 0
[:, :, 2, 3] =
0 0
0 0
[:, :, 3, 3] =
0 0
0 0
julia> X0 = vec(X0)
36-element Array{Int64,1}:
1
2
3
4
0
0
5
6
7
8
âŽ
16
0
0
0
0
0
0
0
0
Great now we compacted Ae
and Be
back into a vector. Now depending on how things are structured and how the optimization routines work, we may need to also encode the parameters in the vector:
julia> X0_with_params = [X0; collect(params)]
41-element Array{Int64,1}:
1
2
3
4
0
0
5
6
7
8
âŽ
0
0
0
0
2
2
2
3
3
julia> param_keys = keys(p)
Recreating Ae and Be is just a matter of unpacking the parameters and repeating the earlier steps.
julia> p = (;zip(param_keys,X0_with_params[end-4:end])...)
(nm = 2, nr = 2, nc = 2, nre = 3, nce = 3)
julia> X0 = reshape(X0_with_params[1:end-5],(2,p.nre,p.nce,p.nm));
julia> Ae_recreated = X0[1,:,:,1] + im*X0[2,:,:,1]
3Ă3 Array{Complex{Int64},2}:
1+2im 5+6im 0+0im
3+4im 7+8im 0+0im
0+0im 0+0im 0+0im
julia> Be_recreated = X0[1,:,:,2] + im*X0[2,:,:,2]
3Ă3 Array{Complex{Int64},2}:
9+10im 13+14im 0+0im
11+12im 15+16im 0+0im
0+0im 0+0im 0+0im
julia> Ae == Ae_recreated
true
julia> Be == Be_recreated
true