Skip to content

Commit

Permalink
Run KNNGraph tests on LockHeapKNNGraph as well
Browse files Browse the repository at this point in the history
  • Loading branch information
dillondaudert committed Dec 10, 2019
1 parent abd22bd commit 6ab81c9
Showing 1 changed file with 111 additions and 105 deletions.
216 changes: 111 additions & 105 deletions test/knn_graph/heap_graph_tests.jl
Expand Up @@ -4,7 +4,7 @@
small_data_f64 = [rand(5) for _ in 1:50]
small_data_f32 = [rand(Float32, 5) for _ in 1:50]

function is_valid_knn_graph(g::HeapKNNGraph)
function is_valid_knn_graph(g::ApproximateKNNGraph)
for i in eachindex(g.heaps)
heap = g.heaps[i]
# check that all nodes have exactly K outgoing edges
Expand All @@ -26,121 +26,127 @@
end

@testset "Constructor Tests" begin
test_data = [rand(2) for _ in 1:4]
test_metric = Euclidean()
test_inds = Int[4 3 2 1; 2 1 4 3]
test_dsts = Float64[1. 2. 3. 4.; 2. 3. 4. 5.]
g = HeapKNNGraph(test_data, test_metric, test_inds, test_dsts)
@test g isa HeapKNNGraph{Int, Float64, Vector{Vector{Float64}}, Euclidean}
@test is_valid_knn_graph(g)
for GraphT in [HeapKNNGraph, LockHeapKNNGraph]
test_data = [rand(2) for _ in 1:4]
test_metric = Euclidean()
test_inds = Int[4 3 2 1; 2 1 4 3]
test_dsts = Float64[1. 2. 3. 4.; 2. 3. 4. 5.]
g = GraphT(test_data, test_metric, test_inds, test_dsts)
@test g isa GraphT{Int, Float64, Vector{Vector{Float64}}, Euclidean}
@test is_valid_knn_graph(g)

@test_throws ErrorException HeapKNNGraph(test_data, test_metric, test_inds, rand(3, 4))
@test_throws ErrorException GraphT(test_data, test_metric, test_inds, rand(3, 4))

k = 10
n = length(small_data_f64)
g = HeapKNNGraph(small_data_f64, k, Euclidean())
@test g isa HeapKNNGraph{Int, Float64, Vector{Vector{Float64}}}
@test is_valid_knn_graph(g)
k = 10
n = length(small_data_f64)
g = GraphT(small_data_f64, k, Euclidean())
@test g isa GraphT{Int, Float64, Vector{Vector{Float64}}}
@test is_valid_knn_graph(g)
end
end
@testset "LightGraphs interface tests" begin
# test LightGraphs interface methods exist on HeapKNNGraph
for m in (edges, vertices, weights, edgetype, ne, nv, eltype)
@test hasmethod(m, (HeapKNNGraph,))
end
@test hasmethod(has_edge, (HeapKNNGraph, Int, Int))
@test hasmethod(has_edge, (HeapKNNGraph, HeapKNNGraphEdge))
@test hasmethod(has_vertex, (HeapKNNGraph, Int))
@test hasmethod(inneighbors, (HeapKNNGraph, Int))
@test hasmethod(outneighbors, (HeapKNNGraph, Int))
@test hasmethod(add_edge!, (HeapKNNGraph, HeapKNNGraphEdge))
# test LightGraphs interface methods exist on HeapKNNGraph, LockHeapKNNGraph
for GraphT in [HeapKNNGraph, LockHeapKNNGraph]
for m in (edges, vertices, weights, edgetype, ne, nv, eltype)
@test hasmethod(m, (GraphT,))
end
@test hasmethod(has_edge, (GraphT, Int, Int))
@test hasmethod(has_edge, (GraphT, HeapKNNGraphEdge))
@test hasmethod(has_vertex, (GraphT, Int))
@test hasmethod(inneighbors, (GraphT, Int))
@test hasmethod(outneighbors, (GraphT, Int))
@test hasmethod(add_edge!, (GraphT, HeapKNNGraphEdge))

