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

**URL:** <https://discourse.julialang.org/t/trouble-creating-a-real-valued-vector-out-of-elements-of-multiple-complex-arrays/33790>\
**Category:** New to Julia\
**Tags:** optimization\
**Created:** [January 25, 2020, 11:16pm UTC](https://discourse.julialang.org/t/trouble-creating-a-real-valued-vector-out-of-elements-of-multiple-complex-arrays/33790 "2020-01-25T23:16:23Z")\
**Posts on this page:** 3\
**Page:** 2

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [January 27, 2020, 12:17am UTC](https://discourse.julialang.org/t/trouble-creating-a-real-valued-vector-out-of-elements-of-multiple-complex-arrays/33790/22 "2020-01-27T00:17:20Z")

</div>

Now for some utility functions

```julia
"""Expand vector to include padded matrices"""
function ExpandVector(x::Vector; nm=2, nr=2, nc=2, nre=3, nce=3)
    vec(PaddedView(0,reshape(x,(2,nr,nc,nm)),(2,nre,nce,nm)))
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:

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

```julia
"""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.

---

<div class="post-metadata">

**Author:** ![CPPhysics](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cpphysics/32/4372_2.png) [@CPPhysics](https://discourse.julialang.org/u/CPPhysics)\
**Post date:** [January 28, 2020, 5:15pm UTC](https://discourse.julialang.org/t/trouble-creating-a-real-valued-vector-out-of-elements-of-multiple-complex-arrays/33790/24 "2020-01-28T17:15:01Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 28, 2020, 6:55pm UTC](https://discourse.julialang.org/t/trouble-creating-a-real-valued-vector-out-of-elements-of-multiple-complex-arrays/33790/25 "2020-01-28T18:55:56Z")

</div>

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

Instead of

> [@mkitti](#):
>
> ```julia
> 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
> 
> ```

do

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

```

And instead of

> [@mkitti](#):
>
> ```julia
> 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
> 
> ```

do

```julia
function mat2vec(z::AbstractArray{Complex{T}, 2}...) where {T}
	x = vec.(reinterpret.(T, z))
	return vcat(x...)
end

```

The `reinterpret` versions are 15-20 times faster (even more if you use `view`), and, imho, nicer.

[Previous page](https://discourse.julialang.org/t/trouble-creating-a-real-valued-vector-out-of-elements-of-multiple-complex-arrays/33790.md?page=1)
