compiled-knowledge 4.0.0a20__cp313-cp313-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of compiled-knowledge might be problematic. Click here for more details.
- ck/__init__.py +0 -0
- ck/circuit/__init__.py +17 -0
- ck/circuit/_circuit_cy.c +37520 -0
- ck/circuit/_circuit_cy.cpython-313-x86_64-linux-musl.so +0 -0
- ck/circuit/_circuit_cy.pxd +32 -0
- ck/circuit/_circuit_cy.pyx +768 -0
- ck/circuit/_circuit_py.py +836 -0
- ck/circuit/tmp_const.py +74 -0
- ck/circuit_compiler/__init__.py +2 -0
- ck/circuit_compiler/circuit_compiler.py +26 -0
- ck/circuit_compiler/cython_vm_compiler/__init__.py +1 -0
- ck/circuit_compiler/cython_vm_compiler/_compiler.c +19821 -0
- ck/circuit_compiler/cython_vm_compiler/_compiler.cpython-313-x86_64-linux-musl.so +0 -0
- ck/circuit_compiler/cython_vm_compiler/_compiler.pyx +380 -0
- ck/circuit_compiler/cython_vm_compiler/cython_vm_compiler.py +121 -0
- ck/circuit_compiler/interpret_compiler.py +223 -0
- ck/circuit_compiler/llvm_compiler.py +388 -0
- ck/circuit_compiler/llvm_vm_compiler.py +546 -0
- ck/circuit_compiler/named_circuit_compilers.py +57 -0
- ck/circuit_compiler/support/__init__.py +0 -0
- ck/circuit_compiler/support/circuit_analyser/__init__.py +13 -0
- ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.c +10615 -0
- ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.cpython-313-x86_64-linux-musl.so +0 -0
- ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_cy.pyx +98 -0
- ck/circuit_compiler/support/circuit_analyser/_circuit_analyser_py.py +93 -0
- ck/circuit_compiler/support/input_vars.py +148 -0
- ck/circuit_compiler/support/llvm_ir_function.py +234 -0
- ck/example/__init__.py +53 -0
- ck/example/alarm.py +366 -0
- ck/example/asia.py +28 -0
- ck/example/binary_clique.py +32 -0
- ck/example/bow_tie.py +33 -0
- ck/example/cancer.py +37 -0
- ck/example/chain.py +38 -0
- ck/example/child.py +199 -0
- ck/example/clique.py +33 -0
- ck/example/cnf_pgm.py +39 -0
- ck/example/diamond_square.py +68 -0
- ck/example/earthquake.py +36 -0
- ck/example/empty.py +10 -0
- ck/example/hailfinder.py +539 -0
- ck/example/hepar2.py +628 -0
- ck/example/insurance.py +504 -0
- ck/example/loop.py +40 -0
- ck/example/mildew.py +38161 -0
- ck/example/munin.py +22982 -0
- ck/example/pathfinder.py +53747 -0
- ck/example/rain.py +39 -0
- ck/example/rectangle.py +161 -0
- ck/example/run.py +30 -0
- ck/example/sachs.py +129 -0
- ck/example/sprinkler.py +30 -0
- ck/example/star.py +44 -0
- ck/example/stress.py +64 -0
- ck/example/student.py +43 -0
- ck/example/survey.py +46 -0
- ck/example/triangle_square.py +54 -0
- ck/example/truss.py +49 -0
- ck/in_out/__init__.py +3 -0
- ck/in_out/parse_ace_lmap.py +216 -0
- ck/in_out/parse_ace_nnf.py +322 -0
- ck/in_out/parse_net.py +480 -0
- ck/in_out/parser_utils.py +185 -0
- ck/in_out/pgm_pickle.py +42 -0
- ck/in_out/pgm_python.py +268 -0
- ck/in_out/render_bugs.py +111 -0
- ck/in_out/render_net.py +177 -0
- ck/in_out/render_pomegranate.py +184 -0
- ck/pgm.py +3475 -0
- ck/pgm_circuit/__init__.py +1 -0
- ck/pgm_circuit/marginals_program.py +352 -0
- ck/pgm_circuit/mpe_program.py +237 -0
- ck/pgm_circuit/pgm_circuit.py +79 -0
- ck/pgm_circuit/program_with_slotmap.py +236 -0
- ck/pgm_circuit/slot_map.py +35 -0
- ck/pgm_circuit/support/__init__.py +0 -0
- ck/pgm_circuit/support/compile_circuit.py +83 -0
- ck/pgm_circuit/target_marginals_program.py +103 -0
- ck/pgm_circuit/wmc_program.py +323 -0
- ck/pgm_compiler/__init__.py +2 -0
- ck/pgm_compiler/ace/__init__.py +1 -0
- ck/pgm_compiler/ace/ace.py +299 -0
- ck/pgm_compiler/factor_elimination.py +395 -0
- ck/pgm_compiler/named_pgm_compilers.py +63 -0
- ck/pgm_compiler/pgm_compiler.py +19 -0
- ck/pgm_compiler/recursive_conditioning.py +231 -0
- ck/pgm_compiler/support/__init__.py +0 -0
- ck/pgm_compiler/support/circuit_table/__init__.py +17 -0
- ck/pgm_compiler/support/circuit_table/_circuit_table_cy.c +16393 -0
- ck/pgm_compiler/support/circuit_table/_circuit_table_cy.cpython-313-x86_64-linux-musl.so +0 -0
- ck/pgm_compiler/support/circuit_table/_circuit_table_cy.pyx +332 -0
- ck/pgm_compiler/support/circuit_table/_circuit_table_py.py +304 -0
- ck/pgm_compiler/support/clusters.py +568 -0
- ck/pgm_compiler/support/factor_tables.py +406 -0
- ck/pgm_compiler/support/join_tree.py +332 -0
- ck/pgm_compiler/support/named_compiler_maker.py +43 -0
- ck/pgm_compiler/variable_elimination.py +91 -0
- ck/probability/__init__.py +0 -0
- ck/probability/empirical_probability_space.py +50 -0
- ck/probability/pgm_probability_space.py +32 -0
- ck/probability/probability_space.py +622 -0
- ck/program/__init__.py +3 -0
- ck/program/program.py +137 -0
- ck/program/program_buffer.py +180 -0
- ck/program/raw_program.py +67 -0
- ck/sampling/__init__.py +0 -0
- ck/sampling/forward_sampler.py +211 -0
- ck/sampling/marginals_direct_sampler.py +113 -0
- ck/sampling/sampler.py +62 -0
- ck/sampling/sampler_support.py +232 -0
- ck/sampling/uniform_sampler.py +72 -0
- ck/sampling/wmc_direct_sampler.py +171 -0
- ck/sampling/wmc_gibbs_sampler.py +153 -0
- ck/sampling/wmc_metropolis_sampler.py +165 -0
- ck/sampling/wmc_rejection_sampler.py +115 -0
- ck/utils/__init__.py +0 -0
- ck/utils/iter_extras.py +163 -0
- ck/utils/local_config.py +270 -0
- ck/utils/map_list.py +128 -0
- ck/utils/map_set.py +128 -0
- ck/utils/np_extras.py +51 -0
- ck/utils/random_extras.py +64 -0
- ck/utils/tmp_dir.py +94 -0
- ck_demos/__init__.py +0 -0
- ck_demos/ace/__init__.py +0 -0
- ck_demos/ace/copy_ace_to_ck.py +15 -0
- ck_demos/ace/demo_ace.py +49 -0
- ck_demos/all_demos.py +88 -0
- ck_demos/circuit/__init__.py +0 -0
- ck_demos/circuit/demo_circuit_dump.py +22 -0
- ck_demos/circuit/demo_derivatives.py +43 -0
- ck_demos/circuit_compiler/__init__.py +0 -0
- ck_demos/circuit_compiler/compare_circuit_compilers.py +32 -0
- ck_demos/circuit_compiler/show_llvm_program.py +26 -0
- ck_demos/pgm/__init__.py +0 -0
- ck_demos/pgm/demo_pgm_dump.py +18 -0
- ck_demos/pgm/demo_pgm_dump_stress.py +18 -0
- ck_demos/pgm/demo_pgm_string_rendering.py +15 -0
- ck_demos/pgm/show_examples.py +25 -0
- ck_demos/pgm_compiler/__init__.py +0 -0
- ck_demos/pgm_compiler/compare_pgm_compilers.py +63 -0
- ck_demos/pgm_compiler/demo_compiler_dump.py +60 -0
- ck_demos/pgm_compiler/demo_factor_elimination.py +47 -0
- ck_demos/pgm_compiler/demo_join_tree.py +25 -0
- ck_demos/pgm_compiler/demo_marginals_program.py +53 -0
- ck_demos/pgm_compiler/demo_mpe_program.py +55 -0
- ck_demos/pgm_compiler/demo_pgm_compiler.py +38 -0
- ck_demos/pgm_compiler/demo_recursive_conditioning.py +33 -0
- ck_demos/pgm_compiler/demo_variable_elimination.py +33 -0
- ck_demos/pgm_compiler/demo_wmc_program.py +29 -0
- ck_demos/pgm_compiler/time_fe_compiler.py +93 -0
- ck_demos/pgm_inference/__init__.py +0 -0
- ck_demos/pgm_inference/demo_inferencing_basic.py +188 -0
- ck_demos/pgm_inference/demo_inferencing_mpe_cancer.py +45 -0
- ck_demos/pgm_inference/demo_inferencing_wmc_and_mpe_sprinkler.py +154 -0
- ck_demos/pgm_inference/demo_inferencing_wmc_student.py +110 -0
- ck_demos/programs/__init__.py +0 -0
- ck_demos/programs/demo_program_buffer.py +24 -0
- ck_demos/programs/demo_program_multi.py +24 -0
- ck_demos/programs/demo_program_none.py +19 -0
- ck_demos/programs/demo_program_single.py +23 -0
- ck_demos/programs/demo_raw_program_interpreted.py +21 -0
- ck_demos/programs/demo_raw_program_llvm.py +21 -0
- ck_demos/sampling/__init__.py +0 -0
- ck_demos/sampling/check_sampler.py +71 -0
- ck_demos/sampling/demo_marginal_direct_sampler.py +40 -0
- ck_demos/sampling/demo_uniform_sampler.py +38 -0
- ck_demos/sampling/demo_wmc_direct_sampler.py +40 -0
- ck_demos/utils/__init__.py +0 -0
- ck_demos/utils/compare.py +120 -0
- ck_demos/utils/convert_network.py +45 -0
- ck_demos/utils/sample_model.py +216 -0
- ck_demos/utils/stop_watch.py +384 -0
- compiled_knowledge-4.0.0a20.dist-info/METADATA +50 -0
- compiled_knowledge-4.0.0a20.dist-info/RECORD +178 -0
- compiled_knowledge-4.0.0a20.dist-info/WHEEL +5 -0
- compiled_knowledge-4.0.0a20.dist-info/licenses/LICENSE.txt +21 -0
- compiled_knowledge-4.0.0a20.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from ck import example
|
|
2
|
+
from ck.pgm import RandomVariable, RVMap
|
|
3
|
+
from ck.pgm_circuit import PGMCircuit
|
|
4
|
+
from ck.pgm_circuit.marginals_program import MarginalsProgram
|
|
5
|
+
from ck.pgm_compiler import factor_elimination, PGMCompiler
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
COMPILER: PGMCompiler = factor_elimination.compile_pgm_best_jointree
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
pgm = example.Cancer()
|
|
13
|
+
|
|
14
|
+
print(f'Compiling PGM {pgm.name!r} to a Circuit')
|
|
15
|
+
pgm_cct: PGMCircuit = COMPILER(pgm)
|
|
16
|
+
|
|
17
|
+
print('Getting Marginals Program')
|
|
18
|
+
marginals = MarginalsProgram(pgm_cct)
|
|
19
|
+
|
|
20
|
+
print()
|
|
21
|
+
print('Showing Program results, weighted model count for each instance:')
|
|
22
|
+
for indicators in pgm.instances_as_indicators():
|
|
23
|
+
instance_as_str = pgm.indicator_str(*indicators)
|
|
24
|
+
wmc_value = marginals.wmc(*indicators)
|
|
25
|
+
pgm_value = pgm.value_product_indicators(*indicators)
|
|
26
|
+
print(f' {instance_as_str:75} {wmc_value:.6f} {pgm_value:.6f}')
|
|
27
|
+
|
|
28
|
+
print()
|
|
29
|
+
print('Showing Program results, marginal distribution for each rv:')
|
|
30
|
+
marginals.compute_conditioned()
|
|
31
|
+
for rv in pgm.rvs:
|
|
32
|
+
distribution = marginals.result_for_rv(rv)
|
|
33
|
+
distribution_str = ', '.join(f'{state} = {value:.6f}' for state, value in zip(rv.states, distribution))
|
|
34
|
+
print(f' {(str(rv) + ":"):12} {distribution_str}')
|
|
35
|
+
|
|
36
|
+
print()
|
|
37
|
+
print('Showing Program results, marginal distribution, given cancer = True:')
|
|
38
|
+
|
|
39
|
+
cancer: RandomVariable = RVMap(pgm).cancer
|
|
40
|
+
condition = cancer('True')
|
|
41
|
+
|
|
42
|
+
marginals.compute_conditioned(condition)
|
|
43
|
+
for rv in pgm.rvs:
|
|
44
|
+
distribution = marginals.result_for_rv(rv)
|
|
45
|
+
distribution_str = ', '.join(f'{state} = {value:.6f}' for state, value in zip(rv.states, distribution))
|
|
46
|
+
print(f' {(str(rv) + ":"):12} {distribution_str}')
|
|
47
|
+
|
|
48
|
+
print()
|
|
49
|
+
print('Done.')
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if __name__ == '__main__':
|
|
53
|
+
main()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from ck import example
|
|
2
|
+
from ck.pgm import RVMap, RandomVariable
|
|
3
|
+
from ck.pgm_circuit.mpe_program import MPEProgram, MPEResult
|
|
4
|
+
from ck.pgm_compiler import factor_elimination, PGMCompiler
|
|
5
|
+
from ck.pgm_circuit import PGMCircuit
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
COMPILER: PGMCompiler = factor_elimination.compile_pgm_best_jointree
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main() -> None:
|
|
12
|
+
pgm = example.Cancer()
|
|
13
|
+
|
|
14
|
+
rv_map = RVMap(pgm)
|
|
15
|
+
pollution: RandomVariable = rv_map.pollution
|
|
16
|
+
smoker: RandomVariable = rv_map.smoker
|
|
17
|
+
cancer: RandomVariable = rv_map.cancer
|
|
18
|
+
xray: RandomVariable = rv_map.xray
|
|
19
|
+
dyspnoea: RandomVariable = rv_map.dyspnoea
|
|
20
|
+
|
|
21
|
+
print(f'Compiling PGM {pgm.name!r} to a Circuit')
|
|
22
|
+
pgm_cct: PGMCircuit = COMPILER(pgm)
|
|
23
|
+
|
|
24
|
+
print('Getting MPE Program')
|
|
25
|
+
mpe = MPEProgram(pgm_cct)
|
|
26
|
+
|
|
27
|
+
print()
|
|
28
|
+
print('Showing Program results:')
|
|
29
|
+
|
|
30
|
+
conditions = [
|
|
31
|
+
[],
|
|
32
|
+
[smoker('True')],
|
|
33
|
+
[cancer('True')],
|
|
34
|
+
[pollution('low')],
|
|
35
|
+
[xray('positive')],
|
|
36
|
+
[pollution('high'), dyspnoea('False')],
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
z: float = pgm.value_product_indicators()
|
|
40
|
+
|
|
41
|
+
for condition in conditions:
|
|
42
|
+
result: MPEResult = mpe.mpe(*condition)
|
|
43
|
+
|
|
44
|
+
condition_str = pgm.condition_str(*condition)
|
|
45
|
+
result_str = pgm.instance_str(result.mpe)
|
|
46
|
+
pr = result.wmc / z
|
|
47
|
+
|
|
48
|
+
print(f'MPE[{condition_str}] = {result_str} with pr = {pr}')
|
|
49
|
+
|
|
50
|
+
print()
|
|
51
|
+
print('Done.')
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if __name__ == '__main__':
|
|
55
|
+
main()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from ck.circuit_compiler import llvm_compiler
|
|
2
|
+
from ck import example
|
|
3
|
+
from ck.pgm_compiler import factor_elimination
|
|
4
|
+
from ck.pgm_circuit import PGMCircuit
|
|
5
|
+
from ck.program.program_buffer import ProgramBuffer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
PGM_COMPILER = factor_elimination.compile_pgm_best_jointree
|
|
9
|
+
CCT_COMPILER = llvm_compiler.compile_circuit
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main() -> None:
|
|
13
|
+
pgm = example.Rain()
|
|
14
|
+
|
|
15
|
+
print(f'Compiling PGM {pgm.name!r} to a Circuit')
|
|
16
|
+
pgm_cct: PGMCircuit = PGM_COMPILER(pgm)
|
|
17
|
+
|
|
18
|
+
print('Compiling Circuit to a Program')
|
|
19
|
+
prog = ProgramBuffer(CCT_COMPILER(pgm_cct.circuit_top))
|
|
20
|
+
slot_map = pgm_cct.slot_map
|
|
21
|
+
|
|
22
|
+
print('Showing Program results')
|
|
23
|
+
for indicators in pgm.instances_as_indicators():
|
|
24
|
+
prog[:] = 0
|
|
25
|
+
for ind in indicators:
|
|
26
|
+
prog[slot_map[ind]] = 1
|
|
27
|
+
|
|
28
|
+
instance_as_str = pgm.indicator_str(*indicators)
|
|
29
|
+
program_value = prog.compute().item()
|
|
30
|
+
pgm_value = pgm.value_product_indicators(*indicators)
|
|
31
|
+
print(f' {instance_as_str:75} {program_value:.6f} {pgm_value:.6f}')
|
|
32
|
+
|
|
33
|
+
print()
|
|
34
|
+
print('Done.')
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
if __name__ == '__main__':
|
|
38
|
+
main()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from ck import example
|
|
2
|
+
from ck.pgm import PGM
|
|
3
|
+
from ck.pgm_circuit import PGMCircuit
|
|
4
|
+
from ck.pgm_circuit.wmc_program import WMCProgram
|
|
5
|
+
from ck.pgm_compiler import recursive_conditioning
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
pgm: PGM = example.Rain()
|
|
10
|
+
|
|
11
|
+
pgm_cct: PGMCircuit = recursive_conditioning.compile_pgm(pgm)
|
|
12
|
+
|
|
13
|
+
print(f'PGM: {pgm.name}')
|
|
14
|
+
print()
|
|
15
|
+
print(f'Circuit:')
|
|
16
|
+
pgm_cct.dump()
|
|
17
|
+
print()
|
|
18
|
+
|
|
19
|
+
wmc = WMCProgram(pgm_cct)
|
|
20
|
+
|
|
21
|
+
print('Showing Program results:')
|
|
22
|
+
for indicators in pgm.instances_as_indicators():
|
|
23
|
+
instance_as_str = pgm.indicator_str(*indicators)
|
|
24
|
+
wmc_value = wmc.wmc(*indicators)
|
|
25
|
+
pgm_value = pgm.value_product_indicators(*indicators)
|
|
26
|
+
print(f' {instance_as_str:80} {wmc_value:.6f} {pgm_value:.6f}')
|
|
27
|
+
|
|
28
|
+
print()
|
|
29
|
+
print('Done.')
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if __name__ == '__main__':
|
|
33
|
+
main()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from ck import example
|
|
2
|
+
from ck.pgm import PGM
|
|
3
|
+
from ck.pgm_circuit import PGMCircuit
|
|
4
|
+
from ck.pgm_circuit.wmc_program import WMCProgram
|
|
5
|
+
from ck.pgm_compiler import variable_elimination
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
pgm: PGM = example.Rain()
|
|
10
|
+
|
|
11
|
+
pgm_cct: PGMCircuit = variable_elimination.compile_pgm(pgm)
|
|
12
|
+
|
|
13
|
+
print(f'PGM: {pgm.name}')
|
|
14
|
+
print()
|
|
15
|
+
print(f'Circuit:')
|
|
16
|
+
pgm_cct.dump()
|
|
17
|
+
print()
|
|
18
|
+
|
|
19
|
+
wmc = WMCProgram(pgm_cct)
|
|
20
|
+
|
|
21
|
+
print('Showing Program results:')
|
|
22
|
+
for indicators in pgm.instances_as_indicators():
|
|
23
|
+
instance_as_str = pgm.indicator_str(*indicators)
|
|
24
|
+
wmc_value = wmc.wmc(*indicators)
|
|
25
|
+
pgm_value = pgm.value_product_indicators(*indicators)
|
|
26
|
+
print(f' {instance_as_str:80} {wmc_value:.6f} {pgm_value:.6f}')
|
|
27
|
+
|
|
28
|
+
print()
|
|
29
|
+
print('Done.')
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if __name__ == '__main__':
|
|
33
|
+
main()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from ck import example
|
|
2
|
+
from ck.pgm_circuit import PGMCircuit
|
|
3
|
+
from ck.pgm_circuit.wmc_program import WMCProgram
|
|
4
|
+
from ck.pgm_compiler import DEFAULT_PGM_COMPILER
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main() -> None:
|
|
8
|
+
pgm = example.Cancer()
|
|
9
|
+
|
|
10
|
+
print(f'Compiling PGM {pgm.name!r} to a Circuit')
|
|
11
|
+
pgm_cct: PGMCircuit = DEFAULT_PGM_COMPILER(pgm)
|
|
12
|
+
|
|
13
|
+
print('Getting WMC Program')
|
|
14
|
+
wmc = WMCProgram(pgm_cct)
|
|
15
|
+
|
|
16
|
+
print()
|
|
17
|
+
print('Showing Program results:')
|
|
18
|
+
for indicators in pgm.instances_as_indicators():
|
|
19
|
+
instance_as_str = pgm.indicator_str(*indicators)
|
|
20
|
+
wmc_value = wmc.wmc(*indicators)
|
|
21
|
+
pgm_value = pgm.value_product_indicators(*indicators)
|
|
22
|
+
print(f' {instance_as_str:75} {wmc_value:.6f} {pgm_value:.6f}')
|
|
23
|
+
|
|
24
|
+
print()
|
|
25
|
+
print('Done.')
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if __name__ == '__main__':
|
|
29
|
+
main()
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
from ck import example
|
|
2
|
+
from ck.circuit import CircuitNode, Circuit
|
|
3
|
+
from ck.circuit_compiler import DEFAULT_CIRCUIT_COMPILER
|
|
4
|
+
from ck.pgm import PGM
|
|
5
|
+
from ck.pgm_circuit import PGMCircuit
|
|
6
|
+
from ck.pgm_compiler.factor_elimination import DEFAULT_PRODUCT_SEARCH_LIMIT, _circuit_tables_from_join_tree
|
|
7
|
+
from ck.pgm_compiler.support.circuit_table import CircuitTable
|
|
8
|
+
from ck.pgm_compiler.support.clusters import min_degree, Clusters
|
|
9
|
+
from ck.pgm_compiler.support.factor_tables import FactorTables, make_factor_tables
|
|
10
|
+
from ck.pgm_compiler.support.join_tree import JoinTree, clusters_to_join_tree
|
|
11
|
+
from ck.program import ProgramBuffer, RawProgram
|
|
12
|
+
from ck_demos.utils.stop_watch import timer
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def main() -> None:
|
|
16
|
+
"""
|
|
17
|
+
Time components of the compilation chain for factor elimination.
|
|
18
|
+
|
|
19
|
+
Process:
|
|
20
|
+
example -> PGM
|
|
21
|
+
min_degree -> Clusters
|
|
22
|
+
clusters_to_join_tree -> JoinTree
|
|
23
|
+
join_tree_to_circuit -> PGMCircuit
|
|
24
|
+
default circuit compiler -> RawProgram
|
|
25
|
+
execute program
|
|
26
|
+
"""
|
|
27
|
+
with timer('make PGM') as make_pgm_time:
|
|
28
|
+
pgm: PGM = example.Mildew()
|
|
29
|
+
|
|
30
|
+
with timer('make clusters') as make_clusters_time:
|
|
31
|
+
clusters: Clusters = min_degree(pgm)
|
|
32
|
+
|
|
33
|
+
with timer('make join tree') as make_join_tree_time:
|
|
34
|
+
join_tree: JoinTree = clusters_to_join_tree(clusters)
|
|
35
|
+
|
|
36
|
+
with timer('make factor tables') as make_factor_tables_time:
|
|
37
|
+
factor_tables: FactorTables = make_factor_tables(
|
|
38
|
+
pgm=pgm,
|
|
39
|
+
const_parameters=True,
|
|
40
|
+
multiply_indicators=True,
|
|
41
|
+
pre_prune_factor_tables=False,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
with timer('make circuit tables') as make_circuit_tables_time:
|
|
45
|
+
top_table: CircuitTable = _circuit_tables_from_join_tree(
|
|
46
|
+
factor_tables,
|
|
47
|
+
join_tree,
|
|
48
|
+
DEFAULT_PRODUCT_SEARCH_LIMIT,
|
|
49
|
+
)
|
|
50
|
+
top: CircuitNode = top_table.top()
|
|
51
|
+
circuit: Circuit = top.circuit
|
|
52
|
+
|
|
53
|
+
orig_size = circuit.number_of_op_nodes
|
|
54
|
+
with timer('remove unreachable nodes') as remove_unreachable_time:
|
|
55
|
+
circuit.remove_unreachable_op_nodes(top)
|
|
56
|
+
print(f' saving {orig_size - circuit.number_of_op_nodes:10,}')
|
|
57
|
+
print(f' leaving {circuit.number_of_op_nodes:10,}')
|
|
58
|
+
|
|
59
|
+
with timer('make PGMCircuit') as make_pgm_time:
|
|
60
|
+
pgm_circuit = PGMCircuit(
|
|
61
|
+
rvs=tuple(pgm.rvs),
|
|
62
|
+
conditions=(),
|
|
63
|
+
circuit_top=top,
|
|
64
|
+
number_of_indicators=factor_tables.number_of_indicators,
|
|
65
|
+
number_of_parameters=factor_tables.number_of_parameters,
|
|
66
|
+
slot_map=factor_tables.slot_map,
|
|
67
|
+
parameter_values=factor_tables.parameter_values,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
with timer('make program') as make_program_time:
|
|
71
|
+
program: RawProgram = DEFAULT_CIRCUIT_COMPILER(pgm_circuit.circuit_top)
|
|
72
|
+
|
|
73
|
+
program_buffer = ProgramBuffer(program)
|
|
74
|
+
with timer('execute program') as execute_program_time:
|
|
75
|
+
program_buffer.compute()
|
|
76
|
+
|
|
77
|
+
print()
|
|
78
|
+
print(f'make PGM {make_pgm_time.seconds():5.2f}')
|
|
79
|
+
print(f'make clusters {make_clusters_time.seconds():5.2f}')
|
|
80
|
+
print(f'make join_tree {make_join_tree_time.seconds():5.2f}')
|
|
81
|
+
print(f'make factor tables {make_factor_tables_time.seconds():5.2f}')
|
|
82
|
+
print(f'make circuit tables {make_circuit_tables_time.seconds():5.2f}')
|
|
83
|
+
print(f'remove unreachables {remove_unreachable_time.seconds():5.2f}')
|
|
84
|
+
print(f'make PGM circuit {make_pgm_time.seconds():5.2f}')
|
|
85
|
+
print(f'make program {make_program_time.seconds():5.2f}')
|
|
86
|
+
print(f'execute program {execute_program_time.seconds():5.2f}')
|
|
87
|
+
|
|
88
|
+
print()
|
|
89
|
+
print('Done.')
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == '__main__':
|
|
93
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Demo script to show the foundational processes PGM compilation
|
|
3
|
+
and inference.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from ck.pgm import PGM
|
|
7
|
+
from ck.pgm_circuit import PGMCircuit
|
|
8
|
+
from ck.pgm_circuit.support.compile_circuit import DEFAULT_CIRCUIT_COMPILER
|
|
9
|
+
from ck.pgm_circuit.wmc_program import WMCProgram
|
|
10
|
+
from ck.pgm_compiler import DEFAULT_PGM_COMPILER
|
|
11
|
+
from ck.program import RawProgram, ProgramBuffer
|
|
12
|
+
|
|
13
|
+
pgm = PGM()
|
|
14
|
+
|
|
15
|
+
# =============================================================
|
|
16
|
+
# Define PGM random variables
|
|
17
|
+
# =============================================================
|
|
18
|
+
A = pgm.new_rv('A', 2)
|
|
19
|
+
B = pgm.new_rv('B', 2)
|
|
20
|
+
C = pgm.new_rv('C', 2)
|
|
21
|
+
D = pgm.new_rv('D', 3)
|
|
22
|
+
|
|
23
|
+
# =============================================================
|
|
24
|
+
# Show the possible worlds
|
|
25
|
+
# =============================================================
|
|
26
|
+
print()
|
|
27
|
+
print("The PGM worlds...")
|
|
28
|
+
print(tuple(str(rv) for rv in pgm.rvs))
|
|
29
|
+
for world in pgm.instances():
|
|
30
|
+
print(world)
|
|
31
|
+
|
|
32
|
+
# =============================================================
|
|
33
|
+
# Add some PGM factors
|
|
34
|
+
# (configure each factor to have a dense potential function)
|
|
35
|
+
# =============================================================
|
|
36
|
+
factor_AB = pgm.new_factor(A, B)
|
|
37
|
+
factor_BCD = pgm.new_factor(B, C, D)
|
|
38
|
+
factor_B = pgm.new_factor(B)
|
|
39
|
+
|
|
40
|
+
f_AB = factor_AB.set_dense()
|
|
41
|
+
f_BCD = factor_BCD.set_dense()
|
|
42
|
+
f_B = factor_B.set_dense()
|
|
43
|
+
|
|
44
|
+
f_AB[0, 0] = 0.9
|
|
45
|
+
f_AB[1, 0] = 0.8
|
|
46
|
+
f_AB[0, 1] = 0.1
|
|
47
|
+
f_AB[1, 1] = 0.2
|
|
48
|
+
|
|
49
|
+
f_BCD[0, 0, 0] = 0
|
|
50
|
+
f_BCD[1, 0, 0] = 1
|
|
51
|
+
f_BCD[0, 1, 0] = 1
|
|
52
|
+
f_BCD[1, 1, 0] = 0
|
|
53
|
+
f_BCD[0, 0, 1] = 1
|
|
54
|
+
f_BCD[1, 0, 1] = 0
|
|
55
|
+
f_BCD[0, 1, 1] = 0
|
|
56
|
+
f_BCD[1, 1, 1] = 1
|
|
57
|
+
f_BCD[0, 0, 2] = 0
|
|
58
|
+
f_BCD[1, 0, 2] = 1
|
|
59
|
+
f_BCD[0, 1, 2] = 1
|
|
60
|
+
f_BCD[1, 1, 2] = 0
|
|
61
|
+
|
|
62
|
+
f_B[0] = 2.3
|
|
63
|
+
f_B[1] = 4.5
|
|
64
|
+
|
|
65
|
+
# =============================================================
|
|
66
|
+
# Show the weight of each possible world
|
|
67
|
+
# =============================================================
|
|
68
|
+
print()
|
|
69
|
+
print('The PGM world factors and weights...')
|
|
70
|
+
z = 0
|
|
71
|
+
print(tuple(str(rv) for rv in pgm.rvs), 'weights...')
|
|
72
|
+
for world in pgm.instances():
|
|
73
|
+
weight = pgm.value_product(world)
|
|
74
|
+
print(world, list(pgm.factor_values(world)), weight)
|
|
75
|
+
z += weight
|
|
76
|
+
print('z =', z)
|
|
77
|
+
|
|
78
|
+
# =============================================================
|
|
79
|
+
# Getting and printing indicators
|
|
80
|
+
# =============================================================
|
|
81
|
+
print()
|
|
82
|
+
|
|
83
|
+
A_is_0 = A[0] # Get the indicator for A=0
|
|
84
|
+
print('Indicator for A = 0:', A_is_0)
|
|
85
|
+
|
|
86
|
+
A_is_0_as_str = pgm.indicator_str(A[0]) # Get the indicator in human-readable form
|
|
87
|
+
print('Indicator string for A = 0:', A_is_0_as_str)
|
|
88
|
+
|
|
89
|
+
print('A possible world:', pgm.indicator_str(A[0], B[1], C[0], D[2]))
|
|
90
|
+
|
|
91
|
+
# =============================================================
|
|
92
|
+
# Convert the PGM into an arithmetic circuit
|
|
93
|
+
# =============================================================
|
|
94
|
+
|
|
95
|
+
pgm_cct: PGMCircuit = DEFAULT_PGM_COMPILER(pgm) # Compiles the PGM into a circuit
|
|
96
|
+
|
|
97
|
+
# Get a reference to the circuit object
|
|
98
|
+
cct = pgm_cct.circuit_top.circuit
|
|
99
|
+
|
|
100
|
+
print()
|
|
101
|
+
print('Dump of the arithmetic circuit')
|
|
102
|
+
cct.dump()
|
|
103
|
+
|
|
104
|
+
# =============================================================
|
|
105
|
+
# Compile the arithmetic circuit into a program
|
|
106
|
+
# =============================================================
|
|
107
|
+
|
|
108
|
+
# Get a reference to the top node of the arithmetic circuit
|
|
109
|
+
cct_top = pgm_cct.circuit_top
|
|
110
|
+
|
|
111
|
+
# Compile the circuit into a program
|
|
112
|
+
raw_program: RawProgram = DEFAULT_CIRCUIT_COMPILER(cct_top)
|
|
113
|
+
program = ProgramBuffer(raw_program)
|
|
114
|
+
|
|
115
|
+
# =============================================================
|
|
116
|
+
# Use the program to compute the partition function, z
|
|
117
|
+
# =============================================================
|
|
118
|
+
|
|
119
|
+
program[:] = 1 # set all input slots to 1
|
|
120
|
+
z = program.compute() # run the program
|
|
121
|
+
|
|
122
|
+
print()
|
|
123
|
+
print('Program computed z =', z)
|
|
124
|
+
|
|
125
|
+
# =============================================================
|
|
126
|
+
# Use the program to compute the weight of A=0,B=1,C=0,D=0
|
|
127
|
+
# =============================================================
|
|
128
|
+
|
|
129
|
+
program[:] = 0 # set all input slots to 0
|
|
130
|
+
program[0] = 1 # A=0
|
|
131
|
+
program[3] = 1 # B=1
|
|
132
|
+
program[4] = 1 # C=0
|
|
133
|
+
program[6] = 1 # D=0
|
|
134
|
+
w = program.compute()
|
|
135
|
+
|
|
136
|
+
print()
|
|
137
|
+
print('Program computed w(A=0, B=1, C=0, D=0) =', w)
|
|
138
|
+
|
|
139
|
+
# =============================================================
|
|
140
|
+
# Use the program to compute the probability of A=0 and B=1
|
|
141
|
+
# =============================================================
|
|
142
|
+
|
|
143
|
+
program[:] = 1 # set all input slots to 1
|
|
144
|
+
program[1] = 0 # exclude A=1
|
|
145
|
+
program[2] = 0 # exclude B=0
|
|
146
|
+
w = program.compute()
|
|
147
|
+
|
|
148
|
+
print()
|
|
149
|
+
print('Program computed P(A=0, B=1) =', (w / z))
|
|
150
|
+
|
|
151
|
+
# =============================================================
|
|
152
|
+
# Using a slot map
|
|
153
|
+
# =============================================================
|
|
154
|
+
|
|
155
|
+
slots = pgm_cct.slot_map # get the slot map
|
|
156
|
+
|
|
157
|
+
program[:] = 1 # set all input slots to 1
|
|
158
|
+
program[slots[B[1]]] = 0 # exclude B=1
|
|
159
|
+
program[slots[C[0]]] = 0 # exclude C=0
|
|
160
|
+
w = program.compute()
|
|
161
|
+
|
|
162
|
+
print()
|
|
163
|
+
print('Program computed P(B=0, C=1) =', (w / z))
|
|
164
|
+
|
|
165
|
+
# =============================================================
|
|
166
|
+
# Using a WMCProgram object with built in slot map
|
|
167
|
+
# =============================================================
|
|
168
|
+
|
|
169
|
+
# Compile the circuit as a WMCProgram object
|
|
170
|
+
wmc = WMCProgram(pgm_cct)
|
|
171
|
+
|
|
172
|
+
wmc[:] = 0 # set all input slots to 0
|
|
173
|
+
wmc[B[1]] = 1 # set B=1 to 1
|
|
174
|
+
wmc[D[2]] = 1 # set C=2 to 1
|
|
175
|
+
wmc[A] = 1 # set all A indicators to 1
|
|
176
|
+
wmc[C] = 1 # set all C indicators to 1
|
|
177
|
+
|
|
178
|
+
print()
|
|
179
|
+
print('Program computed P(B=1, D=2) =', (wmc.compute() / z))
|
|
180
|
+
|
|
181
|
+
# Here is the easy way to do it
|
|
182
|
+
print()
|
|
183
|
+
print('Program computed P(B=0, D=2) =', wmc.probability(B[0], D[2]))
|
|
184
|
+
print('Program computed P(B=1, D=2) =', wmc.probability(B[1], D[2]))
|
|
185
|
+
print('Program computed P(D=2) =', wmc.probability(D[2]))
|
|
186
|
+
|
|
187
|
+
print()
|
|
188
|
+
print('Done.')
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Demonstrate how to do MEP inference on a PGM
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from ck.pgm import PGM
|
|
6
|
+
from ck.pgm_circuit import PGMCircuit
|
|
7
|
+
from ck.pgm_circuit.mpe_program import MPEProgram, MPEResult
|
|
8
|
+
from ck.pgm_compiler import DEFAULT_PGM_COMPILER
|
|
9
|
+
|
|
10
|
+
pgm = PGM()
|
|
11
|
+
pollution = pgm.new_rv('pollution', ('low', 'high'))
|
|
12
|
+
smoker = pgm.new_rv('smoker', ('true', 'false'))
|
|
13
|
+
cancer = pgm.new_rv('cancer', ('true', 'false'))
|
|
14
|
+
xray = pgm.new_rv('xray', ('positive', 'negative'))
|
|
15
|
+
dyspnoea = pgm.new_rv('dyspnoea', ('true', 'false'))
|
|
16
|
+
pgm.new_factor(pollution).set_dense().set_flat(0.9, 0.1)
|
|
17
|
+
pgm.new_factor(smoker).set_dense().set_flat(0.3, 0.7)
|
|
18
|
+
pgm.new_factor(cancer, pollution, smoker).set_dense().set_flat(0.03, 0.001, 0.05, 0.02, 0.97, 0.999, 0.95, 0.98)
|
|
19
|
+
pgm.new_factor(xray, cancer).set_dense().set_flat(0.9, 0.2, 0.1, 0.8)
|
|
20
|
+
pgm.new_factor(dyspnoea, cancer).set_dense().set_flat(0.65, 0.3, 0.35, 0.7)
|
|
21
|
+
|
|
22
|
+
pgm_cct: PGMCircuit = DEFAULT_PGM_COMPILER(pgm)
|
|
23
|
+
mpe = MPEProgram(pgm_cct)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# How we will render an mpe_result
|
|
27
|
+
def mpe_str(_mpe_result: MPEResult) -> str:
|
|
28
|
+
global pgm
|
|
29
|
+
return ', '.join([
|
|
30
|
+
pgm.indicator_str(rv[state])
|
|
31
|
+
for rv, state in zip(mpe.trace_rvs, _mpe_result.mpe)
|
|
32
|
+
])
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# What is the most likely situation (unconditioned MPE)
|
|
36
|
+
mpe_result: MPEResult = mpe.mpe()
|
|
37
|
+
print(mpe_str(mpe_result))
|
|
38
|
+
|
|
39
|
+
# What is the MPE given smoker = true
|
|
40
|
+
mpe_result: MPEResult = mpe.mpe(smoker('true'))
|
|
41
|
+
print(mpe_str(mpe_result))
|
|
42
|
+
|
|
43
|
+
# What is the MPE given pollution = high and xray = negative
|
|
44
|
+
mpe_result: MPEResult = mpe.mpe(pollution('high'), xray('negative'))
|
|
45
|
+
print(mpe_str(mpe_result))
|