k = 10
n = length(small_data_f64)
g = HeapKNNGraph(small_data_f64, k, Euclidean())
# edges
@test length(collect(edges(g))) == n*k
# vertices
@test length(collect(vertices(g))) == n
# weights
@test size(weights(g)) == (n, n)
@test sum(weights(g) .!= 0) == n*k
# edgetype
@test edgetype(g) <: HeapKNNGraphEdge
# has_edge(g, s, d), has_edge(g, e)
e, _ = iterate(edges(g))
@test has_edge(g, src(e), dst(e))
@test has_edge(g, e)
# has_vertex
@test has_vertex(g, 1)
@test !has_vertex(g, -1)
# ne
@test ne(g) == n*k
# nv
@test nv(g) == n
# outneighbors
@test length(outneighbors(g, 1)) == k
@test sizeof(outneighbors(g, 1)) == sizeof(eltype(g))*k
# inneighbors
@test eltype(inneighbors(g, 1)) == eltype(g)
# add_edge!
# case: fail to add bc it exists
@test !(add_edge!(g, e))
# case: fail to add edge bc it exists with a different weight
e2 = HeapKNNGraphEdge(src(e), dst(e), rand(), flag(e))
@test !(add_edge!(g, e2))
# find two nodes without an edge
function absent_edge(graph)
# return the index to an edge that isn't in graph
w = weights(graph)
for i in eachindex(w)
w[i] == 0 && i[1] != i[2] && return i
k = 10
n = length(small_data_f64)
g = GraphT(small_data_f64, k, Euclidean())
# edges
@test length(collect(edges(g))) == n*k
# vertices
@test length(collect(vertices(g))) == n
# weights
@test size(weights(g)) == (n, n)
@test sum(weights(g) .!= 0) == n*k
# edgetype
@test edgetype(g) <: HeapKNNGraphEdge
# has_edge(g, s, d), has_edge(g, e)
e, _ = iterate(edges(g))
@test has_edge(g, src(e), dst(e))
@test has_edge(g, e)
# has_vertex
@test has_vertex(g, 1)
@test !has_vertex(g, -1)
# ne
@test ne(g) == n*k
# nv
@test nv(g) == n
# outneighbors
@test length(outneighbors(g, 1)) == k
@test sizeof(outneighbors(g, 1)) == sizeof(eltype(g))*k
# inneighbors
@test eltype(inneighbors(g, 1)) == eltype(g)
# add_edge!
# case: fail to add bc it exists
@test !(add_edge!(g, e))
# case: fail to add edge bc it exists with a different weight
e2 = HeapKNNGraphEdge(src(e), dst(e), rand(), flag(e))
@test !(add_edge!(g, e2))
# find two nodes without an edge
function absent_edge(graph)
# return the index to an edge that isn't in graph
w = weights(graph)
for i in eachindex(w)
w[i] == 0 && i[1] != i[2] && return i
end
error("Shouldn't get here")
end
error("Shouldn't get here")
ind = absent_edge(g)
# test has_edge and add_edge!
e3 = HeapKNNGraphEdge(ind[2], ind[1], 0.0)
@test !has_edge(g, e3)
@test is_valid_knn_graph(g)
@test add_edge!(g, e3)
@test is_valid_knn_graph(g)
end
ind = absent_edge(g)
# test has_edge and add_edge!
e3 = HeapKNNGraphEdge(ind[2], ind[1], 0.0)
@test !has_edge(g, e3)
@test is_valid_knn_graph(g)
@test add_edge!(g, e3)
@test is_valid_knn_graph(g)
end

@testset "HeapKNNGraph utilities" begin
# knn_diameter
@test hasmethod(knn_diameter, (HeapKNNGraph{Int}, Int))
# knn_matrices
k = 10
n = length(small_data_f64)
g = HeapKNNGraph(small_data_f64, k, Euclidean())
@test hasmethod(knn_matrices, (HeapKNNGraph,))
inds, dists = knn_matrices(g)
@test size(inds) == size(dists) == (k, n)
@test all(issorted(col) for col in eachcol(dists))
for i in 1:size(inds, 2), j_idx in 1:size(inds, 1)
j = inds[j_idx, i]
@test has_edge(g, i, j)
end
# edge_indices, node_edge
@test length(edge_indices(g)) == n*k
for ind in edge_indices(g)
e = node_edge(g, ind[1], ind[2])
@test e isa HeapKNNGraphEdge
@test has_edge(g, e)
end
# node_edges
@test length(node_edges(g, 1)) == k
for e in node_edges(g, 1)
@test src(e) == 1
@test has_edge(g, e)
for GraphT in [HeapKNNGraph, LockHeapKNNGraph]
# knn_diameter
@test hasmethod(knn_diameter, (GraphT{Int}, Int))
# knn_matrices
k = 10
n = length(small_data_f64)
g = GraphT(small_data_f64, k, Euclidean())
@test hasmethod(knn_matrices, (GraphT,))
inds, dists = knn_matrices(g)
@test size(inds) == size(dists) == (k, n)
@test all(issorted(col) for col in eachcol(dists))
for i in 1:size(inds, 2), j_idx in 1:size(inds, 1)
j = inds[j_idx, i]
@test has_edge(g, i, j)
end
# edge_indices, node_edge
@test length(edge_indices(g)) == n*k
for ind in edge_indices(g)
e = node_edge(g, ind[1], ind[2])
@test e isa HeapKNNGraphEdge
@test has_edge(g, e)
end
# node_edges
@test length(node_edges(g, 1)) == k
for e in node_edges(g, 1)
@test src(e) == 1
@test has_edge(g, e)
end
# update_flag!
@test sum((!).(flag).(e for e in edges(g))) == 0 # all true flags
@test flag(node_edge(g, 1, 1))
new_e = update_flag!(g, 1, 1, false)
@test !flag(new_e)
@test new_e === node_edge(g, 1, 1)
@test sum((!).(flag).(e for e in edges(g))) == 1 # one false flag
end
# update_flag!
@test sum((!).(flag).(e for e in edges(g))) == 0 # all true flags
@test flag(node_edge(g, 1, 1))
new_e = update_flag!(g, 1, 1, false)
@test !flag(new_e)
@test new_e === node_edge(g, 1, 1)
@test sum((!).(flag).(e for e in edges(g))) == 1 # one false flag
end

end

0 comments on commit 6ab81c9

Please sign in to comment.