Skip to content

Commit 6146d5b

Browse files
Added the figure scripts for the eGHWT journal paper
1 parent fcf90b3 commit 6146d5b

File tree

11 files changed

+924
-0
lines changed

11 files changed

+924
-0
lines changed
157 KB
Loading
220 KB
Binary file not shown.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
################################################################################
2+
####################### Approximation error plot ###############################
3+
################################################################################
4+
function approx_error2(DVEC::Array{Array{Float64,1},1},
5+
T::Vector{String}, L::Vector{Tuple{Symbol,Symbol}},
6+
frac::Float64 = 0.30)
7+
# This version plots the relative L2 errors against
8+
# the FRACTION of coefficients retained.
9+
plot(xaxis = "Fraction of Coefficients Retained",
10+
yaxis = "Relative Approximation Error")
11+
for i = 1:length(DVEC)
12+
dvec = DVEC[i]
13+
N = length(dvec)
14+
dvec_norm = norm(dvec,2)
15+
dvec_sort = sort(dvec.^2) # the smallest first
16+
er = sqrt.(reverse(cumsum(dvec_sort)))/dvec_norm
17+
er[er .== 0.0] .= minimum(er[er .!= 0.0]) # avoid blowup by taking log in the plot below
18+
# er is the relative L^2 error of the whole thing: length(er)=N.
19+
p = Int64(floor(frac*N)) + 1 # upper limit
20+
plot!(frac*(0:(p-1))/(p-1), er[1:p], yaxis=:log, xlims = (0.,frac),
21+
label = T[i], line = L[i], linewidth = 2, grid = false)
22+
end
23+
display(current())
24+
end
25+
26+
27+
function approx_error3(DVEC::Array{Array{Float64,1},1},
28+
T::Vector{String}, L::Vector{Tuple{Symbol,Symbol}},
29+
N::Int64)
30+
# This version plots the relative L2 errors against
31+
# the NUMBER of coefficients retained.
32+
plot(xaxis = "Number of Coefficients Retained",
33+
yaxis = "Relative Approximation Error")
34+
for i = 1:length(DVEC)
35+
dvec = DVEC[i]
36+
dvec_norm = norm(dvec,2)
37+
dvec_sort = sort(dvec.^2) # the smallest first
38+
er = sqrt.(reverse(cumsum(dvec_sort)))/dvec_norm
39+
er[er .== 0.0] .= minimum(er[er .!= 0.0]) # avoid blowup by taking log in the plot below
40+
# er is the relative L^2 error of the whole thing: length(er)=N.
41+
plot!(0:N-1, er[1:N], yaxis=:log, label = T[i], line = L[i],
42+
linewidth = 2, grid = false)
43+
end
44+
display(current())
45+
end
46+
47+
################################################################################
48+
############ Computing a weight matrix using the Gaussian affinity #############
49+
################################################################################
50+
function image_Gaussian_affinity(img::Matrix{Float64}, r::Int64, σ::Float64)
51+
# Get the neighbors for affinity matrix computation
52+
l = 2*r + 1
53+
temp_x, temp_y = fill(1,l^2), fill(1,l^2)
54+
temp_xy = CartesianIndices((1:l,1:l))
55+
for i = 1:l^2
56+
temp_x[i], temp_y[i] = temp_xy[i][1], temp_xy[i][2]
57+
end
58+
# (r+1, r+1) is the index of the center location.
59+
temp_ind = ((temp_x .- (r + 1)).^2 + (temp_y .- (r + 1)).^2) .<= r^2
60+
# Now, temp_ind indicates those points withinin the circle of radius r
61+
# from the center while neighbor_x, neighbor_y represent relative positions
62+
# of those points from the center.
63+
neighbor_x = temp_x[temp_ind] .- (r + 1)
64+
neighbor_y = temp_y[temp_ind] .- (r + 1)
65+
# So, for any index (x, y), points within (x ± neighbor_x, y ± neighbor_y) are
66+
# its neighbors for the purpose of calculating affinity
67+
68+
# Create affinity matrix
69+
m, n = size(img)
70+
sig = img[:]
71+
W = fill(0., (m*n,m*n))
72+
for i = 1:m*n
73+
cur = CartesianIndices((m,n))[i]
74+
for j = 1:length(neighbor_x) # assuming dim(neighbor_x) == dim(neighbor_y)
75+
if 1 <= cur[1] + neighbor_x[j] <= m && 1 <= cur[2] + neighbor_y[j] <= n
76+
tempd = LinearIndices((m,n))[cur[1] + neighbor_x[j], cur[2] + neighbor_y[j]]
77+
W[i,tempd] = exp(-(sig[i] - sig[tempd])^2/σ)
78+
end
79+
end
80+
end
81+
return sparse(W)
82+
end # end of the image_Gaussian_affinity function
83+
84+
################################################################################
85+
######## Display top 9 basis vectors of various bases for an image data ########
86+
################################################################################
87+
function top_vectors_plot2(dvec::Array{Float64, 2}, m::Int64, n::Int64, BS::BasisSpec, GP::GraphPart;
88+
clims::Tuple{Float64,Float64} = (-0.01, 0.01))
89+
90+
# Get the indices from max to min in terms of absolute value of the coefs
91+
# Note that m*n == length(dvec); m and n are the image size.
92+
sorted_ind = sortperm(abs.(dvec[:]), rev = true);
93+
94+
# Set up the layout as 3 x 3 subplots
95+
plot(9, layout = (3,3), framestyle = :none, legend = false)
96+
97+
# Do the display!
98+
for i=1:9
99+
dvecT = fill(0., size(dvec))
100+
dvecT[sorted_ind[i]] = 1
101+
f = ghwt_synthesis(dvecT, GP, BS)
102+
heatmap!(reshape(f, (m,n)), subplot=i, ratio=1, yaxis=:flip,
103+
showaxis=false, ticks = false, color = :grays, clims = clims)
104+
end
105+
display(current())
106+
end
107+
################################################################################
108+
109+
function top_vectors_plot3(dvec::Array{Float64, 2}, m::Int64, n::Int64, BS::BasisSpec,
110+
GP::GraphPart; clims::Tuple{Float64,Float64} = (-0.01, 0.01), K::Int64 = 9)
111+
112+
# Get the indices from max to min in terms of absolute value of the coefs
113+
# Note that m*n == length(dvec); m and n are the image size.
114+
sorted_ind = sortperm(abs.(dvec[:]), rev = true);
115+
116+
# Set up the layout as 3 x 3 subplots
117+
plot(K, layout = (Int(sqrt(K)), Int(sqrt(K))), framestyle = :none, legend = false)
118+
119+
# Do the display!
120+
for i=1:K
121+
dvecT = fill(0., size(dvec))
122+
dvecT[sorted_ind[i]] = 1
123+
f = ghwt_synthesis(dvecT, GP, BS)
124+
heatmap!(reshape(f, (m,n)), subplot=i, ratio=1, yaxis=:flip,
125+
showaxis=false, ticks = false, color = :grays, clims = clims)
126+
end
127+
display(current())
128+
end
129+
################################################################################
130+
2 MB
Binary file not shown.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Script to generate figures in Figure 2.
2+
using Plots, SparseArrays, JLD2, LinearAlgebra, MultiscaleGraphSignalTransforms
3+
4+
# First define a utility function "Glevel", which generate a Graph Signal that
5+
# are piecewise constants whose values are actual region indices "k".
6+
function Glevel(G::GraphSig, GP::GraphPart, j::Int64)
7+
f = zeros(size(G.f))
8+
for k in 1:size(GP.rs,1)
9+
a = GP.rs[k,j+1]
10+
b = GP.rs[k+1,j+1] - 1
11+
if b == -1
12+
break
13+
end
14+
f[a:b] .= k*1.0
15+
end
16+
Gsub = deepcopy(G)
17+
Gsub.f[GP.ind] = f
18+
return Gsub
19+
end
20+
21+
# Set up the resolution and display size
22+
gr(dpi=200, size=(800,600))
23+
24+
# Load the Toronto street network (vehicular volume counts as its graph signal)
25+
JLD2.@load "Toronto_new.jld2"
26+
tmp1 = toronto["G"]
27+
G=GraphSig(tmp1["W"],xy=tmp1["xy"],f=tmp1["f"],name =tmp1["name"],
28+
plotspecs = tmp1["plotspecs"])
29+
30+
# Assign correct edge weights via 1/Euclidean distance
31+
G = Adj2InvEuc(G)
32+
# Perform the hierarchical graph partitioning using the Fiedler vectors
33+
GP = partition_tree_fiedler(G) # Lrw by default
34+
# Compute the expansion coefficients of the full GHWT c2f dictionary
35+
dmatrix = ghwt_analysis!(G, GP=GP)
36+
N = length(G.f)
37+
38+
# Fig. 2a: Level 1 first since Level 0 is not interesting
39+
j = 1
40+
GraphSig_Plot(Glevel(G,GP,j), linewidth = 1., markersize = 4.,
41+
markercolor = :viridis, markerstrokealpha =0., notitle = true, nocolorbar = true)
42+
plot!(showaxis = false, ticks = false)
43+
savefig("toronto_j1.pdf")
44+
savefig("toronto_j1.png")
45+
46+
# Fig. 2b: Level 2
47+
j = 2
48+
GraphSig_Plot(Glevel(G,GP,j), linewidth = 1., markersize = 4.,
49+
markercolor = :viridis, markerstrokealpha =0., notitle = true, nocolorbar = true)
50+
plot!(showaxis = false, ticks = false)
51+
savefig("toronto_j2.pdf")
52+
savefig("toronto_j2.png")
53+
54+
# Fig. 2c: Level 3
55+
j = 3
56+
GraphSig_Plot(Glevel(G,GP,j), linewidth = 1., markersize = 4.,
57+
markercolor = :viridis, markerstrokealpha =0., notitle = true, nocolorbar = true)
58+
plot!(showaxis = false, ticks = false)
59+
savefig("toronto_j3.pdf")
60+
savefig("toronto_j3.png")
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Script to generate figures in Figure 4.
2+
using Plots, SparseArrays, JLD2, LinearAlgebra, MultiscaleGraphSignalTransforms
3+
4+
# Set up the resolution and display size
5+
gr(dpi=200, size=(800,600))
6+
7+
# Load the Toronto street network (vehicular volume counts as its graph signal)
8+
JLD2.@load "Toronto_new.jld2"
9+
tmp1 = toronto["G"]
10+
G=GraphSig(tmp1["W"],xy=tmp1["xy"],f=tmp1["f"],name =tmp1["name"],
11+
plotspecs = tmp1["plotspecs"])
12+
13+
# Assign correct edge weights via 1/Euclidean distance
14+
G = Adj2InvEuc(G)
15+
# Perform the hierarchical graph partitioning using the Fiedler vectors
16+
GP = partition_tree_fiedler(G) # Lrw by default
17+
# Compute the expansion coefficients of the full GHWT c2f dictionary
18+
dmatrix = ghwt_analysis!(G, GP=GP)
19+
N = length(G.f)
20+
21+
# Fig. 4a: Sacling vector ψ^1_{0,0}, i.e., (j,k,l)=(1,0,0).
22+
j = 1
23+
loc = 1
24+
BS = bs_level(GP, j)
25+
dvec = zeros(N, 1)
26+
dvec[loc,1] = 1.0
27+
(f, GS) = ghwt_synthesis(dvec, GP, BS, G)
28+
GraphSig_Plot(GS, linewidth = 1., markersize = 4., markerstrokealpha = 0.,
29+
markercolor = :viridis, notitle = true, nocolorbar = true, clim = (-0.01, 0.01))
30+
plot!(showaxis = false, ticks = false)
31+
k, l = BS.levlist[loc][1], BS.levlist[loc][2]
32+
print(j," ",(rs_to_region(GP.rs, GP.tag))[k,l]," ",GP.tag[k,l])
33+
savefig("toronto_psi100.pdf")
34+
savefig("toronto_psi100.png")
35+
36+
# Fig. 4b: Haar vector ψ^2_{0,1}, i.e., (j,k,l)=(2,0,1).
37+
j = 2
38+
loc = 2
39+
BS = bs_level(GP, j)
40+
dvec = zeros(N, 1)
41+
dvec[loc,1] = 1.0
42+
(f, GS) = ghwt_synthesis(dvec, GP, BS, G)
43+
GraphSig_Plot(GS, linewidth = 1., markersize = 4., markerstrokealpha = 0.,
44+
markercolor = :viridis, notitle = true, nocolorbar = true, clim = (-0.01, 0.01))
45+
plot!(showaxis = false, ticks = false)
46+
k, l = BS.levlist[loc][1], BS.levlist[loc][2]
47+
print(j," ",(rs_to_region(GP.rs, GP.tag))[k,l]," ",GP.tag[k,l])
48+
savefig("toronto_psi201.pdf")
49+
savefig("toronto_psi201.png")
50+
51+
# Fig. 4c: Walsh vector ψ^3_{0,9}, i.e., (j,k,l)=(3,0,9).
52+
#j = 5
53+
#loc = 1000
54+
j = 3
55+
loc = 10
56+
BS = bs_level(GP, j)
57+
dvec = zeros(N, 1)
58+
dvec[loc,1] = 1
59+
(f, GS) = ghwt_synthesis(dvec, GP, BS, G)
60+
GraphSig_Plot(GS, linewidth = 1., markersize = 4., markerstrokealpha = 0.,
61+
markercolor = :viridis, notitle = true, nocolorbar = true, clim = (-0.01, 0.01))
62+
plot!(showaxis = false, ticks = false)
63+
k, l = BS.levlist[loc][1], BS.levlist[loc][2]
64+
print(j," ",(rs_to_region(GP.rs, GP.tag))[k,l]," ",GP.tag[k,l])
65+
savefig("toronto_psi309.pdf")
66+
savefig("toronto_psi309.png")
67+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Script to generate Figure 15.
2+
using Plots, SparseArrays, JLD2, LinearAlgebra, Wavelets, MultiscaleGraphSignalTransforms
3+
include("auxilaries.jl")
4+
include("../../../src/unbalanced_haar_image.jl")
5+
6+
# Set up the resolution and display size
7+
gr(dpi=200, size=(800,600))
8+
9+
# Load the Barbara image data
10+
JLD2.@load "barbara.jld2"
11+
12+
# smaller face region of size 100x100
13+
row_zoom = 71:170
14+
col_zoom = 341:440
15+
display(heatmap(barbara[row_zoom, col_zoom],ratio=1, yaxis =:flip,
16+
showaxis = false, ticks = false, color = :grays, clims = (0,1)))
17+
18+
# Extract that portion of the image
19+
matrix = deepcopy(barbara[row_zoom, col_zoom])
20+
21+
#
22+
# Perform the image partition using the penalized total variation and then
23+
# compute the expansion coefficients
24+
#
25+
p = 3.0
26+
maxlev = 9 # need this to reach the single node leaves
27+
GPcols = PartitionTreeMatrix_unbalanced_haar_binarytree(matrix, maxlev, p)
28+
maxlev = 8 # need this to reach the single node leaves
29+
GProws = PartitionTreeMatrix_unbalanced_haar_binarytree(copy(matrix'), maxlev, p)
30+
# copy() is necessary to switch the Adjoint type to a regular Matrix{Float64}.
31+
dmatrix = ghwt_analysis_2d(matrix, GProws, GPcols)
32+
33+
#
34+
# Compute the graph Haar coefficients from the previous PTV partition tree
35+
#
36+
BS_haar_rows = bs_haar(GProws)
37+
BS_haar_cols = bs_haar(GPcols)
38+
dvec_haar, loc_haar = BS2loc(dmatrix, GProws, GPcols, BS_haar_rows, BS_haar_cols)
39+
40+
#
41+
# Compute the eGHWT best basis
42+
#
43+
dvec_eghwt, loc_eghwt = eghwt_bestbasis_2d(matrix, GProws, GPcols)
44+
45+
#
46+
# Classical Haar transform via Wavelets.jl with direct input
47+
#
48+
dvec_classichaar = dwt(matrix, wavelet(WT.haar))
49+
50+
#
51+
# Classical Haar transform via Wavelets.jl via putting in the dyadic image
52+
#
53+
matrix2 = zeros(128,128)
54+
matrix2[15:114,15:114] = deepcopy(matrix)
55+
dvec_classichaar2 = dwt(matrix2, wavelet(WT.haar))
56+
57+
#
58+
# Classical Haar transform via Wavelets.jl via putting in the dyadic image
59+
#
60+
matrix3 = zeros(128,128)
61+
matrix3[1:100,1:100] = deepcopy(matrix)
62+
matrix3[101:end,1:100] = deepcopy(matrix[end:-1:end-27,1:100])
63+
matrix3[:,101:end] = matrix3[:,100:-1:73]
64+
dvec_classichaar3 = dwt(matrix3, wavelet(WT.haar))
65+
66+
# Figure 15 (Approximation error plot up to the top 5000 coefficients)
67+
DVEC = [ dvec_classichaar[:], dvec_classichaar2[:], dvec_classichaar3[:],
68+
dvec_haar[:], dvec_eghwt[:] ]
69+
T = [ "Classic Haar (direct)", "Classic Haar (zero pad)",
70+
"Classic Haar (even refl)", "Graph Haar (PTV cost)", "eGHWT (PTV cost)" ]
71+
L = [ (:dashdot, :orange), (:dashdot, :red), (:dashdot, :green),
72+
(:solid, :blue), (:solid, :black) ]
73+
approx_error3(DVEC, T, L, 5000)
74+
savefig("barbara_face100_nondyadic_haar_error.pdf")
75+
savefig("barbara_face100_nondyadic_haar_error.png")

0 commit comments

Comments
 (0)