Created
June 13, 2017 13:30
-
-
Save marius311/c0a364923101306586796fac4248e7c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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