Skip to content

Commit 4db3d34

Browse files
authored
Merge pull request #22 from ranjanan/satest
Tests for Smooth Aggregation
2 parents a219756 + 091a92d commit 4db3d34

File tree

9 files changed

+408
-123
lines changed

9 files changed

+408
-123
lines changed

src/aggregation.jl

Lines changed: 18 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ function extend_hierarchy!(levels, strength, aggregate, smooth,
5757
S = strength_of_connection(strength, A, bsr_flag)
5858

5959
# Aggregation operator
60-
AggOp = aggregation(aggregate, S')
61-
60+
AggOp = aggregation(aggregate, S)
6261
# b = zeros(eltype(A), size(A, 1))
6362

6463
# Improve candidates
@@ -81,51 +80,24 @@ construct_R(::HermitianSymmetry, P) = P'
8180

8281
function fit_candidates(AggOp, B, tol = 1e-10)
8382

84-
# K1 = Int(size(B, 1) / N_fine)
85-
# K2 = size(B, 2)
86-
8783
A = AggOp.'
88-
89-
n_coarse = size(A, 2)
90-
n_fine = size(A, 1)
84+
n_fine, n_coarse = size(A)
9185
n_col = n_coarse
9286

93-
# R = zeros(eltype(B), N_coarse, K2, K2)
9487
R = zeros(eltype(B), n_coarse)
95-
# Qx = zeros(eltype(B), nnz(AggOp), K1, K2)
9688
Qx = zeros(eltype(B), nnz(A))
9789

98-
99-
# R = vec(R)
100-
# Qx = vec(Qx)
101-
102-
# n_row = N_fine
103-
# n_col = N_coarse
104-
105-
# BS = K1 * K2
106-
107-
#=for i = 1:n_col
108-
Ax_start = 1 + BS * A.colptr[i]
109-
110-
for j in nzrange(A, i)
111-
B_start = 1 + BS * A.rowval[j]
112-
B_end = B_start + BS
113-
@show B_start
114-
@show B_end
115-
for ind in B_start:B_end
116-
A.nzval[ind + Ax_start] = B[ind]
117-
end
118-
Ax_start += BS
119-
end
120-
end=#
121-
# copy!(A.nzval, B)
12290
copy!(Qx, B)
123-
# @show size(A.nzval)
124-
# @show size(B)
125-
91+
# copy!(A.nzval, B)
92+
for i = 1:n_col
93+
for j in nzrange(A,i)
94+
row = A.rowval[j]
95+
A.nzval[j] = B[row]
96+
end
97+
end
98+
k = 1
12699
for i = 1:n_col
127100
norm_i = norm_col(A, Qx, i)
128-
# norm_i = norm(A[:,i])
129101
threshold_i = tol * norm_i
130102
if norm_i > threshold_i
131103
scale = 1 / norm_i
@@ -136,82 +108,22 @@ function fit_candidates(AggOp, B, tol = 1e-10)
136108
end
137109
for j in nzrange(A, i)
138110
row = A.rowval[j]
139-
Qx[row] *= scale
111+
# Qx[row] *= scale
112+
#@show k
113+
# Qx[k] *= scale
114+
# k += 1
115+
A.nzval[j] *= scale
140116
end
141-
#=col_start = A.colptr[i]
142-
col_end = A.colptr[i+1]
143-
144-
Ax_start = 1 + BS * col_start
145-
Ax_end = 1 + BS * col_end
146-
R_start = 1 + i * K2 * K2
147-
148-
for bj = 1:K2
149-
norm_j = zero(eltype(A))
150-
Ax_col = Ax_start + bj
151-
while Ax_col < Ax_end
152-
norm_j += norm(A.nzval[Ax_col])
153-
Ax_col += K2
154-
end
155-
norm_j = sqrt(norm_j)
156-
157-
threshold_j = tol * norm_j
158-
159-
for bi = 1:bj
160-
dot_prod = zero(eltype(A))
161-
162-
Ax_bi = Ax_start + bj
163-
Ax_bj = Ax_start + bj
164-
while Ax_bi < Ax_end
165-
dot_prod += dot(A.nzval[Ax_bj], A.nzval[Ax_bi])
166-
Ax_bi += K2
167-
Ax_bj += K2
168-
end
169-
170-
Ax_bi = Ax_start + bi;
171-
Ax_bj = Ax_start + bj;
172-
while Ax_bi < Ax_end
173-
A.nzval[Ax_bj] -= dot_prod * A.nzval[Ax_bi]
174-
Ax_bi += K2
175-
Ax_bj += K2
176-
end
177-
178-
R[R_start + K2 * bi + bj] = dot_prod
179-
end
180-
181-
norm_j = zero(eltype(A))
182-
Ax_bj = Ax_start + bj
183-
while Ax_bj < Ax_end
184-
norm_j += norm(A.nzval[Ax_bj])
185-
Ax_bj += K2
186-
norm_j = sqrt(norm_j)
187-
end
188-
189-
if norm_j > threshold_j
190-
scale = 1 / norm_j
191-
R[R_start + K2 * bj + bj] = norm_j
192-
else
193-
scale = zero(eltype(A))
194-
R[R_start + K2 * bj + bj] = 0
195-
end
196-
197-
Ax_bj = Ax_start + bj
198-
while Ax_bj < Ax_end
199-
A.nzval[Ax_bj] *= scale
200-
Ax_bj += K2
201-
end
202-
end=#
203117
end
204118

205-
#Q = SparseMatrixCSC(N_coarse, N_fine,
206-
#.colptr, A.rowval, Qx)
207-
208-
#R = reshape(R, N_coarse, K2)
209-
SparseMatrixCSC(size(A)..., A.colptr, A.rowval, Qx), R
119+
# SparseMatrixCSC(size(A)..., A.colptr, A.rowval, Qx), R
120+
A, R
210121
end
211122
function norm_col(A, Qx, i)
212123
s = zero(eltype(A))
213124
for j in nzrange(A, i)
214125
val = Qx[A.rowval[j]]
126+
# val = A.nzval[A.rowval[j]]
215127
s += val*val
216128
end
217129
sqrt(s)

src/gallery.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
poisson(n) = sparse(Tridiagonal(fill(-1, n-1), fill(2, n), fill(-1, n-1)))
1+
poisson(T, n) = sparse(Tridiagonal(fill(T(-1), n-1),
2+
fill(T(2), n), fill(T(-1), n-1)))
3+
poisson(n) = poisson(Float64, n)

src/multilevel.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ function solve{T}(ml::MultiLevel, b::Vector{T},
8888
push!(residuals, T(norm(b - A * x)))
8989
end
9090

91+
# @show residuals
9192
if log
9293
return x, residuals
9394
else

src/smoother.jl

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ presmoother!(s, A, x, b) = smoother!(s, s.sweep, A, x, b)
1818
postsmoother!(s, A, x, b) = smoother!(s, s.sweep, A, x, b)
1919
relax!(s, A, x, b) = smoother!(s, s.sweep, A, x, b)
2020

21-
smoother!(s::GaussSeidel, ::ForwardSweep, A, x, b) =
22-
gs!(A, b, x, 1, 1, size(A, 1))
21+
function smoother!(s::GaussSeidel, ::ForwardSweep, A, x, b)
22+
for i in 1:s.iter
23+
gs!(A, b, x, 1, 1, size(A, 1))
24+
end
25+
end
2326

2427
function smoother!(s::GaussSeidel, ::SymmetricSweep, A, x, b)
2528
for i in 1:s.iter
@@ -28,8 +31,11 @@ function smoother!(s::GaussSeidel, ::SymmetricSweep, A, x, b)
2831
end
2932
end
3033

31-
smoother!(s::GaussSeidel, ::BackwardSweep, A, x, b) =
32-
gs!(A, b, x, size(A,1), -1, 1)
34+
function smoother!(s::GaussSeidel, ::BackwardSweep, A, x, b)
35+
for i in 1:s.iter
36+
gs!(A, b, x, size(A,1), -1, 1)
37+
end
38+
end
3339

3440

3541
function gs!(A, b, x, start, step, stop)
@@ -94,11 +100,13 @@ end
94100

95101
struct DiagonalWeighting
96102
end
103+
struct LocalWeighting
104+
end
97105

98106
function smooth_prolongator(j::JacobiProlongation,
99107
A, T, S, B,
100108
degree = 1,
101-
weighting = DiagonalWeighting())
109+
weighting = LocalWeighting())
102110
D_inv_S = weight(weighting, A, j.ω)
103111
P = T
104112
for i = 1:degree
@@ -111,7 +119,14 @@ function weight(::DiagonalWeighting, S, ω)
111119
D_inv = 1 ./ diag(S)
112120
D_inv_S = scale_rows(S, D_inv)
113121
(eltype(S)(ω) / approximate_spectral_radius(D_inv_S)) * D_inv_S
114-
#(ω) * D_inv_S
122+
# (ω) * D_inv_S
123+
end
124+
125+
function weight(::LocalWeighting, S, ω)
126+
D = abs.(S) * ones(size(S, 1))
127+
D_inv = 1 ./ D[find(D)]
128+
D_inv_S = scale_rows(S, D_inv)
129+
eltype(S)(ω) * D_inv_S
115130
end
116131

117132
#approximate_spectral_radius(A) =
@@ -127,4 +142,4 @@ function scale_rows!(ret, S, v)
127142
end
128143
ret
129144
end
130-
scale_rows(S, v) = scale_rows!(deepcopy(S), S, v)
145+
scale_rows(S, v) = scale_rows!(deepcopy(S), S, v)

src/strength.jl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,20 +107,26 @@ function strength_of_connection{T}(s::SymmetricStrength{T}, A, bsr_flag = false)
107107
for j in nzrange(A, i)
108108
row = A.rowval[j]
109109
val = A.nzval[j]
110-
if val*val < eps_Aii * diags[row]
111-
S.nzval[j] = 0
110+
if row != i
111+
if val*val < eps_Aii * diags[row]
112+
S.nzval[j] = 0
113+
end
112114
end
113115
end
114116
end
115117

116118
dropzeros!(S)
117119

118-
S.nzval .= abs.(S.nzval)
119-
# for i = 1:size(S.nzval, 1)
120+
# S.nzval .= abs.(S.nzval)
121+
#for i = 1:size(S.nzval, 1)
120122
# S.nzval[i] = abs(S.nzval[i])
121-
# end
123+
#end
122124

123125
scale_cols_by_largest_entry!(S)
126+
127+
for i = 1:size(S.nzval, 1)
128+
S.nzval[i] = abs(S.nzval[i])
129+
end
124130

125131
S
126132
end

src/utils.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ function approximate_spectral_radius(A, tol = 0.01,
55
symmetric = false
66

77
# Initial guess
8-
v0 = rand(eltype(A), size(A,1))
8+
v0 = rand(eltype(A), size(A,2))
99
maxiter = min(size(A, 1), maxiter)
1010
ev = zeros(eltype(A), maxiter)
1111
max_index = 0
@@ -21,7 +21,7 @@ function approximate_spectral_radius(A, tol = 0.01,
2121
# m, max_index = findmax(abs.(ev))
2222
m, max_index = findmaxabs(ev)
2323
error = H[nvecs, nvecs-1] * evect[end, max_index]
24-
if abs(error) / abs(ev[max_index]) < tol || flag
24+
if (abs(error) / abs(ev[max_index]) < tol) || flag
2525
# v0 = X * evect[:, max_index]
2626
A_mul_B!(v0, X, evect[:, max_index])
2727
break
@@ -63,6 +63,7 @@ function approximate_eigenvalues(A, tol, maxiter, symmetric, v0)
6363
# V = Vector{Vector{eltype(A)}}(maxiter + 1)
6464
# V = zeros(size(A,1), maxiter)
6565
# V[1] = v0
66+
breakdown = find_breakdown(eltype(A))
6667
flag = false
6768

6869
for j = 1:maxiter
@@ -73,11 +74,11 @@ function approximate_eigenvalues(A, tol, maxiter, symmetric, v0)
7374
for (i,v) in enumerate(V)
7475
# for i = 1:j
7576
v = V[i]
76-
H[i,j] = dot(v, w)
77+
H[i,j] = dot(conj.(v), w)
7778
BLAS.axpy!(-H[i,j], v, w)
7879
end
7980
H[j+1,j] = norm(w)
80-
if H[j+1, j] < eps()
81+
if H[j+1, j] < breakdown
8182
flag = true
8283
if H[j+1,j] != 0
8384
scale!(w, 1/H[j+1,j])
@@ -94,3 +95,6 @@ function approximate_eigenvalues(A, tol, maxiter, symmetric, v0)
9495

9596
Vects, Eigs, H, V, flag
9697
end
98+
99+
find_breakdown(::Type{Float64}) = eps(Float64) * 10^6
100+
find_breakdown(::Type{Float32}) = eps(Float64) * 10^3

test/ref_R.jld

16.1 KB
Binary file not shown.

test/runtests.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ using JLD
44
using IterativeSolvers
55
import AMG: V, coarse_solver, Pinv, Classical
66

7+
include("sa_tests.jl")
8+
79
@testset "AMG Tests" begin
810

911
graph = load("test.jld")["G"]
@@ -234,4 +236,33 @@ end
234236

235237
end
236238

239+
# Smoothed Aggregation
240+
@testset "Smoothed Aggregation" begin
241+
242+
@testset "Symmetric Strength of Connection" begin
243+
244+
test_symmetric_soc()
245+
end
246+
247+
@testset "Standard Aggregation" begin
248+
249+
test_standard_aggregation()
250+
end
251+
252+
@testset "Fit Candidates" begin
253+
test_fit_candidates()
254+
end
255+
256+
@testset "Approximate Spectral Radius" begin
257+
test_approximate_spectral_radius()
258+
end
259+
end
260+
261+
@testset "Gauss Seidel" begin
262+
test_gauss_seidel()
263+
end
264+
265+
@testset "Jacobi Prolongation" begin
266+
test_jacobi_prolongator()
267+
end
237268
end

0 commit comments

Comments
 (0)