File size: 2,517 Bytes
177308a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""
The two static graphs G that the paper draws, transcribed from the vector
(SVG/tikz) node coordinates and arrow paths of the arXiv HTML (2606.05689v1),
not guessed.  Each transcription is cross-checked against statements the paper
makes about the same figure in prose.

Figure 1(a):  X1 -> X2 -> S,  X3 -> S              (d = 3)
   paper's check: "the d-separation X1 _||_ X3 | X2, S in G" must hold, and
   X2 _||/|_ X3 | S must fail (the collider at S).
Figure 2:     X1 -> X4, X1 -> X5, X1 -> S,
              X2 -> X3, X3 -> X5, X3 -> S, X4 -> X5   (d = 5)
   paper's checks: an_G(S)\\{S} = {X1,X2,X3}   (Figure 3 caption)
                   {X1,X3,X4} = pa_G(X5), X5 not in an_G(S)  (Figure 3 caption)
"""
from evosel import DG, SEL, dsep, clique_augmented, cpdag, multidomain_augmented

FIG1 = DG([0, 1, 2, SEL], [(0, 1), (1, SEL), (2, SEL)])
FIG2 = DG([0, 1, 2, 3, 4, SEL],
          [(0, 3), (0, 4), (0, SEL), (1, 2), (2, 4), (2, SEL), (3, 4)])


def checks():
    out = {}
    # ---- Figure 1(a)
    out['fig1_X1_indep_X3_given_X2_S'] = dsep(FIG1, [0], [2], [1, SEL])
    out['fig1_X2_dconnected_X3_given_S'] = not dsep(FIG1, [1], [2], [SEL])
    out['fig1_anS'] = sorted(str(v) for v in FIG1.ancestors([SEL]) - {SEL})
    # ---- Figure 2
    out['fig2_anS'] = sorted(FIG2.ancestors([SEL]) - {SEL})
    out['fig2_pa_X5'] = sorted(v for v in FIG2.pa[4])
    out['fig2_X5_in_anS'] = 4 in FIG2.ancestors([SEL])
    # ---- Figure 3 (left): G^+ of Figure 2
    gp = clique_augmented(FIG2, 5)
    out['fig3_left_Gplus_edges'] = sorted((int(u), int(v)) for u, v in gp.edges())
    # ---- Figure 3 (right): CPDAG of G^+
    dd, uu = cpdag(gp)
    out['fig3_right_oriented'] = sorted((int(u), int(v)) for u, v in dd)
    out['fig3_right_unoriented'] = sorted(tuple(sorted(e)) for e in uu)
    # ---- Figure 4: multi-domain, I = {S}
    gpi = multidomain_augmented(FIG2, 5, [SEL])
    out['fig4_left_GplusI_zeta_children'] = sorted(int(v) for v in gpi.ch['zeta'])
    forced = [('zeta', v) for v in gpi.ch['zeta']]
    dd2, uu2 = cpdag(gpi, forced=forced)
    out['fig4_right_oriented_on_X'] = sorted(
        (int(u), int(v)) for (u, v) in dd2 if u != 'zeta' and v != 'zeta')
    out['fig4_right_unoriented_on_X'] = sorted(
        tuple(sorted(e)) for e in uu2 if 'zeta' not in e)
    out['fig4_newly_oriented_vs_fig3'] = sorted(
        set(out['fig4_right_oriented_on_X']) - set(out['fig3_right_oriented']))
    return out


if __name__ == '__main__':
    import json
    print(json.dumps(checks(), indent=1))