Skip to content

thread-safety fixes #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions src/Hadamard.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ module Hadamard
export fwht, ifwht, fwht_natural, ifwht_natural, fwht_natural!, ifwht_natural!, fwht_dyadic, ifwht_dyadic, hadamard, walsh

using FFTW, LinearAlgebra
import FFTW: set_timelimit, dims_howmany, unsafe_execute!, cFFTWPlan, r2rFFTWPlan, PlanPtr, fftwNumber, ESTIMATE, NO_TIMELIMIT, R2HC
import AbstractFFTs: normalization, complexfloat
using FFTW: unsafe_set_timelimit, @exclusive, dims_howmany, unsafe_execute!, cFFTWPlan, r2rFFTWPlan, PlanPtr, fftwNumber, ESTIMATE, NO_TIMELIMIT, R2HC
using AbstractFFTs: normalization, complexfloat

# A power-of-two dimension to be transformed is interpreted as a
# 2x2x2x....x2x2 multidimensional DFT. This function transforms
Expand Down Expand Up @@ -62,34 +62,36 @@ const libfftwf = isdefined(FFTW, :libfftwf) ? FFTW.libfftwf : FFTW.libfftw3f

for (Tr,Tc,fftw,lib) in ((:Float64,:ComplexF64,"fftw",libfftw),
(:Float32,:ComplexF32,"fftwf",libfftwf))
@eval function Plan_Hadamard(X::StridedArray{$Tc,N}, Y::StridedArray{$Tc,N},
@eval @exclusive function Plan_Hadamard(X::StridedArray{$Tc,N}, Y::StridedArray{$Tc,N},
region, flags::Unsigned, timelimit::Real,
bitreverse::Bool) where {N}
set_timelimit($Tr, timelimit)
dims, howmany = dims_howmany(X, Y, [size(X)...], region)
unsafe_set_timelimit($Tr, timelimit)
R = isa(region, Tuple) ? region : copy(region)
dims, howmany = dims_howmany(X, Y, size(X), R)
dims = hadamardize(dims, bitreverse)
plan = ccall(($(string(fftw,"_plan_guru64_dft")),$lib[]),
PlanPtr,
(Int32, Ptr{Int}, Int32, Ptr{Int},
Ptr{$Tc}, Ptr{$Tc}, Int32, UInt32),
size(dims,2), dims, size(howmany,2), howmany,
X, Y, FFTW.FORWARD, flags)
set_timelimit($Tr, NO_TIMELIMIT)
unsafe_set_timelimit($Tr, NO_TIMELIMIT)
if plan == C_NULL
if $(FFTW.fftw_provider == "mkl")
error("MKL is not supported — reconfigure FFTW.jl to use FFTW")
else
error("FFTW could not create plan") # shouldn't normally happen
end
end
return cFFTWPlan{$Tc,FFTW.FORWARD,X===Y,N}(plan, flags, region, X, Y)
return cFFTWPlan{$Tc,FFTW.FORWARD,X===Y,N}(plan, flags, R, X, Y)
end

@eval function Plan_Hadamard(X::StridedArray{$Tr,N}, Y::StridedArray{$Tr,N},
@eval @exclusive function Plan_Hadamard(X::StridedArray{$Tr,N}, Y::StridedArray{$Tr,N},
region, flags::Unsigned, timelimit::Real,
bitreverse::Bool) where {N}
set_timelimit($Tr, timelimit)
dims, howmany = dims_howmany(X, Y, [size(X)...], region)
unsafe_set_timelimit($Tr, timelimit)
R = isa(region, Tuple) ? region : copy(region)
dims, howmany = dims_howmany(X, Y, size(X), R)
dims = hadamardize(dims, bitreverse)
kind = Array{Int32}(undef, size(dims,2))
kind .= R2HC
Expand All @@ -99,15 +101,15 @@ for (Tr,Tc,fftw,lib) in ((:Float64,:ComplexF64,"fftw",libfftw),
Ptr{$Tr}, Ptr{$Tr}, Ptr{Int32}, UInt32),
size(dims,2), dims, size(howmany,2), howmany,
X, Y, kind, flags)
set_timelimit($Tr, NO_TIMELIMIT)
unsafe_set_timelimit($Tr, NO_TIMELIMIT)
if plan == C_NULL
if $(FFTW.fftw_provider == "mkl")
error("MKL is not supported — reconfigure FFTW.jl to use FFTW")
else
error("FFTW could not create plan") # shouldn't normally happen
end
end
return r2rFFTWPlan{$Tr,Vector{Int32},X===Y,N}(plan, flags, region, X, Y, kind)
return r2rFFTWPlan{$Tr,Vector{Int32},X===Y,N}(plan, flags, R, X, Y, kind)
end
end

Expand Down Expand Up @@ -371,7 +373,7 @@ end
"""
walsh(n)

Return a Walsh matrix of order `n`, which must be a power of two, in sequency ordering.
Return a Walsh matrix of order `n`, which must be a power of two, in sequency ordering.
This is related to the Hadamard matrix [`hadamard(n)`](@ref) by a bit-reversal permutation
followed by a Gray-code permutation of the rows.

Expand All @@ -390,7 +392,7 @@ function walsh(n::Int)
j = b ⊻ (b >> 1) # binary sequency index
j + 1 # 1-based index
end
for i in 0:n-1 ]
for i in 0:n-1 ]

return hadamard(n)[j, :]
end
Expand Down
238 changes: 121 additions & 117 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,133 +1,138 @@
using Hadamard, Test, LinearAlgebra

H8 = [ 1 1 1 1 1 1 1 1
1 1 1 1 -1 -1 -1 -1
1 1 -1 -1 -1 -1 1 1
1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1
1 -1 1 -1 -1 1 -1 1
1 -1 1 -1 1 -1 1 -1 ]

H8n = [ 1 1 1 1 1 1 1 1
1 -1 1 -1 1 -1 1 -1
1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1
1 1 1 1 -1 -1 -1 -1
1 -1 1 -1 -1 1 -1 1
1 1 -1 -1 -1 -1 1 1
1 -1 -1 1 -1 1 1 -1 ]

H8d = [ 1 1 1 1 1 1 1 1
1 1 1 1 -1 -1 -1 -1
1 1 -1 -1 1 1 -1 -1
1 1 -1 -1 -1 -1 1 1
1 -1 1 -1 1 -1 1 -1
1 -1 1 -1 -1 1 -1 1
1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1 ]


I8 = Matrix{Float64}(I,8,8)
iI8 = Matrix{Int8}(I,8,8)

@test ifwht(I8,1) == H8
@test ifwht(I8,2)' == H8
@test ifwht_natural(I8,1) == H8n
@test ifwht_natural(I8,2)' == H8n
@test ifwht_dyadic(I8,1) == H8d
@test ifwht_dyadic(I8,2)' == H8d

@test ifwht(iI8,1) == H8
@test ifwht(iI8,2)' == H8
@test ifwht_natural(iI8,1) == H8n
@test ifwht_natural(iI8,2)' == H8n
@test ifwht_dyadic(iI8,1) == H8d
@test ifwht_dyadic(iI8,2)' == H8d

H32 = [ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1
1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1
1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1
1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1
1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1
1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1
1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1
1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1
1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1
1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1
1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1
1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1
1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1
1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1
1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1
1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1
1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1
1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1
1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1
1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1
1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1
1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1
1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1
1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 ]

I32 = Matrix{Float64}(I,32,32)
iI32 = Matrix{Int8}(I,32,32)

@test ifwht(I32,1) == H32
@test ifwht(I32,2)' == H32

@test ifwht(iI32,1) == H32
@test ifwht(iI32,2)' == H32

X = reshape(sin.([1:1024*32;]), 1024,32);
norminf(A) = maximum(abs, A)

# non-lazy transpose for 0.7:
transp(x::AbstractMatrix) = permutedims(x, (2,1))

for f in (:fwht, :fwht_natural, :fwht_dyadic)
fi = Symbol(string("i", f))
@eval begin
@test norminf(X - $fi($f(X))) < 1e-14
@test norminf(X - $fi($f(X,1),1)) < 1e-14
@test norminf(X - $fi($f(X,2),2)) < 1e-14
@test norminf($f($f(X,1),2) - $f(X)) < 1e-14
@test norminf(transp($f(transp(X),1)) - $f(X,2)) < 1e-14
# test input data
X = reshape(sin.([1:1024*32;]), 1024,32)

@testset "fast Walsh–Hadamard transforms" begin
H8 = [ 1 1 1 1 1 1 1 1
1 1 1 1 -1 -1 -1 -1
1 1 -1 -1 -1 -1 1 1
1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1
1 -1 1 -1 -1 1 -1 1
1 -1 1 -1 1 -1 1 -1 ]

H8n = [ 1 1 1 1 1 1 1 1
1 -1 1 -1 1 -1 1 -1
1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1
1 1 1 1 -1 -1 -1 -1
1 -1 1 -1 -1 1 -1 1
1 1 -1 -1 -1 -1 1 1
1 -1 -1 1 -1 1 1 -1 ]

H8d = [ 1 1 1 1 1 1 1 1
1 1 1 1 -1 -1 -1 -1
1 1 -1 -1 1 1 -1 -1
1 1 -1 -1 -1 -1 1 1
1 -1 1 -1 1 -1 1 -1
1 -1 1 -1 -1 1 -1 1
1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1 ]


I8 = Matrix{Float64}(I,8,8)
iI8 = Matrix{Int8}(I,8,8)

@test ifwht(I8,1) == H8
@test ifwht(I8,2)' == H8
@test ifwht_natural(I8,1) == H8n
@test ifwht_natural(I8,2)' == H8n
@test ifwht_dyadic(I8,1) == H8d
@test ifwht_dyadic(I8,2)' == H8d

@test ifwht(iI8,1) == H8
@test ifwht(iI8,2)' == H8
@test ifwht_natural(iI8,1) == H8n
@test ifwht_natural(iI8,2)' == H8n
@test ifwht_dyadic(iI8,1) == H8d
@test ifwht_dyadic(iI8,2)' == H8d

H32 = [ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1
1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1
1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1
1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1
1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1
1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1
1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1
1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1
1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1
1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1
1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 1 1 -1 -1 1 1 -1 -1
1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1
1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1
1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1
1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1
1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1
1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1
1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1
1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1
1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1
1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1
1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1
1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1
1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1
1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 1 -1 1 -1 1 -1 1 -1
1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1
1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 ]

I32 = Matrix{Float64}(I,32,32)
iI32 = Matrix{Int8}(I,32,32)

@test ifwht(I32,1) == H32
@test ifwht(I32,2)' == H32

@test ifwht(iI32,1) == H32
@test ifwht(iI32,2)' == H32

for f in (:fwht, :fwht_natural, :fwht_dyadic)
fi = Symbol(string("i", f))
@eval begin
@test norminf(X - $fi($f(X))) < 1e-14
@test norminf(X - $fi($f(X,1),1)) < 1e-14
@test norminf(X - $fi($f(X,2),2)) < 1e-14
@test norminf($f($f(X,1),2) - $f(X)) < 1e-14
@test norminf(transp($f(transp(X),1)) - $f(X,2)) < 1e-14
end
end
end

@test hadamard(8) == H8n
@test ifwht_natural(I32, 1) == hadamard(32)
@test ifwht_natural(Matrix{Float64}(I,2,2), 1) == hadamard(2)
@test hadamard(8) == H8n
@test ifwht_natural(I32, 1) == hadamard(32)
@test ifwht_natural(Matrix{Float64}(I,2,2), 1) == hadamard(2)

let X = copy(I32)
@test ifwht_natural!(X, 1) == X == hadamard(32)
@test fwht_natural!(X, 1) == X == I32
let X = copy(I32)
@test ifwht_natural!(X, 1) == X == hadamard(32)
@test fwht_natural!(X, 1) == X == I32
end
end

print("Checking unitarity of hadamard(n): ")
sizes = Int[]
for i = 4:4:1200
H = try
Matrix{Int}(hadamard(i))
catch
Int[]
end
if !isempty(H)
print(i, ", ")
@test norminf(H'*H - size(H,1)*I) == 0
push!(sizes, i)
@testset "hadamard(n)" begin
sizes = Int[]
for i = 4:4:1200
H = try
Matrix{Int}(hadamard(i))
catch
Matrix{Int}(undef,0,0)
end
if !isempty(H)
# print(i, ", ")
@test norminf(H'*H - size(H,1)*I) == 0
push!(sizes, i)
end
end
@test sizes == [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 256, 264, 272, 280, 288, 296, 304, 312, 320, 328, 336, 344, 352, 360, 368, 376, 384, 392, 400, 408, 416, 424, 428, 432, 440, 448, 456, 464, 472, 480, 488, 496, 504, 512, 528, 544, 560, 576, 592, 608, 624, 640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848, 856, 864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1040, 1056, 1088, 1104, 1120, 1152, 1184, 1200]
end
@test sizes == [4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 256, 264, 272, 280, 288, 296, 304, 312, 320, 328, 336, 344, 352, 360, 368, 376, 384, 392, 400, 408, 416, 424, 428, 432, 440, 448, 456, 464, 472, 480, 488, 496, 504, 512, 528, 544, 560, 576, 592, 608, 624, 640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848, 856, 864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1040, 1056, 1088, 1104, 1120, 1152, 1184, 1200]

@testset "walsh(n)" begin
@test walsh(8) == [1 1 1 1 1 1 1 1; 1 1 1 1 -1 -1 -1 -1; 1 1 -1 -1 -1 -1 1 1; 1 1 -1 -1 1 1 -1 -1; 1 -1 -1 1 1 -1 -1 1; 1 -1 -1 1 -1 1 1 -1; 1 -1 1 -1 -1 1 -1 1; 1 -1 1 -1 1 -1 1 -1]
Expand All @@ -137,4 +142,3 @@ end
end
end

println(".\nSuccess!")
Loading