Skip to content

Commit e146c60

Browse files
add butterfly constructor for orthogonal matrices
1 parent a018a6d commit e146c60

File tree

4 files changed

+116
-20
lines changed

4 files changed

+116
-20
lines changed

src/SphericalHarmonics/Butterfly.jl

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,79 @@ function Butterfly{T}(A::AbstractMatrix{T}, L::Int64)
101101
Butterfly(columns, factors, permutations, indices, zeros(T, kk), zeros(T, kk), zeros(T, kk))
102102
end
103103

104+
function orthogonalButterfly{T}(A::AbstractMatrix{T}, L::Int64)
105+
m, n = size(A)
106+
tL = 2^L
107+
108+
LRAOpts = LRAOptions(T; rtol = eps(real(T))*max(m, n))
109+
110+
columns = Vector{Matrix{T}}(tL)
111+
factors = Vector{Vector{IDPackedV{T}}}(L+1)
112+
permutations = Vector{Vector{ColumnPermutation}}(L+1)
113+
indices = Vector{Vector{Int64}}(L+1)
114+
cs = Vector{Vector{Vector{Int64}}}(L+1)
115+
116+
factors[1] = Vector{IDPackedV{T}}(tL)
117+
permutations[1] = Vector{ColumnPermutation}(tL)
118+
indices[1] = Vector{Int64}(tL+1)
119+
cs[1] = Vector{Vector{Int64}}(tL)
120+
121+
nd = n÷tL
122+
nl = 1
123+
nu = nd
124+
indices[1][1] = 1
125+
for j = 1:tL
126+
factors[1][j] = IDPackedV{T}(collect(1:nd),Int64[],Array{T}(nd,0))
127+
permutations[1][j] = factors[1][j][:P]
128+
indices[1][j+1] = indices[1][j] + size(factors[1][j], 1)
129+
cs[1][j] = factors[1][j].sk+nl-1
130+
nl += nd
131+
nu += nd
132+
end
133+
134+
ii, jj = 2, (tL>>1)
135+
for l = 2:L+1
136+
factors[l] = Vector{IDPackedV{T}}(tL)
137+
permutations[l] = Vector{ColumnPermutation}(tL)
138+
indices[l] = Vector{Int64}(tL+1)
139+
cs[l] = Vector{Vector{Int64}}(tL)
140+
141+
ctr = 0
142+
md = m÷ii
143+
ml = 1
144+
mu = md
145+
indices[l][1] = 1
146+
for i = 1:ii
147+
shft = 2jj*div(ctr,2jj)
148+
for j = 1:jj
149+
cols = vcat(cs[l-1][2j-1+shft],cs[l-1][2j+shft])
150+
factors[l][j+ctr] = idfact(view(A, ml:mu, cols), LRAOpts)
151+
permutations[l][j+ctr] = factors[l][j+ctr][:P]
152+
indices[l][j+ctr+1] = indices[l][j+ctr] + size(factors[l][j+ctr], 1)
153+
cs[l][j+ctr] = cols[factors[l][j+ctr].sk]
154+
end
155+
ml += md
156+
mu += md
157+
ctr += jj
158+
end
159+
ii <<= 1
160+
jj >>= 1
161+
end
162+
163+
md = m÷tL
164+
ml = 1
165+
mu = md
166+
for i = 1:tL
167+
columns[i] = A[ml:mu,cs[L+1][i]]
168+
ml += md
169+
mu += md
170+
end
171+
172+
kk = sumkmax(indices)
173+
174+
Butterfly(columns, factors, permutations, indices, zeros(T, kk), zeros(T, kk), zeros(T, kk))
175+
end
176+
104177
function sumkmax(indices::Vector{Vector{Int64}})
105178
ret = 0
106179
@inbounds for j = 1:length(indices)

src/SphericalHarmonics/fastplan.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ function FastSphericalHarmonicPlan{T}(A::Matrix{T}, L::Int)
2323
BF = Vector{Butterfly{T}}(n-2)
2424
for j = 1:2:n-2
2525
A_mul_B!(Ce, RP.layers[j])
26-
BF[j] = Butterfly(Ce, L)
27-
println("Level: ",j)
26+
BF[j] = orthogonalButterfly(Ce, L)
27+
#println("Level: ",j)
2828
end
2929
for j = 2:2:n-2
3030
A_mul_B!(Co, RP.layers[j])
31-
BF[j] = Butterfly(Co, L)
32-
println("Level: ",j)
31+
BF[j] = orthogonalButterfly(Co, L)
32+
#println("Level: ",j)
3333
end
3434
FastSphericalHarmonicPlan(RP, BF, p1, p2, p1inv, p2inv, B)
3535
end

test/butterflytests.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,26 @@ for n in 7:N
7777
@time A_mul_B!(u, B, b)
7878
println(norm(u-uf)/2^n)
7979
end
80+
81+
82+
N = 14
83+
A = Vector{Matrix{Complex{Float64}}}(N)
84+
B = Vector{Butterfly{Complex{Float64}}}(N)
85+
for n in 7:N
86+
A[n] = randnfft(2^n,2^n,0.1)
87+
@time B[n] = Butterfly(A[n], n-6)
88+
println(n)
89+
end
90+
91+
for n in 7:N
92+
println("N = ", n)
93+
b = rand(Complex{Float64},2^n)./(1:2^n)
94+
uf = zero(b)
95+
u = zero(b)
96+
@time for k = 1:100
97+
A_mul_B!(uf, A[n], b)
98+
end
99+
@time for k = 1:100
100+
A_mul_B!(u, B[n], b)
101+
end
102+
end

test/test_fastplan.jl

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,25 @@ function maxcolnorm(A::AbstractMatrix)
5959
norm(nrm, Inf)
6060
end
6161

62-
n = 1023
62+
function zero_spurious_modes!(A::AbstractMatrix)
63+
M, N = size(A)
64+
n = N÷2
65+
for j = 1:n
66+
for i = M-j+1:M
67+
A[i,2j] = 0
68+
A[i,2j+1] = 0
69+
end
70+
end
71+
A
72+
end
73+
74+
n = 255
6375

6476
A = sphrandn(Float64, n+1, n+1)
6577
normalizecolumns!(A)
6678
Ac = deepcopy(A)
6779

68-
FP = FastSphericalHarmonicPlan(A, 5);
80+
FP = FastSphericalHarmonicPlan(A, 2);
6981

7082
B = zero(A);
7183

@@ -91,20 +103,8 @@ println("The difference between fast plan and original: ", maxcolnorm(A-D))
91103
println("The difference between slow plan and original: ", maxcolnorm(A-E))
92104
println("The difference between slow and fast plans: ", maxcolnorm(D-E))
93105

94-
function zero_spurious_modes!(A::AbstractMatrix)
95-
M, N = size(A)
96-
n = N÷2
97-
for j = 1:n
98-
for i = M-j+1:M
99-
A[i,2j] = 0
100-
A[i,2j+1] = 0
101-
end
102-
end
103-
A
104-
end
105-
106-
zero_spurious_modes!(D)
107-
zero_spurious_modes!(E)
106+
zero_spurious_modes!(D);
107+
zero_spurious_modes!(E);
108108

109109
println("The difference between fast plan and original: ", maxcolnorm(A-D))
110110
println("The difference between slow plan and original: ", maxcolnorm(A-E))

0 commit comments

Comments
 (0)