Skip to content

Instantly share code, notes, and snippets.

@marius311
Created June 13, 2017 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marius311/c0a364923101306586796fac4248e7c7 to your computer and use it in GitHub Desktop.
Save marius311/c0a364923101306586796fac4248e7c7 to your computer and use it in GitHub Desktop.
module Issue22125
import Base: convert
# Define some "Field" types which are basically a wrapper around a 2-D matrix,
# whose size is known at compile-time (i.e. "Nside"), which can converted
# between "map" and "fourier" bases via FFT
abstract type Pix end
abstract type Flat{Nside} <: Pix end
abstract type Basis end
abstract type Map <: Basis end
abstract type Fourier <: Basis end
abstract type Field{P<:Pix, B<:Basis} end
struct FlatMap{T<:Real,P<:Flat} <: Field{P,Map}
Tx::Matrix{T}
end
FlatMap(Tx::Matrix{T}) where {T} = FlatMap{T,Flat{size(Tx,2)}}(Tx)
struct FlatFourier{T<:Real,P<:Flat} <: Field{P,Fourier}
Tl::Matrix{Complex{T}}
end
# Add some "shorthand" so you can use the Basis types for conversion
(::Type{B})(f::Field{P,B}) where {P,B} = f
convert(::Type{F}, f::Field{P,B1}) where {P,B1,B2,F<:Field{P,B2}} = B2(f)
Fourier(f::FlatMap{T,P}) where {T,P} = FlatFourier{T,P}(gfft(T,P)*f.Tx)
Map(f::FlatFourier{T,P}) where {T,P} = FlatMap{T,P}(gfft(T,P)\f.Tl)
# This seemingly unrelated call needs to be here to trigger the error
using PyCall
# Since we know the matrix size at compile-time, use a generated function to
# plan the FFT only once per matrix-size. Its important that this is @generated for the error.
@generated function gfft(::Type{T},::Type{P}) where {Nside, T<:Real, P<:Flat{Nside}}
plan_rfft(rand(T,fill(Nside,2)...))
end
# Its apparently also important that this is here and is *after* the @generated
using ImageCore
# Now here's essentially the code to trigger the error:
struct Foo{F<:Field}
a::F
b::F
end
# note how argument 2 is getting implicitly converted, which is important:
Foo(a::F) where {F} = Foo{F}(Map(a),Fourier(a))
Foo(FlatMap(rand(4,4))) # <--- error
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment