Skip to content

Commit

Permalink
Add SamplePSDD tests
Browse files Browse the repository at this point in the history
  • Loading branch information
RenatoGeh committed Jun 23, 2021
1 parent 99c3893 commit f261145
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/ProbabilisticCircuits.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ include("structurelearner/init.jl")
include("structurelearner/heuristics.jl")
include("structurelearner/learner.jl")
include("structurelearner/vtree_learner.jl")
include("structurelearner/sample_psdd.jl")

include("ensembles/ensembles.jl")
include("ensembles/bmc.jl")

include("LoadSave/LoadSave.jl")
@reexport using .LoadSave
Expand Down
8 changes: 7 additions & 1 deletion src/structurelearner/sample_psdd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,17 @@ Samples a PSDD from a BDD `ϕ` and vtree `V` with at most `k` elements in each d
@inline function sample_psdd::Diagram, V::Vtree, k::Integer, D::DataFrame;
opts::SamplingOpts = full, randomize_weights::Bool = false, pseudocount::Real = 1.0,
fact_on_⊤::Bool = false, ⊤_k::Integer = k, p_mr::Real = 0.5, always_compress::Bool = false,
always_merge::Bool = false, merge_branch::Real = 0.0)::StructProbCircuit
always_merge::Bool = false, merge_branch::Real = 0.0, maxiter::Integer = 0)::StructProbCircuit
memo = Dict{Tuple{Vtree, Diagram}, StructSumNode}()
C = sample_psdd_r(ϕ, V, k, Dict{Int32, StructProbLiteralNode}(), randomize_weights, opts,
fact_on_⊤, ⊤_k, p_mr, always_compress, always_merge, memo, merge_branch > 0.0,
merge_branch, false, false)
if maxiter > 0
# Optionally grow the circuit by Strudel.
loss(x) = heuristic_loss(x, D)
C = struct_learn(C; primitives = [split_step], kwargs = Dict(split_step => (loss = loss,)),
maxiter, verbose = false)
end
!randomize_weights && estimate_parameters(C, D; pseudocount)
return C
end
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
BinaryDecisionDiagrams = "cd45f48d-2bff-4983-a793-756749635bd1"
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
Expand Down
39 changes: 39 additions & 0 deletions test/structurelearner/sample_psdd_tests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Test
using ProbabilisticCircuits
using DataFrames
using BinaryDecisionDiagrams
import LogicCircuits: Vtree

@testset "SamplePSDD tests" begin
# Set up a logic constraint ϕ as a BDD and scope size n. Sample m PSDDs.
function case::Diagram, n::Integer; m::Integer = 20, atol::Real = 0)
# All possible valuations (including impossible ones).
M = all_valuations(collect(1:n))
# Get only possible worlds.
W = M[findall(ϕ.(eachrow(M))),:]
# Assign random probabilities for each world in W.
R = rand(1:20, size(W, 1))
# Construct a dataset that maps the distribution of R (world W[i] repeats R[i] times).
D = DataFrame(vcat([repeat(W[i,:], 1, R[i])' for i 1:size(W, 1)]...))
# Learn PSDDs from ϕ and D. Overfit them so that we can use ≈ without Julia complaining.
C = Vector{StructProbCircuit}(undef, m)
Threads.@threads for i 1:m
C[i] = sample_psdd(ϕ, Vtree(n, :random), 16, D; pseudocount = 0.0, maxiter = 100)
end
T = DataFrame(M)
for i 1:m
# Test consistency.
@test (EVI(C[i], T) .> -Inf) == ϕ.(eachrow(M))
# Test probabilities.
evi = exp.(EVI(C[i], T))
@test isapprox(evi[findall(>(0), evi)], (R/sum(R)); atol)
end
end

case((1 2) (3 ¬4) (¬1 5), 5)
case((1 3) (5 ¬2), 5)
case(and(1, 2, 3) and(4, 5), 5)
case(exactly(3, collect(1:5)), 5)
case(atleast(3, collect(1:5)), 5)
case(atmost(3, collect(1:5)), 5)
end

0 comments on commit f261145

Please sign in to comment.