# Trouble creating a real-valued vector out of elements of multiple complex arrays

Now for some utility functions

``````"""Expand vector to include padded matrices"""
function ExpandVector(x::Vector; nm=2, nr=2, nc=2, nre=3, nce=3)
end

"""Expand vector to include padded matrices and append parameters"""
function ExpandVectorWithParams(x::Vector; params...)
[ExpandVector(x;params...); collect(values(params))]
end

"""Extract matrices from vector"""
function VectorToMatrices(x::Vector; nm=2, nr=2, nc=2)
x = reshape(x,(2,nr,nc,nm))
x = x[1,:,:,:] + x[2,:,:,:,]*im
ntuple(i->x[:,:,i],size(x,3))
end

"""Extract expanded matrices from vectors"""
function VectorToExpandedMatrices(x::Vector; nm=2, nre=3, nce=3, args...)
VectorToMatrices(x; nm=nm, nr=nre, nc=nce)
end

"""Convert matrices back to vector form"""
function MatricesToVector(args...)
X = cat(dims=3,args...)
X = cat(dims=4,real.(X),imag.(X))
X = permutedims(X,(4,1,2,3))
vec(X)
end
``````

One version if we are allowed to define the functions with known parameters is as follows:

``````params = (nm=2, nr=2, nc=2, nre=3, nce=3)
Initializer(x::Vector) = ExpandVector(x; params...)
Create(x::Vector) = VectorToExpandedMatrices(x; params...)
Create(x) = Create( collect(x) )

julia> X0 = Initializer( collect(1:16) )
36-element reshape(PaddedView(0, ::Array{Int64,4}, (Base.OneTo(2), Base.OneTo(3), Base.OneTo(3), Base.OneTo(2))), 36) with eltype Int64:
1
2
3
4
0
0
5
6
7
8
⋮
16
0
0
0
0
0
0
0
0

julia> Ae,Be = Create(X0)
(Complex{Int64}[1 + 2im 5 + 6im 0 + 0im; 3 + 4im 7 + 8im 0 + 0im; 0 + 0im 0 + 0im 0 + 0im], Complex{Int64}[9 + 10im 13 + 14im 0 + 0im; 11 + 12im 15 + 16im 0 + 0im; 0 + 0im 0 + 0im 0 + 0im])

julia> 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> 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

``````

Alternatively, let’s say we don’t know the parameters when defining `Create`:

``````"""Create with unknown params"""
param_keys = (:nm, :nr, :nc, :nre, :nce)
CreateUnknownParams(x::Vector) = VectorToExpandedMatrices(x[1:end-5]; ( ; zip(param_keys, x[end-4:end]) ... ) ... )

"""Initialize with known params encoded in vector"""
params = (nm=2, nr=2, nc=2, nre=3, nce=3)
InitializeWithParams(x::Vector) = ExpandVectorWithParams(x; params...)

julia> X0 = InitializeWithParams( collect(1:16) )
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> Ae,Be = CreateUnknownParams(X0)
(Complex{Int64}[1 + 2im 5 + 6im 0 + 0im; 3 + 4im 7 + 8im 0 + 0im; 0 + 0im 0 + 0im 0 + 0im], Complex{Int64}[9 + 10im 13 + 14im 0 + 0im; 11 + 12im 15 + 16im 0 + 0im; 0 + 0im 0 + 0im 0 + 0im])

julia> 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> 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

``````

I hope that helps.

3 Likes

Thank you so much, this is exactly what I was looking for, you have helped tremendously. I feel I am finally getting the hang of programming this sort of linear algebra manipulation through this explanation.

I would really suggest leveraging the `reinterpret` function here:

do

``````function vec2mat(x::Vector{T}; nm=2, nr=2, nc=2) where {T<:Real}
z = reshape(reinterpret(Complex{T}, x), nr, nc, nm)
return ntuple(i->z[:,:,i], nm)
end
``````

``````function mat2vec(z::AbstractArray{Complex{T}, 2}...) where {T}
The `reinterpret` versions are 15-20 times faster (even more if you use `view`), and, imho, nicer.