mollusk 0e4acfb8f2 fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
2018-06-11 03:28:36 -07:00

353 lines
12 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# This file is a part of Julia. License is MIT: https://julialang.org/license
# issue #19892
# (test this first to make sure it happens before set_num_threads)
let a = randn(10^5,1), p1 = plan_rfft(a, flags=FFTW.ESTIMATE)
FFTW.set_num_threads(2)
p2 = plan_rfft(a, flags=FFTW.ESTIMATE)
@test p1*a p2*a
# make sure threads are actually being used for p2
# (tests #21163).
if FFTW.version >= v"3.3.4"
@test !contains(string(p1), "dft-thr")
@test contains(string(p2), "dft-thr")
end
end
# fft
a = rand(8) + im*rand(8)
@test norm(ifft(fft(a)) - a) < 1e-8
@test norm(ifft(fft(a,1),1) - a) < 1e-8
@test norm(ifft(fft(a,[1]),[1]) - a) < 1e-8
@test norm(ifft(fft(a,(1,)),(1,)) - a) < 1e-8
a = rand(-10:10, 8) + im*rand(-10:10, 8)
@test norm(ifft(fft(a)) - a) < 1e-8
m4 = [16. 2 3 13;
5 11 10 8;
9 7 6 12;
4 14 15 1]
true_fft_m4 = [
34. 34. 34. 34.;
7. - 1.0im -5. + 3.0im -3. + 5.0im 1. - 7.0im;
16. -16. -16. 16.;
7. + 1.0im -5. - 3.0im -3. - 5.0im 1. + 7.0im ]
true_fftn_m4 = [
136. 0 0 0 ;
0. 20 8 + 8im 0 - 12im ;
0. 32 + 32im 0 32 - 32im ;
0. 0 + 12im 8 - 8im 20 ]
true_fftd2_m4 = [
34. 13 + 11im 4 13 - 11im ;
34. -5 - 3im -4 -5 + 3im ;
34. 3 + 5im -4 3 - 5im ;
34. -11 - 13im 4 -11 + 13im ]
b = rand(17,14)
b[3:6,9:12] = m4
sm4 = view(b,3:6,9:12)
m3d = map(Float32,copy(reshape(1:5*3*2, 5, 3, 2)))
true_fftd3_m3d = Array{Float32}(5, 3, 2)
true_fftd3_m3d[:,:,1] = 17:2:45
true_fftd3_m3d[:,:,2] = -15
# use invoke to force usage of CTPlan versions even if FFTW is present
for A in (Array,SubArray)
for f in (:fft,:ifft,:plan_fft,:plan_ifft)
f_ = Symbol(f, "_")
@eval begin
$f_{T,N}(x::$A{T,N}) = invoke($f, Tuple{AbstractArray{T,N}}, x)
$f_{T,N,R}(x::$A{T,N},r::R) = invoke($f,Tuple{AbstractArray{T,N},R},x,r)
end
end
end
for (f,fi,pf,pfi) in ((fft,ifft,plan_fft,plan_ifft),
(fft_,ifft_,plan_fft_,plan_ifft_))
pm4 = pf(m4,1)
fft_m4 = f(m4,1)
fftd2_m4 = f(m4,2)
ifft_fft_m4 = fi(f(m4,1),1)
fftn_m4 = f(m4)
ifftn_fftn_m4 = fi(f(m4))
fft!_m4 = complex(m4); fft!(fft!_m4,1)
fft!d2_m4 = complex(m4); fft!(fft!d2_m4,2)
ifft!_fft_m4 = f(m4,1); ifft!(ifft!_fft_m4,1)
fft!n_m4 = complex(m4); fft!(fft!n_m4)
ifft!n_fftn_m4 = f(m4); ifft!(ifft!n_fftn_m4)
pfft_m4 = pf(m4,1)*m4
pfftd2_m4 = pf(m4,2)*m4
pifft_fft_m4 = pfi(fft_m4,1)*fft_m4
pfftn_m4 = pf(m4)*m4
pifftn_fftn_m4 = pfi(fftn_m4)*fftn_m4
pfft!_m4 = complex(m4); plan_fft!(pfft!_m4,1)*pfft!_m4
pfft!d2_m4 = complex(m4); plan_fft!(pfft!d2_m4,2)*pfft!d2_m4
pifft!_fft_m4 = f(m4,1); plan_ifft!(pifft!_fft_m4,1)*pifft!_fft_m4
pfft!n_m4 = complex(m4); plan_fft!(pfft!n_m4)*pfft!n_m4
pifft!n_fftn_m4 = f(m4); plan_ifft!(pifft!n_fftn_m4)*pifft!n_fftn_m4
sfftn_m4 = f(sm4)
psfftn_m4 = pf(sm4)*sm4
sfft!n_b = map(Complex128,b)
sfft!n_m4 = view(sfft!n_b,3:6,9:12); fft!(sfft!n_m4)
psfft!n_b = map(Complex128,b)
psfft!n_m4 = view(psfft!n_b,3:6,9:12); plan_fft!(psfft!n_m4)*psfft!n_m4
for i = 1:length(m4)
@test fft_m4[i] true_fft_m4[i]
@test fftd2_m4[i] true_fftd2_m4[i]
@test ifft_fft_m4[i] m4[i]
@test fftn_m4[i] true_fftn_m4[i]
@test ifftn_fftn_m4[i] m4[i]
@test fft!_m4[i] true_fft_m4[i]
@test fft!d2_m4[i] true_fftd2_m4[i]
@test ifft!_fft_m4[i] m4[i]
@test fft!n_m4[i] true_fftn_m4[i]
@test ifft!n_fftn_m4[i] m4[i]
@test pfft_m4[i] true_fft_m4[i]
@test pfftd2_m4[i] true_fftd2_m4[i]
@test pifft_fft_m4[i] m4[i]
@test pfftn_m4[i] true_fftn_m4[i]
@test pifftn_fftn_m4[i] m4[i]
@test pfft!_m4[i] true_fft_m4[i]
@test pfft!d2_m4[i] true_fftd2_m4[i]
@test pifft!_fft_m4[i] m4[i]
@test pfft!n_m4[i] true_fftn_m4[i]
@test pifft!n_fftn_m4[i] m4[i]
@test sfftn_m4[i] true_fftn_m4[i]
@test sfft!n_m4[i] true_fftn_m4[i]
@test psfftn_m4[i] true_fftn_m4[i]
@test psfft!n_m4[i] true_fftn_m4[i]
end
ifft!(sfft!n_m4)
plan_ifft!(psfft!n_m4)*psfft!n_m4
@test norm(sfft!n_m4 - m4) < 1e-8
@test norm(psfft!n_m4 - m4) < 1e-8
# The following capabilities are FFTW only.
# They are not available in MKL, and hence do not test them.
if Base.fftw_vendor() != :mkl
ifft3_fft3_m3d = fi(f(m3d))
fftd3_m3d = f(m3d,3)
ifftd3_fftd3_m3d = fi(fftd3_m3d,3)
fft!d3_m3d = complex(m3d); fft!(fft!d3_m3d,3)
ifft!d3_fftd3_m3d = copy(fft!d3_m3d); ifft!(ifft!d3_fftd3_m3d,3)
pfftd3_m3d = pf(m3d,3)*m3d
pifftd3_fftd3_m3d = pfi(fftd3_m3d,3)*fftd3_m3d
pfft!d3_m3d = complex(m3d); plan_fft!(pfft!d3_m3d,3)*pfft!d3_m3d
pifft!d3_fftd3_m3d = copy(fft!d3_m3d); plan_ifft!(pifft!d3_fftd3_m3d,3)*pifft!d3_fftd3_m3d
@test isa(fftd3_m3d, Array{Complex64,3})
@test isa(ifftd3_fftd3_m3d, Array{Complex64,3})
@test isa(fft!d3_m3d, Array{Complex64,3})
@test isa(ifft!d3_fftd3_m3d, Array{Complex64,3})
@test isa(pfftd3_m3d, Array{Complex64,3})
@test isa(pifftd3_fftd3_m3d, Array{Complex64,3})
@test isa(pfft!d3_m3d, Array{Complex64,3})
@test isa(pifft!d3_fftd3_m3d, Array{Complex64,3})
for i = 1:length(m3d)
@test fftd3_m3d[i] true_fftd3_m3d[i]
@test ifftd3_fftd3_m3d[i] m3d[i]
@test ifft3_fft3_m3d[i] m3d[i]
@test fft!d3_m3d[i] true_fftd3_m3d[i]
@test ifft!d3_fftd3_m3d[i] m3d[i]
@test pfftd3_m3d[i] true_fftd3_m3d[i]
@test pifftd3_fftd3_m3d[i] m3d[i]
@test pfft!d3_m3d[i] true_fftd3_m3d[i]
@test pifft!d3_fftd3_m3d[i] m3d[i]
end
end # if fftw_vendor() != :mkl
# rfft/rfftn
rfft_m4 = rfft(m4,1)
rfftd2_m4 = rfft(m4,2)
rfftn_m4 = rfft(m4)
prfft_m4 = plan_rfft(m4,1)*m4
prfftd2_m4 = plan_rfft(m4,2)*m4
prfftn_m4 = plan_rfft(m4)*m4
srfftn_m4 = rfft(sm4)
psrfftn_m4 = plan_rfft(sm4)*sm4
for i = 1:3, j = 1:4
@test rfft_m4[i,j] true_fft_m4[i,j]
@test rfftd2_m4[j,i] true_fftd2_m4[j,i]
@test rfftn_m4[i,j] true_fftn_m4[i,j]
@test prfft_m4[i,j] true_fft_m4[i,j]
@test prfftd2_m4[j,i] true_fftd2_m4[j,i]
@test prfftn_m4[i,j] true_fftn_m4[i,j]
@test srfftn_m4[i,j] true_fftn_m4[i,j]
@test psrfftn_m4[i,j] true_fftn_m4[i,j]
end
irfft_rfft_m4 = irfft(rfft_m4,size(m4,1),1)
irfft_rfftd2_m4 = irfft(rfftd2_m4,size(m4,2),2)
irfftn_rfftn_m4 = irfft(rfftn_m4,size(m4,1))
pirfft_rfft_m4 = plan_irfft(rfft_m4,size(m4,1),1)*rfft_m4
pirfft_rfftd2_m4 = plan_irfft(rfftd2_m4,size(m4,2),2)*rfftd2_m4
pirfftn_rfftn_m4 = plan_irfft(rfftn_m4,size(m4,1))*rfftn_m4
for i = 1:length(m4)
@test irfft_rfft_m4[i] m4[i]
@test irfft_rfftd2_m4[i] m4[i]
@test irfftn_rfftn_m4[i] m4[i]
@test pirfft_rfft_m4[i] m4[i]
@test pirfft_rfftd2_m4[i] m4[i]
@test pirfftn_rfftn_m4[i] m4[i]
end
if Base.fftw_vendor() != :mkl
rfftn_m3d = rfft(m3d)
rfftd3_m3d = rfft(m3d,3)
@test size(rfftd3_m3d) == size(fftd3_m3d)
irfft_rfftd3_m3d = irfft(rfftd3_m3d,size(m3d,3),3)
irfftn_rfftn_m3d = irfft(rfftn_m3d,size(m3d,1))
for i = 1:length(m3d)
@test rfftd3_m3d[i] true_fftd3_m3d[i]
@test irfft_rfftd3_m3d[i] m3d[i]
@test irfftn_rfftn_m3d[i] m3d[i]
end
fftn_m3d = fft(m3d)
@test size(fftn_m3d) == (5,3,2)
rfftn_m3d = rfft(m3d)
@test size(rfftn_m3d) == (3,3,2)
for i = 1:3, j = 1:3, k = 1:2
@test rfftn_m3d[i,j,k] fftn_m3d[i,j,k]
end
end # !mkl
end
# FFT self-test algorithm (for unscaled 1d forward FFTs):
# Funda Ergün, "Testing multivariate linear functions: Overcoming
# the generator bottleneck," Proc. 27th ACM Symposium on the Theory
# of Computing, pp. 407-416 (1995).
# Check linearity, impulse-response, and time-shift properties.
function fft_test{T<:Complex}(p::Base.DFT.Plan{T}, ntrials=4,
tol=1e5 * eps(real(T)))
ndims(p) == 1 || throw(ArgumentError("not a 1d FFT"))
n = length(p)
twopi_i = (-2 * convert(real(T), π)/n * (0:n-1)) * im
for trial = 1:ntrials
# linearity:
x = rand(T, n)
y = rand(T, n)
α = rand(T)
β = rand(T)
X = p * (α*x + β*y)
err = norm(α * (p*x) + β * (p*y) - X, Inf) / norm(X, Inf)
err <= tol || error("linearity error $err in $p")
# impulse-response:
z = zeros(T, n)
i = rand(0:n-1)
z[i+1] = 1
X = exp.(twopi_i*i)
err = norm(p*z - X, Inf) / norm(X, Inf)
err <= tol || error("impulse-response error $err in $p")
# time-shift:
if n > 1
s = rand(1:n-1)
X = (p*x).*exp.(twopi_i*s)
err = norm(p*circshift(x,s) - X, Inf) / norm(X, Inf)
err <= tol || error("time-shift error $err in $p")
end
end
end
for T in (Complex64, Complex128)
for n in [1:100; 121; 143; 1000; 1024; 1031; 2000; 2048]
x = zeros(T, n)
fft_test(plan_fft(x))
fft_test(plan_fft_(x))
end
end
# test inversion, scaling, and pre-allocated variants
for T in (Complex64, Complex128)
for x in (T[1:100;], copy(reshape(T[1:200;], 20,10)))
y = similar(x)
for planner in (plan_fft, plan_fft_, plan_ifft, plan_ifft_)
p = planner(x)
pi = inv(p)
p3 = 3*p
p3i = inv(p3)
@test eltype(p) == eltype(pi) == eltype(p3) == eltype(p3i) == T
@test vecnorm(x - p3i * (p * 3x)) < eps(real(T)) * 10000
@test vecnorm(3x - pi * (p3 * x)) < eps(real(T)) * 10000
A_mul_B!(y, p, x)
@test y == p * x
A_ldiv_B!(y, p, x)
@test y == p \ x
end
end
end
let
plan32 = plan_fft([1.0:2048.0;])
plan64 = plan_fft([1f0:2048f0;])
FFTW.flops(plan32)
FFTW.flops(plan64)
end
# issue #9772
for x in (randn(10),randn(10,12))
z = complex(x)
y = rfft(x)
@inferred rfft(x)
@inferred brfft(x,18)
@inferred brfft(y,10)
for f in (plan_bfft!, plan_fft!, plan_ifft!,
plan_bfft, plan_fft, plan_ifft,
fft, bfft, fft_, ifft)
p = @inferred f(z)
if isa(p, FFTW.Plan)
@inferred FFTW.plan_inv(p)
end
end
for f in (plan_bfft, plan_fft, plan_ifft,
plan_rfft, fft, bfft, fft_, ifft)
p = @inferred f(x)
if isa(p, FFTW.Plan)
@inferred FFTW.plan_inv(p)
end
end
# note: inference doesn't work for plan_fft_ since the
# algorithm steps are included in the CTPlan type
end
# issue #17896
a = rand(5)
@test fft(a) == fft(view(a,:)) == fft(view(a, 1:5)) == fft(view(a, [1:5;]))
@test rfft(a) == rfft(view(a,:)) == rfft(view(a, 1:5)) == rfft(view(a, [1:5;]))
a16 = convert(Vector{Float16}, a)
@test fft(a16) == fft(view(a16,:)) == fft(view(a16, 1:5)) == fft(view(a16, [1:5;]))
@test rfft(a16) == rfft(view(a16,:)) == rfft(view(a16, 1:5)) == rfft(view(a16, [1:5;]))