new implementation of aggregates, using matrices.
This commit is contained in:
parent
22b17b5856
commit
922424abd0
@ -8,72 +8,81 @@
|
|||||||
|
|
||||||
:- use_module(library(clpbn), [{}/1]).
|
:- use_module(library(clpbn), [{}/1]).
|
||||||
|
|
||||||
:- use_module(library(lists), [last/2]).
|
:- use_module(library(lists),
|
||||||
|
[last/2,
|
||||||
|
sumlist/2,
|
||||||
|
max_list/2,
|
||||||
|
min_list/2
|
||||||
|
]).
|
||||||
|
|
||||||
|
:- use_module(library(matrix),
|
||||||
|
[matrix_new/3,
|
||||||
|
matrix_to_list/2,
|
||||||
|
matrix_set/3]).
|
||||||
|
|
||||||
:- use_module(dists, [get_dist_domain_size/2]).
|
:- use_module(dists, [get_dist_domain_size/2]).
|
||||||
|
|
||||||
cpt_average(Vars, Key, Els0, CPT) :-
|
cpt_average(Vars, Key, Els0, CPT) :-
|
||||||
check_domain(Els0, Els),
|
build_avg_table(Vars, Els0, Key, 1.0, CPT).
|
||||||
length(Els, SDomain),
|
|
||||||
build_avg_table(Vars, Els, SDomain, Els0, Key, 1.0, CPT).
|
|
||||||
|
|
||||||
cpt_average(Vars, Key, Els0, Softness, CPT) :-
|
cpt_average(Vars, Key, Els0, Softness, CPT) :-
|
||||||
check_domain(Els0, Els),
|
build_avg_table(Vars, Els0, Key, Softness, CPT).
|
||||||
length(Els, SDomain),
|
|
||||||
build_avg_table(Vars, Els, SDomain, Els0, Key, Softness, CPT).
|
|
||||||
|
|
||||||
cpt_max(Vars, Key, Els0, CPT) :-
|
cpt_max(Vars, Key, Els0, CPT) :-
|
||||||
check_domain(Els0, Els),
|
build_max_table(Vars, Els0, Els0, Key, 1.0, CPT).
|
||||||
length(Els, SDomain),
|
|
||||||
build_max_table(Vars, Els, SDomain, Els0, Key, CPT).
|
|
||||||
|
|
||||||
cpt_min(Vars, Key, Els0, CPT) :-
|
cpt_min(Vars, Key, Els0, CPT) :-
|
||||||
check_domain(Els0, Els),
|
build_min_table(Vars, Els0, Els0, Key, 1.0, CPT).
|
||||||
length(Els, SDomain),
|
|
||||||
build_min_table(Vars, Els, SDomain, Els0, Key, CPT).
|
|
||||||
|
|
||||||
build_avg_table(Vars, Domain, SDomain, ODomain, _, 1.0, p(ODomain, CPT, Vars)) :-
|
build_avg_table(Vars, Domain, _, Softness, p(Domain, CPT, Vars)) :-
|
||||||
|
length(Domain, SDomain),
|
||||||
int_power(Vars, SDomain, 1, TabSize),
|
int_power(Vars, SDomain, 1, TabSize),
|
||||||
TabSize =< 16,
|
TabSize =< 16,
|
||||||
/* case gmp is not there !! */
|
/* case gmp is not there !! */
|
||||||
TabSize > 0, !,
|
TabSize > 0, !,
|
||||||
average_cpt(Vars, Domain, CPT).
|
average_cpt(Vars, Domain, Softness, CPT).
|
||||||
build_avg_table(Vars, Domain, _, ODomain, Key, Softness, p(ODomain, CPT, [V1,V2])) :-
|
build_avg_table(Vars, Domain, Key, Softness, p(Domain, CPT, [V1,V2])) :-
|
||||||
length(Vars,L),
|
length(Vars,L),
|
||||||
LL1 is L//2,
|
LL1 is L//2,
|
||||||
LL2 is L-LL1,
|
LL2 is L-LL1,
|
||||||
list_split(LL1, Vars, L1, L2),
|
list_split(LL1, Vars, L1, L2),
|
||||||
Domain = [Min|Els1],
|
Min = 0,
|
||||||
last(Els1,Max),
|
length(Domain,Max1), Max is Max1-1,
|
||||||
build_intermediate_table(LL1, sum(Min,Max), L1, V1, Key, Softness, 0, I1),
|
build_intermediate_table(LL1, sum(Min,Max), L1, V1, Key, 1.0, 0, I1),
|
||||||
build_intermediate_table(LL2, sum(Min,Max), L2, V2, Key, Softness, I1, _),
|
build_intermediate_table(LL2, sum(Min,Max), L2, V2, Key, 1.0, I1, _),
|
||||||
normalised_average_cpt(L, [V1,V2], Domain, Softness, CPT).
|
average_cpt([V1,V2], Domain, Softness, CPT).
|
||||||
|
|
||||||
build_max_table(Vars, Domain, SDomain, ODomain, _, p(ODomain, CPT, Vars)) :-
|
build_max_table(Vars, Domain, Softness, p(Domain, CPT, Vars)) :-
|
||||||
|
length(Domain, SDomain),
|
||||||
int_power(Vars, SDomain, 1, TabSize),
|
int_power(Vars, SDomain, 1, TabSize),
|
||||||
TabSize =< 16, !,
|
TabSize =< 16,
|
||||||
max_cpt(Vars, Domain, CPT).
|
/* case gmp is not there !! */
|
||||||
build_max_table(Vars, Domain, _, ODomain, Key, p(ODomain, CPT, [V1,V2])) :-
|
TabSize > 0, !,
|
||||||
|
max_cpt(Vars, Domain, Softness, CPT).
|
||||||
|
build_max_table(Vars, Domain, Softness, p(Domain, CPT, [V1,V2])) :-
|
||||||
length(Vars,L),
|
length(Vars,L),
|
||||||
LL1 is L//2,
|
LL1 is L//2,
|
||||||
LL2 is L-LL1,
|
LL2 is L-LL1,
|
||||||
list_split(LL1, Vars, L1, L2),
|
list_split(LL1, Vars, L1, L2),
|
||||||
build_intermediate_table(LL1, max(Domain,CPT), L1, V1, Key, 1.0, 0, I1),
|
build_intermediate_table(LL1, max(Domain,CPT), L1, V1, Key, 1.0, 0, I1),
|
||||||
build_intermediate_table(LL2, max(Domain,CPT), L2, V2, Key, 1.0, I1, _),
|
build_intermediate_table(LL2, max(Domain,CPT), L2, V2, Key, 1.0, I1, _),
|
||||||
max_cpt([V1,V2], Domain, CPT).
|
max_cpt([V1,V2], Domain, Softness, CPT).
|
||||||
|
|
||||||
build_min_table(Vars, Domain, SDomain, ODomain, _, p(ODomain, CPT, Vars)) :-
|
build_min_table(Vars, Domain, Softness, p(Domain, CPT, Vars)) :-
|
||||||
|
length(Domain, SDomain),
|
||||||
int_power(Vars, SDomain, 1, TabSize),
|
int_power(Vars, SDomain, 1, TabSize),
|
||||||
TabSize =< 16, !,
|
TabSize =< 16,
|
||||||
min_cpt(Vars, Domain, CPT).
|
/* case gmp is not there !! */
|
||||||
build_min_table(Vars, Domain, _, ODomain, Key, p(ODomain, CPT, [V1,V2])) :-
|
TabSize > 0, !,
|
||||||
|
min_cpt(Vars, Domain, Softness, CPT).
|
||||||
|
build_min_table(Vars, Domain, Softness, p(Domain, CPT, [V1,V2])) :-
|
||||||
length(Vars,L),
|
length(Vars,L),
|
||||||
LL1 is L//2,
|
LL1 is L//2,
|
||||||
LL2 is L-LL1,
|
LL2 is L-LL1,
|
||||||
list_split(LL1, Vars, L1, L2),
|
list_split(LL1, Vars, L1, L2),
|
||||||
build_intermediate_table(LL1, min(Domain,CPT), L1, V1, Key, 1.0, 0, I1),
|
build_intermediate_table(LL1, min(Domain,CPT), L1, V1, Key, 1.0, 0, I1),
|
||||||
build_intermediate_table(LL2, min(Domain,CPT), L2, V2, Key, 1.0, I1, _),
|
build_intermediate_table(LL2, min(Domain,CPT), L2, V2, Key, 1.0, I1, _),
|
||||||
min_cpt([V1,V2], Domain, CPT).
|
min_cpt([V1,V2], Domain, Softness, CPT).
|
||||||
|
|
||||||
int_power([], _, TabSize, TabSize).
|
int_power([], _, TabSize, TabSize).
|
||||||
int_power([_|L], X, I0, TabSize) :-
|
int_power([_|L], X, I0, TabSize) :-
|
||||||
@ -116,185 +125,93 @@ list_split(I, [H|L], [H|L1], L2) :-
|
|||||||
I1 is I-1,
|
I1 is I-1,
|
||||||
list_split(I1, L, L1, L2).
|
list_split(I1, L, L1, L2).
|
||||||
|
|
||||||
% allow quick description for a range.
|
|
||||||
check_domain([I0|Is], [I0|Is]) :-
|
|
||||||
integer(I0),
|
|
||||||
check_integer_domain(Is,I0), !.
|
|
||||||
check_domain(D, ND) :-
|
|
||||||
normalise_domain(D, 0, ND).
|
|
||||||
|
|
||||||
check_integer_domain([],_).
|
|
||||||
check_integer_domain([I1|Is],I0) :-
|
|
||||||
I0 < I1,
|
|
||||||
check_integer_domain(Is,I1).
|
|
||||||
|
|
||||||
normalise_domain([], _, []).
|
|
||||||
normalise_domain([_|D], I0, [I0|ND]) :-
|
|
||||||
I is I0+1,
|
|
||||||
normalise_domain(D, I, ND).
|
|
||||||
|
|
||||||
|
|
||||||
%
|
%
|
||||||
% generate actual table, instead of trusting the solver
|
% generate actual table, instead of trusting the solver
|
||||||
%
|
%
|
||||||
|
|
||||||
average_cpt(Vs,Vals,CPT) :-
|
average_cpt(Vs,Vals,_,CPT) :-
|
||||||
generate_indices(Vals,Inds,0,Av),
|
get_ds_lengths(Vs,Lengs),
|
||||||
combine_all(Vs, Inds, Cs),
|
sumlist(Lengs, Tot),
|
||||||
length(Vs, Max),
|
length(Vals,SVals),
|
||||||
average_possible_cases(0, Av, Max, Cs, 1.0, CPT).
|
Factor is SVals/Tot,
|
||||||
|
matrix_new(floats,[SVals|Lengs],MCPT),
|
||||||
|
fill_in_average(Lengs,Factor,MCPT),
|
||||||
|
matrix_to_list(MCPT,CPT).
|
||||||
|
|
||||||
sum_cpt(Vs, Vals, Softness, CPT) :-
|
get_ds_lengths([],[]).
|
||||||
length(Vals,Sz),
|
get_ds_lengths([V|Vs],[Sz|Lengs]) :-
|
||||||
combine_all(Vs, Cs),
|
get_vdist_size(V, Sz),
|
||||||
sum_possible_cases(0, Sz, Cs, Softness, CPT).
|
get_ds_lengths(Vs,Lengs).
|
||||||
|
|
||||||
normalised_average_cpt(Max, Vs, Vals, Softness, CPT) :-
|
fill_in_average(Lengs,SVals,MCPT) :-
|
||||||
generate_indices(Vals,_,0,Sz),
|
generate(Lengs, Case),
|
||||||
combine_all(Vs, Cs),
|
average(Case, SVals, Val),
|
||||||
average_possible_cases(0, Sz, Max, Cs, Softness, CPT).
|
matrix_set(MCPT,[Val|Case],1.0),
|
||||||
|
fail.
|
||||||
|
fill_in_average(_,_,_).
|
||||||
|
|
||||||
|
generate([], []).
|
||||||
|
generate([N|Lengs], [C|Case]) :-
|
||||||
|
from(0,N,C),
|
||||||
|
generate(Lengs, Case).
|
||||||
|
|
||||||
|
from(I,_,I).
|
||||||
|
from(I1,M,J) :-
|
||||||
|
I is I1+1,
|
||||||
|
I < M,
|
||||||
|
from(I,M,J).
|
||||||
|
|
||||||
|
average(Case, SVals, Val) :-
|
||||||
|
sumlist(Case, Tot),
|
||||||
|
Val is integer(round(Tot*SVals)).
|
||||||
|
|
||||||
|
|
||||||
generate_indices([],[],Av,Av).
|
sum_cpt(Vs,Vals,_,CPT) :-
|
||||||
generate_indices([_|Ls],[I|Inds],I,Av) :-
|
get_ds_lengths(Vs,Lengs),
|
||||||
I1 is I+1,
|
length(Vals,SVals),
|
||||||
generate_indices(Ls,Inds,I1,Av).
|
matrix_new(floats,[SVals|Lengs],MCPT),
|
||||||
|
fill_in_sum(Lengs,MCPT),
|
||||||
|
matrix_to_list(MCPT,CPT).
|
||||||
|
|
||||||
|
fill_in_sum(Lengs,MCPT) :-
|
||||||
|
generate(Lengs, Case),
|
||||||
|
sumlist(Case, Val),
|
||||||
|
matrix_set(MCPT,[Val|Case],1.0),
|
||||||
|
fail.
|
||||||
|
fill_in_sum(_,_).
|
||||||
|
|
||||||
|
|
||||||
combine_all([], [[]]).
|
max_cpt(Vs,Vals,_,CPT) :-
|
||||||
combine_all([V|LV], Cs) :-
|
get_ds_lengths(Vs,Lengs),
|
||||||
combine_all(LV, Cs0),
|
length(Vals,SVals),
|
||||||
get_vdist_size(V,Sz),
|
matrix_new(floats,[SVals|Lengs],MCPT),
|
||||||
generate_indices(0, Sz, Vals),
|
fill_in_max(Lengs,MCPT),
|
||||||
add_vals(Vals, Cs0, Cs).
|
matrix_to_list(MCPT,CPT).
|
||||||
|
|
||||||
combine_all([], _, [[]]).
|
fill_in_max(Lengs,MCPT) :-
|
||||||
combine_all([_|LV], Vals, Cs) :-
|
generate(Lengs, Case),
|
||||||
combine_all(LV, Vals, Cs0),
|
max_list(Case, Val),
|
||||||
add_vals(Vals, Cs0, Cs).
|
matrix_set(MCPT,[Val|Case],1.0),
|
||||||
|
fail.
|
||||||
generate_indices(Sz,Sz,[]) :- !.
|
fill_in_max(_,_).
|
||||||
generate_indices(I0,Sz,[I0|Vals]) :-
|
|
||||||
I is I0+1,
|
|
||||||
generate_indices(I,Sz,Vals).
|
|
||||||
|
|
||||||
|
|
||||||
add_vals([], _, []).
|
min_cpt(Vs,Vals,_,CPT) :-
|
||||||
add_vals([V|Vs], Cs0, Csf) :-
|
get_ds_lengths(Vs,Lengs),
|
||||||
add_vals(Vs, Cs0, Cs),
|
length(Vals,SVals),
|
||||||
add_val_to_cases(Cs0, V, Cs, Csf).
|
matrix_new(floats,[SVals|Lengs],MCPT),
|
||||||
|
fill_in_max(Lengs,MCPT),
|
||||||
|
matrix_to_list(MCPT,CPT).
|
||||||
|
|
||||||
add_val_to_cases([], _, Cs, Cs).
|
fill_in_min(Lengs,MCPT) :-
|
||||||
add_val_to_cases([C|Cs], V, Cs0, [[V|C]|Csf]) :-
|
generate(Lengs, Case),
|
||||||
add_val_to_cases(Cs, V, Cs0, Csf).
|
max_list(Case, Val),
|
||||||
|
matrix_set(MCPT,[Val|Case],1.0),
|
||||||
|
fail.
|
||||||
|
fill_in_min(_,_).
|
||||||
|
|
||||||
sum_all([],N,N).
|
|
||||||
sum_all([C|Cs],N0,N) :-
|
|
||||||
X is C+N0,
|
|
||||||
sum_all(Cs,X,N).
|
|
||||||
|
|
||||||
average_possible_cases(Av,Av,_,_,_,[]) :- !.
|
|
||||||
average_possible_cases(I,Av,Max,Cs,Softness,Lf) :-
|
|
||||||
average_cases2(Cs,I,Av,Softness,Lf,L0),
|
|
||||||
I1 is I+1,
|
|
||||||
average_possible_cases(I1,Av,Max,Cs,Softness,L0).
|
|
||||||
|
|
||||||
average_cases2([], _, _, _, L, L).
|
|
||||||
average_cases2([C|Cs], I, Av, Softness, [P|Lf], L0) :-
|
|
||||||
calculate_avg_prob(C, I, Av, Softness, P),
|
|
||||||
average_cases2(Cs, I, Av, Softness, Lf, L0).
|
|
||||||
|
|
||||||
calculate_avg_prob(C, I, Av, Softness, Softness) :-
|
|
||||||
sum_all(C,0,N),
|
|
||||||
I =:= integer(round(N/Av)), !.
|
|
||||||
calculate_avg_prob(_, _, Av, Softness, Comp) :-
|
|
||||||
Comp is (1.0-Softness)/(Av-1).
|
|
||||||
|
|
||||||
sum_possible_cases(Av,Av,_, _, []) :- !.
|
|
||||||
sum_possible_cases(I,Av,Cs,Softness, Lf) :-
|
|
||||||
sum_cases2(Cs,I, Av, Softness, Lf,L0),
|
|
||||||
I1 is I+1,
|
|
||||||
sum_possible_cases(I1,Av,Cs,Softness, L0).
|
|
||||||
|
|
||||||
sum_cases2([], _, _, _, L, L).
|
|
||||||
sum_cases2([C|Cs], I, Av, Softness, [P|Lf], L0) :-
|
|
||||||
calculate_sum_prob(C, I, Av, Softness, P),
|
|
||||||
sum_cases2(Cs, I, Av, Softness, Lf, L0).
|
|
||||||
|
|
||||||
calculate_sum_prob(C, I, _, Softness, Softness) :-
|
|
||||||
sum_all(C,0,N),
|
|
||||||
I =:= N, !.
|
|
||||||
calculate_sum_prob(_, _, Av, Softness, Comp) :-
|
|
||||||
Comp is (1.0-Softness)/(Av-1).
|
|
||||||
|
|
||||||
%
|
|
||||||
% generate a CPT for max.
|
|
||||||
%
|
|
||||||
max_cpt(Vs, Domain, CPT) :-
|
|
||||||
combinations(Vs, Domain, Combinations),
|
|
||||||
cpt_from_domain(Domain, Combinations, Domain, max, CPT).
|
|
||||||
|
|
||||||
min_cpt(Vs, Domain, CPT) :-
|
|
||||||
combinations(Vs, Domain, Combinations),
|
|
||||||
cpt_from_domain(Domain, Combinations, Domain, min, CPT).
|
|
||||||
|
|
||||||
combinations(Vs, Domain, Combinations) :-
|
|
||||||
mult_domains(Vs, Domain, Domains),
|
|
||||||
cart(Domains, Combinations).
|
|
||||||
|
|
||||||
mult_domains([], _, []).
|
|
||||||
mult_domains([_|Vs], Domain, [Domain|Domains]) :-
|
|
||||||
mult_domains(Vs, Domain, Domains).
|
|
||||||
|
|
||||||
cart([], [[]]).
|
|
||||||
cart([L|R], Rf) :-
|
|
||||||
cart(R, R1),
|
|
||||||
add(L, R1, Rf).
|
|
||||||
|
|
||||||
add([], _, []).
|
|
||||||
add([A|R], R1, RsF) :-
|
|
||||||
add_head(R1, A, RsF, Rs0),
|
|
||||||
add(R, R1, Rs0).
|
|
||||||
|
|
||||||
add_head([], _, Rs, Rs).
|
|
||||||
add_head([H|L], A, [[A|H]|Rs], Rs0) :-
|
|
||||||
add_head(L, A, Rs, Rs0).
|
|
||||||
|
|
||||||
cpt_from_domain([], _, _, _, []).
|
|
||||||
cpt_from_domain([El|Domain], Combinations, Domain0, OP, CPT) :-
|
|
||||||
cpt_from_domain_el(Combinations, El, Domain0, OP, CPT, CPT0),
|
|
||||||
cpt_from_domain(Domain, Combinations, Domain0, OP, CPT0).
|
|
||||||
|
|
||||||
cpt_from_domain_el([], _, _, _, CPT, CPT).
|
|
||||||
cpt_from_domain_el([C|Combinations], El, Domain, OP, [P|CPT], CPT0) :-
|
|
||||||
cpt_for_el(C, OP, El, Domain, 0.0, P),
|
|
||||||
cpt_from_domain_el(Combinations, El, Domain, OP, CPT, CPT0).
|
|
||||||
|
|
||||||
cpt_for_el([], _, _, _, P, P).
|
|
||||||
cpt_for_el([El|Cs], MAX, El, Domain, _, P) :- !,
|
|
||||||
cpt_for_el(Cs, MAX, El, Domain, 1.0, P).
|
|
||||||
cpt_for_el([C|_], MAX, El, Domain, _, 0.0) :-
|
|
||||||
op_broken(MAX, C, El, Domain), !.
|
|
||||||
cpt_for_el([_|Cs], MAX, El, Domain, P0, P) :-
|
|
||||||
cpt_for_el(Cs, MAX, El, Domain, P0, P).
|
|
||||||
|
|
||||||
op_broken(max, C, El, Domain) :-
|
|
||||||
lg(Domain, C, El).
|
|
||||||
op_broken(min, C, El, Domain) :-
|
|
||||||
sm(Domain, C, El).
|
|
||||||
|
|
||||||
lg([El|_], _, El) :- !.
|
|
||||||
lg([C|_], C, _) :- !, fail.
|
|
||||||
lg([_|Vs], C, El) :-
|
|
||||||
lg(Vs, C, El).
|
|
||||||
|
|
||||||
sm([El|_], _, El) :- !, fail.
|
|
||||||
sm([V|_], V, _) :- !.
|
|
||||||
sm([_|Vs], C, El) :-
|
|
||||||
sm(Vs, C, El).
|
|
||||||
|
|
||||||
get_vdist_size(V, Sz) :-
|
get_vdist_size(V, Sz) :-
|
||||||
clpbn:get_atts(V, [dist(Dist,_)]),
|
clpbn:get_atts(V, [dist(Dist,_)]),
|
||||||
get_dist_domain_size(Dist, Sz).
|
get_dist_domain_size(Dist, Sz).
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user