# Store complex and real numbers with same underlying

**URL:** https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489
**Category:** General Usage
**Tags:** type, parametric-types
**Created:** [February 17, 2021, 9:53pm UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489 "2021-02-17T21:53:45Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![Uroc327](https://avatars.discourse-cdn.com/v4/letter/u/eb8c5e/32.png) [@Uroc327](https://discourse.julialang.org/u/Uroc327)
#### Post date: [February 17, 2021, 9:53pm UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489/1 "2021-02-17T21:53:45Z")

</div>

Hi,  
I am trying to store multiple values in a struct. I’d like those values to have the same precision (expected use cases are floating point and fixed point types with several precisions). Some of those values may be complex, but don’t have to be.

I am basically trying something like

```julia
struct MyData{T<:Number}
	a::T
	b::real(T)
end

```

or

```julia
struct MyData{T} where {T<:Number}
	a::T
	b::real(T)
end

```

With the first version, I see the error `MethodError: no method matching real(::TypeVar)`, whereas the second version shows me a syntax error in the (here) first line.

The thing is, I do not want to make `a` a `Complex{T}` as in [this question](https://stackoverflow.com/questions/51758584/how-to-store-real-and-complex-types-of-same-precision-in-a-parameterized-type-de) and be done with it. Further downstream, I have to do differing things for real `T` and complex `T`.

Due to this, also something like

```julia
struct MyData{T<:Number}
    a::Complex{T}
    b::T
end

f(d::MyData{<:Real}) = √(2π)
f(d::MyData{<:Complex}) = π

```

is not an option, because I can’t construct a `Complex` from another `Complex`, only from `Real`s.

How can I store real values and probably real, probably complex values with the same underlying type, so that their type (precision as well as real/complex nature) is preserved for later dispatch?

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 17, 2021, 10:10pm UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489/2 "2021-02-17T22:10:01Z")

</div>

Does this meet your need?

```julia
struct MyData{S, T<:Union{S, Complex{S}}}
  a::S # Real
  b::T # Real or Complex
end

data1 = MyData(1.0, 2.0)
data2 = MyData(1.0, 2.0+1.0im)
data3 = MyData(1, 2)
data4 = MyData(1, 2-2im)

dispatch(x::MyData{Float64, Float64}) =
  x == data1
dispatch(x::MyData{Float64, Complex{Float64}}) =
  x == data2

dispatch(x::MyData{Int64, T}) where {T<:Union{Int64, Complex{Int64}}} =
  x == data3 || x == data4
# or the last can be done this way
const MaybeComplexInt64 =
  Union{Int64, Complex{Int64}}
dispatch(x::MyData{Int64, T}) where {T<:MaybeComplexInt64} =
  x == data3 || x == data4

julia> dispatch(data1)
true
julia> dispatch(data2)
true
julia> dispatch(data3)
true
julia> dispatch(data4)
true

```

---

<div class="post-metadata">

### Author: ![Uroc327](https://avatars.discourse-cdn.com/v4/letter/u/eb8c5e/32.png) [@Uroc327](https://discourse.julialang.org/u/Uroc327)
#### Post date: [February 17, 2021, 10:28pm UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489/3 "2021-02-17T22:28:21Z")

</div>

That seems to work, thanks!

I guess I can make your `MaybeComplexInt64` parametric as well?

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [February 17, 2021, 10:45pm UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489/4 "2021-02-17T22:45:46Z")

</div>

[re-edited that answer to show both approaches]

---

<div class="post-metadata">

### Author: ![Uroc327](https://avatars.discourse-cdn.com/v4/letter/u/eb8c5e/32.png) [@Uroc327](https://discourse.julialang.org/u/Uroc327)
#### Post date: [February 17, 2021, 10:46pm UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489/5 "2021-02-17T22:46:01Z")

</div>

For further reference: Yep, this does work.

```julia
const PossiblyComplex{T<:Real} = Union{T, Complex{T}}

f(::MyData{T, <:PossiblyComplex{T}}, ::Number) where {T<:Real} = "complex"
f(::MyData{T, T}, ::Real) where {T<:Real} = "real"

```

did a good job for me.

Although I wonder, if there is any more concise solution, not requiring me to repeat the type `T` when defining methods…

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [February 18, 2021, 12:16am UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489/6 "2021-02-18T00:16:47Z")

</div>

I see a couple of options:

First, you could use a `Union` field for `a`, which makes the behavior of the struct nicely obvious:

```julia
julia> struct MyData{T <: Real}
         a::Union{T, Complex{T}}
         b::T
       end

julia> MyData(1.0, 2.0)
MyData{Float64}(1.0, 2.0)

julia> MyData(1.0 + 2im, 2.0)
MyData{Float64}(1.0 + 2.0im, 2.0)

```

This doesn’t let you dispatch on `MyData{<:Complex}`, so it would require doing something like:

```julia
if isreal(my_data.a)
  ...

```

which might not be ideal, but could be fine.

Another option would be to use [GitHub - vtjnash/ComputedFieldTypes.jl: Build types in Julia where some fields have computed types](https://github.com/vtjnash/ComputedFieldTypes.jl) which kind of makes your original example just work:

```julia
julia> using ComputedFieldTypes

julia> @computed struct MyData{T<:Number}
               a::T
               b::real(T)
       end
fulltype (generic function with 2 methods)

julia> MyData{Float64}(1.0, 2.0)
MyData{Float64,Float64}(1.0, 2.0)

julia> MyData{ComplexF64}(1.0, 2.0)
MyData{Complex{Float64},Float64}(1.0 + 0.0im, 2.0)

```

ComputeFieldTypes.jl still creates a second type parameter for `b`, but it lets you avoid typing it out in most cases.

---

<div class="post-metadata">

### Author: ![Uroc327](https://avatars.discourse-cdn.com/v4/letter/u/eb8c5e/32.png) [@Uroc327](https://discourse.julialang.org/u/Uroc327)
#### Post date: [February 18, 2021, 12:27am UTC](https://discourse.julialang.org/t/store-complex-and-real-numbers-with-same-underlying/55489/7 "2021-02-18T00:27:57Z")

</div>

Thanks for the hints! I’d prefer dispatching, as I believe this to be faster and I know, that this happens in hot sections.

Do you happen to have any examples how dispatching looks with the `ComputedFieldTypes.jl` library? I didn’t find anything on their repo after a first glance.
