diff --git a/.gitignore b/.gitignore
index 783cd5b..28678a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
*.swp
+.Rproj.user
diff --git a/gui/dags.css b/gui/dags.css
index 8603fd1..912d401 100644
--- a/gui/dags.css
+++ b/gui/dags.css
@@ -175,6 +175,16 @@ form{
margin: 2em;
}
+p.warning {
+ color: #a00;
+ font-weight: bold;
+}
+p.assurance {
+ color: #0a0;
+ font-weight: bold;
+}
+
+
@media screen and (max-width: 40em) {
main{
height: 90%;
diff --git a/gui/dags.html b/gui/dags.html
index 3c2b9ff..c592b05 100644
--- a/gui/dags.html
+++ b/gui/dags.html
@@ -1,10 +1,10 @@
-
+
- DAGitty v3.0
+ DAGitty v3.1
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/test/tests.js b/test/tests.js
deleted file mode 100644
index aaadcc2..0000000
--- a/test/tests.js
+++ /dev/null
@@ -1,1943 +0,0 @@
-GraphParser.VALIDATE_GRAPH_STRUCTURE = true;
-
-var $p = function(s){ return GraphParser.parseGuess(s) }
-var $es = function(g){ return GraphSerializer.toDotEdgeStatements(g) }
-
-
-QUnit.test( "multivariate polynomials", function( assert ) {
- assert.equal(MPoly("0"), "0")
- assert.equal(MPoly("1"), "1")
- assert.equal(MPoly("2"), "2")
- assert.equal(MPoly("-1"), "-1")
- assert.equal(MPoly("-2"), "-2")
- assert.equal(MPoly("1.234E8"), "123400000")
- assert.equal(MPoly("-1.234e8"), "-123400000")
- assert.equal(MPoly("a"), "a")
- assert.equal(MPoly("b"), "b")
- assert.equal(MPoly("abc123"), "abc123")
- assert.equal(MPoly("x"), "x")
- assert.equal(MPoly("x^2"), "x^2")
- assert.equal(MPoly("x^2 y^3"), "x^2 y^3")
- assert.equal(MPoly("y^3 x^2"), "x^2 y^3")
- assert.equal(MPoly("x x"), "x^2")
- assert.equal(MPoly("x x * x * x"), "x^4")
- assert.equal(MPoly("y x^2"), "x^2 y")
- assert.equal(MPoly("y x^2 z"), "x^2 y z")
- assert.equal(MPoly("3x"), "3 x")
- assert.equal(MPoly(" 3 x"), "3 x")
- assert.equal(MPoly(" 3e2 x"), "300 x")
- assert.equal(MPoly(" 3e2 * x"), "300 x")
- assert.equal(MPoly(" 3e2 x y"), "300 x y")
- assert.equal(MPoly(" 3e2 x^5 y^6"), "300 x^5 y^6")
- assert.equal(MPoly("-x^2"), "-x^2")
- assert.equal(MPoly("- x^2"), "-x^2")
- assert.equal(MPoly("x + y"), "x + y")
- assert.equal(MPoly("x + 2y"), "x + 2 y")
- assert.equal(MPoly("x+2y"), "x + 2 y")
- assert.equal(MPoly("a^2 b^2 + 0x"), "a^2 b^2")
- assert.equal(MPoly("a^2 b^2 + 123x"), "a^2 b^2 + 123 x")
- assert.equal(MPoly("-2y"), "-2 y")
- assert.equal(MPoly("x-2y"), "x - 2 y")
- assert.equal(MPoly("x^4-2y^5"), "x^4 - 2 y^5")
- assert.equal(MPoly("x^4-2y^5-z^7"), "x^4 - 2 y^5 - z^7")
- assert.equal(MPoly("xy + abc123"), "abc123 + xy")
- assert.equal(MPoly("xy*abc*def"), "abc def xy")
-
- assert.equal(MPoly("x").negate(), "-x")
- assert.equal(MPoly("x+y").negate(), "-x - y")
- assert.equal(MPoly("x + 4 y").negate(), "-x - 4 y")
-
- assert.equal(MPoly("x").add(MPoly("y")), "x + y")
- assert.equal(MPoly("x + y").add(MPoly("y + z")), "x + 2 y + z")
- assert.equal(MPoly("x + y").add(MPoly("-y + z")), "x + z")
- assert.equal(MPoly("x - y - z").add(MPoly("y - z")), "x - 2 z")
- assert.equal(MPoly("z").add(MPoly("a + x")), "a + x + z")
-
- assert.equal(MPoly.add(), "0")
- assert.equal(MPoly.add(MPoly("x")), "x")
- assert.equal(MPoly.add(MPoly("x"), MPoly("y")), "x + y")
- assert.equal(MPoly.add(MPoly("x"), MPoly("y"), MPoly("x")), "2 x + y")
-
- assert.equal(MPoly("100 y^3").mul(MPoly("217")), "21700 y^3")
- assert.equal(MPoly("100 y^3").mul(MPoly("2 x^100 z^7 zz^8")), "200 x^100 y^3 z^7 zz^8")
- assert.equal(MPoly("100 y^3 zzzz^9").mul(MPoly("2 x^100 y z^7 zz^8")), "200 x^100 y^4 z^7 zz^8 zzzz^9")
- assert.equal(MPoly("x + y").mul(MPoly("z")), "x z + y z")
- assert.equal(MPoly("x + y").mul(MPoly("x y")), "x y^2 + x^2 y")
- assert.equal(MPoly("x + y").mul(MPoly("x + y")), "2 x y + x^2 + y^2")
- assert.equal(MPoly("x + y").mul(MPoly("0 x")), "0")
- assert.equal(MPoly("- x").mul(MPoly("- x")), "x^2")
-
- assert.equal(MPoly("0").isZero(), true)
- assert.equal(MPoly("1").isZero(), false)
- assert.equal(MPoly("x + y + z").isZero(), false)
- assert.equal(MPoly("0 x + 0 y + 0*z").isZero(), true)
-
- assert.equal(MPoly("x+y").sub(MPoly("x")), "y")
- assert.equal(MPoly("x+y").sub(MPoly("y")), "x")
- assert.equal(MPoly("x+y").sub(MPoly("x+y")), "0")
- assert.equal(MPoly("x").sub(MPoly("x")).isZero(), true)
- assert.equal(MPoly("x").sub(MPoly("x + y")).isZero(), false)
-
-
- assert.equal(MPoly("0").eval({"x": MPoly("7")}), "0")
- assert.equal(MPoly("x").eval({"x": MPoly("7")}), "7")
- assert.equal(MPoly("x").eval({"x": MPoly("y")}), "y")
- assert.equal(MPoly("x").eval({"x": MPoly("x + y")}), "x + y")
- assert.equal(MPoly("x^2").eval({"x": MPoly("x + y")}), "2 x y + x^2 + y^2")
- assert.equal(MPoly("x y").eval({"x": MPoly("y")}), "y^2")
- assert.equal(MPoly("x y").eval({"x": MPoly("x + y")}), "x y + y^2")
- assert.equal(MPoly("x^2 y").eval({"x": MPoly("x + y")}), "2 x y^2 + x^2 y + y^3")
- assert.equal(MPoly("x y + z + a").eval({"x": MPoly("y")}), "a + y^2 + z")
- assert.equal(MPoly("x y + z + a").eval({"x": MPoly("x + y")}), "a + x y + y^2 + z")
- assert.equal(MPoly("x^2 y + z + a").eval({"x": MPoly("x + y")}), "a + 2 x y^2 + x^2 y + y^3 + z")
- assert.equal(MPoly("x^2 y + z + a").eval({"x": MPoly("2 x + 10 y")}), "a + 40 x y^2 + 4 x^2 y + 100 y^3 + z")
- assert.equal(MPoly("x^2 y + z + a").eval({"x": MPoly("x + y"), "z": MPoly("3 a^2"), "a": MPoly("b^7")}), "3 a^2 + b^7 + 2 x y^2 + x^2 y + y^3")
- assert.equal(MPoly("x^3").eval({"x": MPoly("x + y")}), "3 x y^2 + 3 x^2 y + x^3 + y^3")
- assert.equal(MPoly("x^3").eval({"x": MPoly("2 x + 10 y")}), "600 x y^2 + 120 x^2 y + 8 x^3 + 1000 y^3")
- assert.equal(MPoly("x^4").eval({"x": MPoly("x + y")}), "4 x y^3 + 6 x^2 y^2 + 4 x^3 y + x^4 + y^4")
- assert.equal(MPoly("x^4").eval({"x": MPoly("2 x + 10 y")}), "8000 x y^3 + 2400 x^2 y^2 + 320 x^3 y + 16 x^4 + 10000 y^4")
-
-
- assert.equal(MPoly("0").evalToNumber({"x": 7}), 0)
- assert.equal(MPoly("123").evalToNumber({"x": 7}), 123)
- assert.equal(MPoly("x").evalToNumber({"x": 7}), 7)
- assert.equal(MPoly("x^2").evalToNumber({"x": 7}), 49)
- assert.equal(MPoly("x y").evalToNumber({"x": 7, "y": 3}), 21)
- assert.equal(MPoly("x y + z + a").evalToNumber({"x": 7, "y": 2, "z": 1000, "a": 200}), 1214)
- assert.equal(MPoly("x^3").evalToNumber({"x": 3}), 27)
- assert.equal(MPoly("x^4").evalToNumber({"x": 3}), 81)
-
- assert.equal(MPoly("0").evalToBigInt({"x": 7n}), 0)
- assert.equal(MPoly("123").evalToBigInt({"x": 7n}), 123)
- assert.equal(MPoly("x").evalToBigInt({"x": 7n}), 7)
- assert.equal(MPoly("x^2").evalToBigInt({"x": 7n}), 49)
- assert.equal(MPoly("x y").evalToBigInt({"x": 7n, "y": 3n}), 21)
- assert.equal(MPoly("x y + z + a").evalToBigInt({"x": 7n, "y": 2n, "z": 1000n, "a": 200n}), 1214)
- assert.equal(MPoly("x^3").evalToBigInt({"x": 3n}), 27)
- assert.equal(MPoly("x^4").evalToBigInt({"x": 3n}), 81)
-})
-
-
-QUnit.test( "graph manipulation", function( assert ) {
-
- var g = $p( "dag G { x <-> x }" )
- assert.equal( g.areAdjacent("x","x"), true )
-
- g = $p( "dag G { x <-> y }" )
- assert.equal( g.areAdjacent("x","y"), true )
- assert.equal( g.areAdjacent("y","x"), true )
- g.changeEdge( g.getEdge("x","y",Graph.Edgetype.Bidirected), Graph.Edgetype.Directed )
- assert.equal( $es( g ), "x -> y" )
- assert.equal( g.areAdjacent("x","y"), true )
- assert.equal( g.areAdjacent("y","x"), true )
-
- g = $p( "digraph G { x -> y }" )
- assert.equal( g.areAdjacent("x","y"), true )
- g.changeEdge( g.getEdge("x","y"), Graph.Edgetype.Undirected )
- assert.equal( $es( g ), "x -- y" )
- assert.equal( g.areAdjacent("x","y"), true )
-
-
- g = $p( "digraph G { x -> y }" )
- assert.equal( g.areAdjacent("x","y"), true )
- g.reverseEdge( g.getEdge("x","y"), Graph.Edgetype.Undirected )
- assert.equal( $es( g ), "y -> x" )
- assert.equal( g.areAdjacent("x","y"), true )
-
-
- g = $p( "digraph G { x -- y }" )
- assert.equal( g.areAdjacent("x","y"), true )
- g.changeEdge( g.getEdge("y","x",Graph.Edgetype.Undirected), Graph.Edgetype.Directed )
- assert.equal( $es( g ), "x -> y" )
- assert.equal( g.areAdjacent("x","y"), true )
-
- g = $p( "digraph G { x -- y }" )
- g.changeEdge( g.getEdge("y","x",Graph.Edgetype.Undirected), Graph.Edgetype.Directed, "y" )
- assert.equal( $es( g ), "y -> x", "edge change" )
-
- g = $p( "digraph G { y <- x <-> m -- y }")
- g.deleteVertex("m")
- assert.equal( $es( g ), "x -> y", "vertex deletion" )
-
-
-} )
-
-QUnit.test( "parsing and serializing", function( assert ) {
- // GraphParser.VALIDATE_GRAPH_STRUCTURE = false;
-
- assert.equal( $p( "dag{{x->{a b}}}" ).edges.length, 2 )
-
- assert.equal( $p( "dag{{x->{a ; b}}}" ).edges.length, 2,
- "semicolons" )
- assert.equal( $p( "dag{a;b}" ).getVertices().length, 2,
- "semicolons 2" )
- assert.equal( $p( "dag{;b}" ).getVertices().length, 1,
- "semicolons 2" )
- assert.equal( $p( "dag{a;}" ).getVertices().length, 1,
- "semicolons 2" )
-
- assert.equal( $p( "dag{}" ).getVertices().length, 0,
- "semicolons 2" )
- assert.equal( $p( "dag{;}" ).getVertices().length, 0,
- "semicolons 2" )
- assert.equal( $p( "dag{;;;}" ).getVertices().length, 0,
- "semicolons 2" )
-
- assert.equal( $p( "dag{a}" ).getVertices().length,
- 1, "spaces" )
- assert.equal( $p( "dag{a }" ).getVertices().length,
- 1, "spaces" )
- assert.equal( $p( "dag{ a }" ).getVertices().length,
- 1, "spaces" )
-
-
- assert.equal( $p( "pag{a @-> {b --@ {c @-@ d} }}" ).edges.length, 6 )
- assert.equal( _.pluck($p( "pag{a @->b<-@c}" ).getVertices(),"id").sort().join(","), "a,b,c" )
- assert.equal( _.pluck($p( "pag{a @->b<-@c @-@d}" ).getVertices(),"id").sort().join(","), "a,b,c,d" )
-
- assert.equal( $p( "dag{x->{a b}}" ).edges.length, 2 )
-
- assert.equal( $p( "dag{x->{a->b}}" ).edges.length, 3 )
-
- assert.equal( $p( "dag{a->{b->{c->{d->e}}}}" ).edges.length, 10 )
-
- assert.equal( GraphSerializer.toDotVertexStatements( $p(
- "digraph G { \"ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ\" }" ) ).trim(),
- "\"ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ\"" )
-
- assert.equal( GraphSerializer.toDotVertexStatements( $p(
- "digraph G { x [label=\"από το Άξιον Εστί\"] }" ) ).trim(),
- "x [label=\"από το Άξιον Εστί\"]" )
-
- assert.equal( GraphSerializer.toDot( $p(
- "digraph G { graph [bb=\"0,0,100,100\"] }" ) ).trim(),
- "digraph G{\nbb=\"0,0,100,100\"\n\n}" )
-
- assert.equal( TestGraphs.small1().oldToString(), "A 1\nS E\nT O\n\nA S\nS T" )
-
- assert.equal((function(){
- var g = $p(
- "digraph G { x <-> y }"
- ).addSource("x").addTarget("y")
- GraphTransformer.activeBiasGraph( g )
- return g.edges[0].directed
- })(), Graph.Edgetype.Bidirected )
-
- assert.equal((function(){
- var g = $p(
- "digraph G { xi1 [latent]\n"+
- "xi1 -> x1\n"+
- "xi1 -> x3\n"+
- "xi1 -> x4\n"+
- "xi1 -> x5\n"+
- "x5 -> x6\n"+
- "x1 -> x6\n"+
- "x6 -> x3 }\n"
- )
- return g.oldToString()
- })(), "x1 1\nx3 1\nx4 1\nx5 1\nx6 1\nxi1 U\n\nx1 x6\nx5 x6\nx6 x3\nxi1 x1 x3 x4 x5" )
-
- assert.equal((function(){
- var g = GraphParser.parseDot(
- "digraph { xi1 [latent]\n"+
- "xi2 [latent]\n"+
- "xi1 <-> xi2\n"+
- "xi1 -> x1\n"+
- "xi1 -> x2\n"+
- "xi1 -> x3\n"+
- "xi2 -> x4\n"+
- "xi2 -> x5\n"+
- "xi2 -> x6 } "
- )
- return g.oldToString()
- })(), "x1 1\nx2 1\nx3 1\nx4 1\nx5 1\nx6 1\nxi1 U\nxi2 U\n\nxi1 x1 x2 x3 xi2\nxi2 x4 x5 x6 xi1" )
-
- assert.equal((function(){
- var g = GraphParser.parseDot( "digraph { x -> y\ny -> z\nx <-> y } " )
- //console.log( g.toString() )
- return $es(g)
- })(), "x -> y\nx <-> y\ny -> z" )
-
-
- assert.equal((function(){
- var g = $p(
- "digraph G {\ny -- x -> y <-> x }" )
- return $es(g)
- })(), "x -- y\nx -> y\nx <-> y" )
-
-
- assert.equal((function(){
- var g = $p(
- "graph G {\nx [ exposure , pos =\" 12. , .13 \"]\ny [outcome]\n}" )
- return GraphSerializer.toDot(g)
- })(), "graph G{\nx [exposure,pos=\"12.000,0.130\"]\ny [outcome]\n\n}\n" )
-
-
- assert.equal((function(){
- var g = $p(
- "graph G { x [exposure] \n y [outcome] }" )
- g.getVertex("x").layout_pos_x = 1.0
- g.getVertex("x").layout_pos_y = 1.0
- return GraphSerializer.toDot(g)
- })(), "graph G{\nx [exposure,pos=\"1.000,1.000\"]\ny [outcome]\n\n}\n" )
-
- assert.equal((function(){
- var g = $p(
- "graph G { x \n y }" )
- return GraphSerializer.toDot(g)
- })(), "graph G{\nx\ny\n\n}\n" )
-
- assert.equal((function(){
- var g = $p(
- "graph G { x [] \n y [] }" )
- return GraphSerializer.toDot(g)
- })(), "graph G{\nx\ny\n\n}\n" )
-
- assert.equal((function(){
- var g = $p(
- "digraph G { x [] \n y [] }" )
- g.addEdge("x","y",Graph.Edgetype.Directed)
- g.addEdge("x","y",Graph.Edgetype.Undirected)
- g.addEdge("x","y",Graph.Edgetype.Bidirected)
- return $es(g)
- })(), "x -- y\nx -> y\nx <-> y" )
-
- assert.equal((function(){
- var g = $p( "digraph G { x <-> m } " )
- return typeof g.getEdge("m","x",2)
- })(), "object" )
-
- assert.equal((function(){
- var g = $p( "digraph G { x <-> m } " )
- return typeof g.getEdge("x","m",2)
- })(), "object" )
-
- assert.equal((function(){
- var g = $p( "digraph G { x -> m } " )
- return $es(g)
- })(), "x -> m" )
-
- assert.equal((function(){
- var g = $p( "dag G { M [pos=\"-0.521,-0.265\"] \n "+
- "X [exposure,pos=\"-1.749,-0.238\"] \n "+
- "Y [outcome,pos=\"1.029,-0.228\"] \n "+
- "M <-> Y [pos=\"0.645,-0.279\"] \n "+
- "X -> Y \n "+
- "X -> M -> Y } " )
- return GraphSerializer.toDot(g)
- })(), "dag G{\nM [pos=\"-0.521,-0.265\"]\n"+
- "X [exposure,pos=\"-1.749,-0.238\"]\n"+
- "Y [outcome,pos=\"1.029,-0.228\"]\n"+
- "M -> Y\n"+
- "M <-> Y [pos=\"0.645,-0.279\"]\n"+
- "X -> M\n"+
- "X -> Y\n}\n" )
-
- assert.equal((function(){
- var g = $p( "dag G { M [pos=\"-0.521,-0.265\"] "+
- "X [exposure,pos=\"-1.749,-0.238\"] "+
- "Y [outcome,pos=\"1.029,-0.228\"] "+
- "M <-> Y [pos=\"0.645,-0.279\"] "+
- "X -> Y "+
- "X -> M -> Y } " )
- return GraphSerializer.toDot(g)
- })(), "dag G{\nM [pos=\"-0.521,-0.265\"]\n"+
- "X [exposure,pos=\"-1.749,-0.238\"]\n"+
- "Y [outcome,pos=\"1.029,-0.228\"]\n"+
- "M -> Y\n"+
- "M <-> Y [pos=\"0.645,-0.279\"]\n"+
- "X -> M\n"+
- "X -> Y\n}\n" )
-
- assert.equal((function(){
- var g = $p(
- "digraph G { x -- y \n x -> y \n x <-> y [pos=\"1.000,1.000\"] }" )
- return $es(g)
- })(), "x -- y\nx -> y\nx <-> y [pos=\"1.000,1.000\"]" )
-
- assert.equal((function(){
- var g = $p(
- "digraph G {\n y -- x -> y <-> x [pos=\"1.0,0.1\"] }" )
- return $es(g)
- })(), "x -- y [pos=\"1.000,0.100\"]\nx -> y [pos=\"1.000,0.100\"]\nx <-> y [pos=\"1.000,0.100\"]" )
-
- assert.equal(GraphSerializer.toLavaan($p("dag{x1}")).split("\n")[1]
- ,"x1 ~~ x1")
-
- assert.equal( $es($p(
- "dag{ U -> {a b c d} }" )), "U -> a\nU -> b\nU -> c\nU -> d" )
-});
-
-QUnit.test( "ancestry", function( assert ) {
- var shrier = TestGraphs.findExample("Shrier")
- assert.equal(
- (_.pluck(shrier.ancestorsOf(
- shrier.getVertex(["PreGameProprioception"])),"id")).sort().join(",")
- , "Coach,FitnessLevel,Genetics,PreGameProprioception" )
-
- assert.equal((function(){
- var g = $p(
- "digraph G {a -- b }" )
- return g.getVertex("a").getNeighbours().length
- })(), 1 )
-
-});
-
-QUnit.test( "separators", function( assert ) {
- var g, gm
- function verts(a) {
- return _.isArray(a) ? a.map(function(vid){return g.getVertex(vid)}) : [g.getVertex(a)]
- }
-
- g = GraphTransformer.backDoorGraph(TestGraphs.small1())
- assert.equal( sep_2_str( GraphAnalyzer.listMinimalSeparators(g) ), "{}" )
- assert.strictEqual( sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g) ] ) , "{}" )
-
- g = GraphTransformer.backDoorGraph(TestGraphs.confounding_triangle())
- gm = GraphTransformer.moralGraph(GraphTransformer.ancestorGraph(g))
- assert.equal( sep_2_str( GraphAnalyzer.listMinimalSeparators(gm) ), "{C}" )
- assert.equal( sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g) ] ), "{C}" )
-
-
- g = GraphTransformer.backDoorGraph(TestGraphs.m_bias_graph())
- gm = GraphTransformer.moralGraph(GraphTransformer.ancestorGraph(g))
- assert.equal( sep_2_str ( GraphAnalyzer.listMinimalSeparators(gm) ), "{}" )
- assert.equal( sep_2_str( [ GraphAnalyzer.findMinimalSeparator(gm) ] ) , "{}" )
-
- g = GraphTransformer.backDoorGraph(TestGraphs.extended_confounding_triangle())
- gm = GraphTransformer.moralGraph(GraphTransformer.ancestorGraph(g))
- assert.equal(sep_2_str( GraphAnalyzer.listMinimalSeparators(gm) ), "{C, D}\n{C, E}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g) ] ) , "{C, D}")
-
- assert.equal(sep_2_str(GraphAnalyzer.listMinimalSeparators( gm, verts(["D"]), [] ) ), "{C, D}" )
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, verts(["D"]), []) ] ) , "{C, D}")
-
- assert.equal(sep_2_str( GraphAnalyzer.listMinimalSeparators(gm, [], [], 1) ), "{C, E}")
- assert.equal(sep_2_str( GraphAnalyzer.listMinimalSeparators(gm, [], verts(["D"])) ), "{C, E}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, [], verts(["D"]) ) ] ) , "{C, E}")
-
- g = $p("digraph {"+
- "D [outcome] "+
- "E [exposure] "+
- "v1 v2 v3 v4 v5 v6 v7 "+
- "D <-> v5 "+
- "E -> v1 "+
- "E -> v6 "+
- "v1 -> D "+
- "v2 -> D "+
- "v2 -> E "+
- "v3 -> E "+
- "v3 <-> v4 "+
- "v4 -> v6 "+
- "v5 -> v4 "+
- "v6 -> v7 "+
- "v7 -> D"+
- "}")
-
- gm = GraphTransformer.moralGraph(GraphTransformer.ancestorGraph(g))
- assert.equal(sep_2_str( GraphAnalyzer.listMinimalSeparators(gm) ), "{v1, v2, v3, v4, v6}\n{v1, v2, v3, v4, v7}\n{v1, v2, v5, v6}\n{v1, v2, v5, v7}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g) ] ), "{v1, v2, v3, v4, v6}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, verts("D"), verts("E")) ] ), "{v1, v2, v5, v7}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, verts("v7")) ] ), "{v1, v2, v3, v4, v7}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, verts("v5")) ] ), "{v1, v2, v5, v6}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, verts(["v5","v7"])) ] ), "{v1, v2, v5, v7}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, [], verts(["v7"])) ] ), "{v1, v2, v3, v4, v6}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, [], verts(["v6"])) ] ), "{v1, v2, v3, v4, v7}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, [], verts(["v4"])) ] ), "{v1, v2, v5, v6}")
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, null, null, [], verts(["v4","v6"])) ] ), "{v1, v2, v5, v7}")
- assert.strictEqual(GraphAnalyzer.findMinimalSeparator(g, null, null, [], verts(["v2"])) , false)
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, verts("v4"), verts("v2")) ]) , "{}" )
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, verts("v4"), verts("v2"), verts("D"), []) ]) , "{D, E, v3, v5, v6}" )
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, verts("v4"), verts("v2"), verts(["D","v7"]), []) ]) , "{D, E, v3, v5, v7}" )
- assert.equal(sep_2_str( [ GraphAnalyzer.findMinimalSeparator(g, verts("v4"), verts("v2"), verts("D"), verts("v6")) ]) , "{D, E, v3, v5, v7}" )
-
- gm.setSources(verts("v4"))
- gm.setTargets(verts("v2"))
- assert.equal(sep_2_str( GraphAnalyzer.listMinimalSeparators(gm, verts("D"), []) ) , "{D, E, v3, v5, v6}\n{D, E, v3, v5, v7}" )
-} );
-
-QUnit.test( "graph analysis", function( assert ) {
- var g = $p("dag{x->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),true)
- g = $p("mag{x->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),false)
- g = $p("mag{z<->x->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),true)
- g = $p("mag{z->x->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),true)
- g = $p("mag{z--x->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),false)
- g = $p("mag{c<->a {a<->b<->x}->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),true)
- g = $p("mag{c->a {a<->b<->x}->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),true)
- g = $p("mag{c->{a b x}->y}")
- assert.equal(GraphAnalyzer.isEdgeVisible(g,g.getEdge("x","y")),true)
-
-
-
-
- g = $p("dag{x->y}")
- assert.equal(GraphAnalyzer.isEdgeStronglyProtected(g,g.getEdge("x","y")),false)
- g = $p("dag{x->y<-z}")
- assert.equal(GraphAnalyzer.isEdgeStronglyProtected(g,g.getEdge("x","y")),true)
- g = $p("dag{x->y<-z->x}")
- assert.equal(GraphAnalyzer.isEdgeStronglyProtected(g,g.getEdge("x","y")),false)
- g = $p("dag{{a b}->x->y}")
- assert.equal(GraphAnalyzer.isEdgeStronglyProtected(g,g.getEdge("x","y")),true)
-
- g = $p("dag{x<-z3<-z1->x}")
- assert.equal(GraphAnalyzer.isEdgeStronglyProtected(g,g.getEdge("z1","x")),true)
- assert.equal(GraphAnalyzer.isEdgeStronglyProtected(g,g.getEdge("z3","x")),false)
- assert.equal(GraphAnalyzer.isEdgeStronglyProtected(g,g.getEdge("z1","z3")),false)
-
- assert.equal(
- GraphAnalyzer.containsCycle( TestGraphs.cyclic_graph() ), "A→B→C→A" )
- assert.equal(
- $p("x E\ny O\nz\na\n\nx y a z\na y\nz y").countPaths(),3)
- assert.equal((function(){
- // note, this test is overly restrictive as only one solution is
- // considered legal
- var g = TestGraphs.extended_confounding_triangle();
- var to = GraphAnalyzer.topologicalOrdering(g)
- var vids = _.pluck(g.vertices.values(),"id")
- vids.sort( function(a,b){ return to[a] < to[b] ? -1 : 1 } )
- return vids.toString();
- })(),"E,D,C,A,B")
-
- var chordalGraphs = [
- "graph { t -- x \n x -- y \n y -- t }",
- "graph { A -- E \n A -- Z \n B -- D \n B -- Z \n D -- Z \n E -- Z \n }",
- "graph { A -- B \n A -- E \n A -- Z \n B -- D \n B -- Z \n D -- Z \n E -- Z \n }",
- "graph { A -- B \n A -- E \n A -- Z \n B -- D \n B -- E \n B -- Z \n D -- Z \n E -- Z }"
- ];
- _.each(chordalGraphs, function(g) {
- assert.equal(GraphAnalyzer.isChordal($p(g)), true);
- });
- assert.equal(GraphAnalyzer.isChordal(TestGraphs.K5), true);
-
- var notChordalGraphs = [
- "graph {a -- b \n a -- x \n b -- y \n x -- y}",
- "graph {A -- E \n A -- Z \n B -- Z \n B -- D \n D -- E}",
- "graph {A -- E \n B -- D \n B -- Z \n B -- A \n D -- Z \n E -- Z }"
- ];
- _.each(notChordalGraphs, function(g) {
- assert.equal(GraphAnalyzer.isChordal($p(g)), false);
- });
-});
-
-QUnit.test( "biasing paths in DAGs (allowing <->)", function( assert ) {
- assert.equal((function(){
- var g = TestGraphs.confounding_triangle_with_irrelevant_nodes();
- var vv = [];
- _.each(GraphTransformer.activeBiasGraph(g).vertices.values(),function( v ){
- vv.push( v.id );
- })
- vv.sort();
- return vv.join(",");
- })(),"A,B,M" )
-assert.equal((function(){
- var g = $p( "digraph G { x <-> y } " )
- return $es(
- GraphTransformer.activeBiasGraph(g,g.getVertex(["x"]),g.getVertex(["y"])))
-})(), "x <-> y" )
-
-assert.equal((function(){
- var g = $p( "digraph G { x <- m <-> y } " )
- g.addSource("x")
- g.addTarget("y")
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "m -> x\nm <-> y" )
-
-assert.equal((function(){
- var g = $p( "digraph G { x -> m <-> y } " )
- g.addSource("x")
- g.addTarget("y")
- g.addAdjustedNode("m")
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "m <-> y\nx -> m" )
-
-assert.equal((function(){
- var g = $p( "digraph G { m <-> y \n x -> m -> y } " )
- g.addSource("x")
- g.addTarget("y")
- g.addAdjustedNode("m")
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "m <-> y\nx -> m" )
-
-assert.equal((function(){
- var g = $p( "digraph G { m <-> y \n x -> m -> y } " )
- g.addSource("x")
- g.addTarget("y")
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "" )
-
-assert.equal((function(){
- var g = $p( "digraph G { M \n "+
- "X [exposure] \n "+
- "Y [outcome] \n "+
- "M <-> Y [pos=\"0.645,-0.279\"] \n "+
- "X -> Y \n "+
- "X -> M -> Y } " )
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "" )
-
-});
-
-QUnit.test( "graph transformations", function( assert ) {
- assert.equal(
- $es(GraphTransformer.lineDigraph(
- $p( "dag{a<-b->c}" ))),
- "")
- assert.equal(
- $es(GraphTransformer.lineDigraph(
- $p( "dag{a->b->c}" ))),
- "ab -> bc")
-
- assert.equal(
- $es(GraphTransformer.lineDigraph(
- $p( "dag{a->b [label=x] b->c [label=y]}" ))),
- "x -> y")
-
- assert.equal(
- GraphTransformer.ancestorGraph( TestGraphs.small1() ).oldToString(),
- "A 1\nS E\nT O\n\nA S\nS T" )
- assert.equal(
- GraphTransformer.moralGraph(
- GraphTransformer.ancestorGraph(TestGraphs.small1()) ).oldToString()
- , "A 1\nS E\nT O\n\nA S\nS A T\nT S" )
- assert.equal((function(){
- var g = TestGraphs.confounding_triangle_with_irrelevant_nodes();
- var vv = [];
- _.each(GraphTransformer.ancestorGraph(g).vertices.values(),function( v ){
- vv.push( v.id );
- } );
- vv.sort();
- return vv.join(",");
- })(), "A,B,M,U1,U2" )
- assert.equal((function(){
- var g = TestGraphs.m_bias_graph();
- g.addAdjustedNode( "M" );
- return GraphTransformer.moralGraph(
- GraphTransformer.ancestorGraph(GraphTransformer.backDoorGraph(g)) ).oldToString()
- })(), "A E\nB O\nM A\nU1 1\nU2 1\n\n"+
- "A U1\nB U2\nM U1 U2\nU1 A M U2\nU2 B M U1" )
-
- assert.equal((function(){
- return GraphTransformer.moralGraph(
- GraphTransformer.ancestorGraph(
- GraphTransformer.backDoorGraph(TestGraphs.m_bias_graph())) ).oldToString()
- })(), "A E\nB O\nU1 1\nU2 1\n\nA U1\nB U2\nU1 A\nU2 B" )
-
- assert.equal((function(){
- var g = $p("dag{x<-z3<-z1->x}")
- return GraphTransformer.markovEquivalentDags(g).length
- })(),6,"markov equiv")
-
- var transformations = [
- GraphTransformer.pagToPdag,
- "pag{x@-@y@->z}","pdag{x--y->z}",
-
- GraphTransformer.dagToCpdag,
- "dag{x->y}", "pdag { x -- y }",
- "dag{x->y<-z}", "pdag { x -> y <- z }",
- "dag{x->y<-z->x}", "pdag { x -- y -- z -- x }",
- "dag{z1->{x z3} z2->{z3 y} z3->{x y} x->w->y}",
- "pdag {x <- z1 z1->z3 z2->z3 y<-z2 x<-z3 z3->y x->w->y}",
-
- GraphTransformer.cgToRcg,
- "pdag { k -- n; l -- m; n -- t; t -- y; x -> y; }",
- "pdag { k;l;m;n;t;x;y; l -- m; n -> k; t -> n; x -> y; y -> t }",
- "pdag { k -- n; l -- m; l -> n; l -> t; l -> y; n -- t; t -- y; x -> y; }",
- "pdag { k;l;m;n;t;x;y; l -- m; l -> n; l -> t; l -> y; n -> k; t -> n; x -> y; y -> t }",
- "pdag {a -> b -- c <- d }",
- null,
- "digraph { a -> b; b -- c; c <- d; b -- d }",
- "digraph { a -> b; b -> c; b -> d; d -> c }",
-
- function (g){ return GraphTransformer.contractComponents(g,
- GraphAnalyzer.connectedComponents(g), [Graph.Edgetype.Directed])},
- "pdag { k -- n l -- m n -- t t -- y x -> y }",
- 'pdag { "l,m" ; x -> "k,n,t,y" }',
- "digraph { a -- b; b -> c; c -- a }",
- 'digraph { "a,b,c" -> "a,b,c" }',
-
- GraphTransformer.transitiveClosure,
- "dag G { x -> y -> z }",
- "dag G { x -> y -> z <- x }",
-
- GraphTransformer.transitiveReduction,
- "dag G { x -> y -> z <- x }",
- "dag G { x -> y -> z }",
-
- GraphTransformer.dag2DependencyGraph,
- "dag G { x -> y -> z <- x }",
- "graph G { x -- y -- z -- x }",
- "dag G { x -> y -> z }",
- "graph G { x -- y -- z -- x }",
- "dag G { x -> y <- z }",
- "graph G { x -- y -- z }",
-
- GraphTransformer.dagToMag,
- "dag { v1 [latent] z <- v1 -> v2 -> y x -> v1}",
- "mag { x -> z <-> v2 -> y x -> v2 }",
- "dag { l1 [latent] l2 [latent] a -> x l1 -> x l1 -> z l2 -> y l2 -> z x -> y z -> x z -> y}",
- "mag { a -> x a -> y x -> y z -> x z -> y } ",
-
- ];
- var i = 0; var transfunc;
- while (i < transformations.length) {
- if (typeof transformations[i] === "function") {
- transfunc = transformations[i];
- i ++;
- }
- var gin = transformations[i]; i++;
- if (typeof gin === "string") gin = $p(gin);
- var gout = transfunc(gin);
- var gref = transformations[i]; i++;
- if( gref != null ){ gref = $p(gref) }
- assert.equal(GraphAnalyzer.equals(gout, gref),true);
- }
-});
-
-QUnit.test( "adjustment in DAGs", function( assert ) {
-
- assert.equal((function(){
- var g = $p("pdag{ x -> {a -- b -- c -- a } b -> y x[e] y[o] }")
- return _.pluck(GraphAnalyzer.properPossibleCausalPaths(g),"id").sort().join(" ")
- })(), "a b c x y" )
-
- assert.equal((function(){
- var g = $p("pdag{ x -> a -- b -> y x[e] y[o] }")
- return _.pluck(GraphAnalyzer.properPossibleCausalPaths(g),"id").sort().join(" ")
- })(), "a b x y" )
-
- assert.equal((function(){
- var g = $p("pdag{ x -> a -- b -- c -> y x[e] y[o] }")
- return _.pluck(GraphAnalyzer.properPossibleCausalPaths(g),"id").sort().join(" ")
- })(), "a b c x y" )
-
-
- assert.equal((function(){
- // our non-X-ancestor MSAS example from the UAI paper w/ causal edge
- var g = $p("X1 E\nX2 E\nY O\nM1 1\nM2 1\n\nX1 Y M1\nY M2\nM1 M2\nM2 X2")
- return sep_2_str( GraphAnalyzer.listMsasDirectEffect( g ) )
- })(), "" )
-
- assert.equal((function(){
- // our non-X-ancestor MSAS example from the UAI paper w/o causal edge
- var g = $p("X1 E\nX2 E\nY O\nM1 1\nM2 1\n\nX1 M1\nY M2\nM1 M2\nM2 X2")
- return sep_2_str( GraphAnalyzer.listMsasDirectEffect( g ) )
- })(), "{M1, M2}" )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "Thoemmes" )
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) )
- })(), "" )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "Thoemmes" )
- g.removeAdjustedNode("s2")
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) )
- })(), "{}" )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "Thoemmes" )
- return sep_2_str( GraphAnalyzer.listMsasDirectEffect( g ) )
- })(), "{e2, s2}\n{s1, s2}" )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "mediat" )
- return sep_2_str( GraphAnalyzer.listMsasDirectEffect( g ) )
- })(), "{I}" )
-
- assert.equal((function(){
- var g = $p("dag{x[e] y[o] x<-z->y}")
- return GraphAnalyzer.isAdjustmentSet(g,["z"])
- })(), true)
-
- assert.equal((function(){
- var g = $p("dag{x[e] y[o] x<->m<->y x->y}")
- return GraphAnalyzer.isAdjustmentSet(g,["m"])
- })(), false)
-
- assert.equal(
- sep_2_str( GraphAnalyzer.listMsasTotalEffect( TestGraphs.findExample("Polzer") ) ),
- "{Age, Alcohol, Diabetes, Obesity, Psychosocial, Sex, Smoking, Sport}\n"+
- "{Age, Alcohol, Periodontitis, Psychosocial, Sex, Smoking}" )
- assert.equal((function(){
- var g = TestGraphs.m_bias_graph();
- g.addAdjustedNode("A");
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
- })(), "{A}" )
- assert.equal((function(){
- var g = TestGraphs.m_bias_graph();
- g.addAdjustedNode("M");
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
- })(), "{M, U1}\n{M, U2}" )
- assert.equal((function(){
- var g = TestGraphs.findExample( "Acid" );
- g.addAdjustedNode("x9");
- return GraphAnalyzer.violatesAdjustmentCriterion( g )
- })(), true )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "Acid" );
- g.addAdjustedNode("x16");
- return GraphAnalyzer.violatesAdjustmentCriterion( g )
- })(), true )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "Acid" );
- return GraphAnalyzer.violatesAdjustmentCriterion( g )
- })(), false )
-
- assert.equal( sep_2_str(GraphAnalyzer.listMsasTotalEffect(
- $p("dag { X1 [exposure]\n "+
- "X2 [exposure]\n Y1 [outcome] \n Y2 [outcome]\n "+
- "C -> Y1 \n"+
- "C -> m \n X1 -> X2 \n X1 -> Y2 -> Y1 \n X2 -> Y1 \n X1 -> m2 -> m -> X2 }"))),
- "{C}\n{m, m2}")
-
- g = $p( "dag G { a <-> b } " )
- assert.equal( GraphTransformer.trekGraph( g ).edges.length, 4, "trek graph with <->" )
-
-
-});
-
-QUnit.test( "adjustment in other graphs", function( assert ) {
- assert.equal( sep_2_str(GraphAnalyzer.listMsasTotalEffect(
- $p("pdag { X [exposure]\n"+
- "Y [outcome]\n"+
- "X -> W -> Y ; F -> W -- Z ; X <- F -> Z }")
- ) ),
- "{F}" )
-
- assert.equal( sep_2_str(GraphAnalyzer.listMsasTotalEffect(
- $p("mag { X [e] Y[o] X->Y }")
- ) ), "" )
-
- assert.equal( sep_2_str(GraphAnalyzer.listMsasTotalEffect(
- $p("mag { X [e] Y[o] I->X->Y }")
- ) ), "{}" )
-
- assert.equal( GraphAnalyzer.listMsasTotalEffect($p($p("pag{i<-@x->y x[e] y[o]}").toString()) ).length,
- 0 )
-
-});
-
-QUnit.test( "PAGs", function( assert ) {
-
- assert.equal( GraphAnalyzer.listMsasTotalEffect(
- TestGraphs.spirtes, [], [], 200 ).length, 200 )
-
- assert.equal( GraphAnalyzer.violatesAdjustmentCriterion(
- TestGraphs.spirtes ), false )
-
- var gam = GraphTransformer.moralGraph(
- GraphTransformer.ancestorGraph(
- GraphTransformer.backDoorGraph( TestGraphs.spirtes ) ) )
-
- assert.equal( gam.edges.length, 302 )
-
- assert.equal( GraphTransformer.ancestorGraph(
- GraphTransformer.backDoorGraph(
- TestGraphs.spirtes ) ).edges.length, 133 )
-
-
- assert.equal( GraphTransformer.backDoorGraph(
- TestGraphs.spirtes ).edges.length, 795 )
-
- assert.equal(
- GraphTransformer.backDoorGraph(
- $p("pag{ {V2 V1} @-> X -> {V4 @-> Y} <- V3 @-> X X[e] Y[o]}")).
- getVertex("X").getChildren().length, 0, "No children of X" )
-
- assert.equal(
- GraphTransformer.backDoorGraph(
- $p("pag{ {V2 V1} -> X -> {V4 -> Y} <- V3 -> X X[e] Y[o]}")).
- getVertex("X").getChildren().length, 0 )
-
- assert.equal(
- GraphTransformer.backDoorGraph(
- $p("pdag{ {V2 V1} -> X -> {V4 -> Y} <- V3 -> X X[e] Y[o]}")).
- getVertex("X").getChildren().length, 0 )
-
- assert.equal(
- GraphAnalyzer.dpcp($p("pag{ {V2 V1} -> X -> V4 -> Y <- V3 <-> {X V4} X[e] Y[o]}")).length, 2 )
-
-});
-
-QUnit.test( "testable implications", function( assert ) {
- assert.equal((function(){
- var g = TestGraphs.findExample("Shrier")
- var ii = GraphAnalyzer.listMinimalImplications( g )
- var all_good=true
- for( var i = 0 ; i < ii.length ; i ++ ){
- for( var j = 0 ; j < ii[i][2].length ; j ++ ){
- if( ii[i][2][j].length > 0 ){
- all_good = all_good && GraphAnalyzer.dConnected( g,
- [g.getVertex(ii[i][0])], [g.getVertex(ii[i][1])],
- ii[i][2][j].slice(1) )
- }
- }
- }
- return all_good
- })(), true )
-
- assert.equal((function(){
- var g = TestGraphs.findExample("Shrier")
- var ii = GraphAnalyzer.listMinimalImplications( g )
- var all_good=true
- for( var i = 0 ; i < ii.length ; i ++ ){
- for( var j = 0 ; j < ii[i][2].length ; j ++ ){
- all_good = all_good && !GraphAnalyzer.dConnected( g,
- [g.getVertex(ii[i][0])], [g.getVertex(ii[i][1])], ii[i][2][j] )
- }
- }
- return all_good
- })(), true )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "mediat" );
- return imp_2_str( GraphAnalyzer.listBasisImplications( g ) );
- })(), "Y _||_ Z | I, X" )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "mediat" );
- return imp_2_str( GraphAnalyzer.listMinimalImplications( g ) );
- })(), "Y _||_ Z | I, X" )
-
- assert.equal((function(){
- var g = TestGraphs.findExample( "mediat" );
- g.getVertex("Z").adjusted_for = true;
- return imp_2_str( GraphAnalyzer.listMinimalImplications( g ) );
- })(), "Y _||_ Z | I, X" )
-
- assert.equal((function(){
- return imp_2_str(
- GraphAnalyzer.listMinimalImplications( TestGraphs.commentator1() ) );
- })(), "X _||_ V | W1, Z1\nX _||_ Z2 | V, W2\nX _||_ Z2 | W1, W2, Z1\nY _||_ V | W1, W2, Z1, Z2\nV _||_ W1\nV _||_ W2\nW1 _||_ Z2 | W2\nW2 _||_ Z1 | W1\nZ1 _||_ Z2 | V, W2\nZ1 _||_ Z2 | V, W1" )
-});
-
-QUnit.test( "tetrad analysis", function( assert ) {
- assert.equal( function(){
- var g = $p("dag { {a b} -> x -> y }")
- return GraphAnalyzer.vanishingTetrads( g ).length
- }() , 1, "choke point in I/J side" )
-
- assert.equal((function(){
- var g = $p("dag { xi1 [u] xi2 [u] xi3 [u] xi1 <-> xi2 <-> xi3 <-> xi1 "+
- " xi1 -> {X1 X2 X3} xi2 -> {X4 X5 X6} xi3 -> {X7 X8 X9} }")
- return GraphAnalyzer.vanishingTetrads( g ).length
- })(), 162 )
-
- assert.equal((function(){
- var g = $p("xi1 U\neta1 U\neta2 U\nY1 1\n Y2 1\nY3 1\n Y4 1\nX1 1\n X2 1\n\nxi1 eta1 eta2 X1 X2\neta1 eta2 Y1 Y2\neta2 Y3 Y4")
- return ""+GraphAnalyzer.vanishingTetrads( g ).join("\n")
- })(), "Y1,Y3,Y4,Y2\nY1,Y3,X1,Y2\nY1,Y3,X2,Y2\nY1,Y4,X1,Y2\nY1,Y4,X2,Y2\nY1,X1,X2,Y2\nY1,Y3,Y4,X1\nY1,Y3,Y4,X2\nY1,X1,X2,Y3\nY1,X1,X2,Y4\nY2,Y3,Y4,X1\nY2,Y3,Y4,X2\nY2,X1,X2,Y3\nY2,X1,X2,Y4\nY3,X1,X2,Y4" )
-
- assert.equal((function(){
- var g = $p("xi1 U\nxi2 U\nxi3 U\nU1 U\nU2 U\nU3 U\nX1 1\nX2 1\nX3 1\nX4 1\nX5 1\nX6 1\nX7 1\nX8 1\nX9 1\n\nxi1 X1 X2 X3\nxi2 X4 X5 X6\nxi3 X7 X8 X9\nU1 xi1 xi2\nU2 xi2 xi3\nU3 xi1 xi3")
- return GraphAnalyzer.vanishingTetrads( g ).length
- })(), 162 )
-
- assert.equal((function(){
- var g = $p("xi1 U\neta1 U\neta2 U\nY1 1\n Y2 1\nY3 1\n Y4 1\nX1 1\n X2 1\n\nxi1 eta1 eta2 X1 X2\neta1 eta2 Y1 Y2\neta2 Y3 Y4")
- return GraphAnalyzer.vanishingTetrads( g ).length
- })(), 15 )
-
- assert.equal((function(){
- var g = $p("U U\nX1 1\nX10 1 \nX2 1 \nX3 1 \nX4 1 \nX5 1 \nX6 1 \nX7 1 \nX8 1 \nX9 1 \nxi_1 U \nxi_2 U \n\n"+
- "U xi_1 xi_2\nxi_1 X1 X2 X3 X4 X5\nxi_2 X6 X7 X8 X9 X10\nUa X1 X2\nUb X1 X6")
- return ""+GraphAnalyzer.vanishingTetrads( g ).length
- })(), 430 )
-
- assert.equal((function(){
- var g = $p("u U\nx U\ny U\nx1 1\nx2 1\nx3 1\nx4 1\ny1 1\ny2 1\ny3 1\ny4 1\n\n"
- +"u x y\nx x1 x2 x3 x4\ny y1 y2 y3 y4")
- return GraphAnalyzer.vanishingTetrads( g ).length
- })(), 138 )
-
- assert.equal((function(){
- return GraphAnalyzer.vanishingTetrads( TestGraphs.findExample( "Thoemmes" ) ).length
- })(), 98 )
-
- assert.equal((function(){
- return GraphTransformer.trekGraph( $p("dag {E<-A->Z<-B->D<-E}") ).toAdjacencyList()
- })(), "dw_A dw_E dw_Z\ndw_B dw_D dw_Z\ndw_E dw_D\nup_A dw_A\nup_B dw_B\nup_D dw_D up_B up_E\nup_E dw_E up_A\nup_Z dw_Z up_A up_B" )
-
-});
-
-QUnit.test( "instrumental variables", function( assert ) {
- assert.equal((function(){
- var g = $p( "digraph G { u1 [latent] \n u2 [latent] \n"+
- "u2 -> d -> a -> z \n a -> c -> b -> z \n "+
- "u2 -> y \n b -> u1 -> y \n "+
- "\n }" )
- return _.pluck(GraphAnalyzer.closeSeparator(
- g, g.getVertex("y"), g.getVertex("z")
- ),"id").join(",")
- })(), "b,d" )
-
- assert.equal((function(){
- var g = $p( "digraph G { u [latent] \n x [exposure] \n y [outcome] \n"+
- " w -> z -> x -> y \n w -> u -> x \n u -> y \n }" )
- return iv_2_str( GraphAnalyzer.conditionalInstruments( g ) )
- })(), "z | w" )
-
- assert.equal((function(){
- var g = $p( "digraph G { u [latent] \n x [exposure] \n y [outcome] \n"+
- " z -> x -> y \n u -> x \n u -> y \n }" )
- return iv_2_str( GraphAnalyzer.conditionalInstruments( g ) )
- })(), "z" )
-
- assert.equal((function(){
- var g = $p( "digraph G { u \n w -> z -> x -> y \n w -> u -> x \n u -> y }" )
- return _(GraphAnalyzer.ancestralInstrument( g, g.getVertex("x"), g.getVertex("y"),
- g.getVertex("z") )).pluck("id").join(",")
- })(), "u" )
-
- assert.equal((function(){
- var g = $p( "dag{ u \n z -> x -> y \n u -> x \n u -> y \n }" )
- return ""+_(GraphAnalyzer.conditionalInstruments( g,
- g.getVertex("x"), g.getVertex("y"))[0][1]).pluck("id").join(",")
- })(), "" )
-
- assert.equal((function(){
- var g = $p( "digraph G { u [latent] \n w -> z -> x -> y \n w -> u -> x \n u -> y }" )
- return _(GraphAnalyzer.ancestralInstrument( g, g.getVertex("x"), g.getVertex("y"),
- g.getVertex("z") )).pluck("id").join(",")
- })(), "w" )
-
- assert.equal((function(){
- var g = $p( "digraph G { u [latent] \n z -> x -> y \n u -> x \n u -> y \n }" )
- return ""+_(GraphAnalyzer.ancestralInstrument( g, g.getVertex("x"), g.getVertex("y"),
- g.getVertex("z") )).pluck("id").join(",")
- })(), "" )
-});
-
-QUnit.test( "treeID", function( assert ) {
- //instrument
- var r = GraphAnalyzer.treeID($p( "dag { Z -> X \n X -> Y \n X <-> Y }" )).results
- assert.equal(r["X"][0].instrument, "Z")
- assert.equal(r["X"][0].fastp.length, 1)
- assert.equal(r["Y"][0].instrument, "Z")
- assert.equal(r["Y"][0].fastp.length, 1)
-
- //instrument + propagate
- var r = GraphAnalyzer.treeID($p( "dag { A -> E \n A <-> D \n E -> D \n E -> v1 }" )).results
- assert.equal(r["E"][0].instrument, "A")
- assert.equal(r["E"][0].fastp.length, 1)
- assert.equal(r["v1"][0].instrument, "A")
- assert.equal(r["v1"][0].fastp.length, 1)
- assert.equal(r["D"][0].propagate, "E")
- assert.equal(r["D"][0].fastp.length, 1)
-
- //missing cycles (example from weihs/drton tsID)
- var r = GraphAnalyzer.treeID($p( "dag { 0 -> 1 \n 0 -> 2 \n 0 -> 3 \n 0 <-> 1 \n 0 <-> 2 \n 0 <-> 3 \n 0 <-> 4 \n 3 -> 4 }" )).results
- assert.equal(r["1"][0].propagate, "2")
- assert.equal(r["1"][0].fastp.length, 1)
- assert.equal(r["2"][0].propagate, "4")
- assert.equal(r["2"][0].fastp.length, 1)
- assert.equal(r["4"][0].propagate, "3")
- assert.equal(r["4"][0].fastp.length, 1)
- assert.equal("missingCycles" in r["3"][0], true)
- assert.equal(r["3"][0].fastp.length, 1)
-
- //missing cycles (example (4680, 403) from weihs/drton tsID)
- var r = GraphAnalyzer.treeID($p( "dag { 3->4 \n 1->2 \n 0->1 \n 2->3 \n 3<->1 \n 3<->0 \n 1<->0 \n 0<->2 \n 0<->4 }" )).results
- assert.equal(r["3"][0].propagate, "4")
- assert.equal(r["3"][0].fastp.length, 1)
- assert.equal(r["4"][0].propagate, "1")
- assert.equal(r["4"][0].fastp.length, 1)
- assert.equal(r["1"][0].propagate, "2")
- assert.equal(r["1"][0].fastp.length, 1)
- assert.equal("missingCycles" in r["2"][0], true)
- assert.equal(r["2"][0].fastp.length, 1)
-
- //not identifiable
- var r = GraphAnalyzer.treeID($p( "dag { A -> E \n A <-> D \n A <-> E \n A <-> v1 \n D <-> v1 \n E -> D \n E -> v1 }" )).results
- assert.equal( ("A" in r) || ("E" in r) || ("D" in r) || ("v1" in r), false )
-
- //2-id, missing cycle [[1, 2], [2, 3], [3, 4], [1, 4]]
- var r = GraphAnalyzer.treeID($p( "dag { 0 -> 1 \n 0 <-> 1 \n 0 <-> 2 \n 0 <-> 3 \n 0 <-> 4 \n 1 -> 2 \n 1 <-> 3 \n 2 -> 3 \n 2 <-> 4 \n 3 -> 4 }" )).results
- assert.equal(r["4"][0].propagate, "3")
- assert.equal(r["4"][0].fastp.length, 2)
- assert.equal(r["3"][0].propagate, "2")
- assert.equal(r["3"][0].fastp.length, 2)
- assert.equal(r["2"][0].propagate, "1")
- assert.equal(r["2"][0].fastp.length, 2)
- assert.equal("missingCycles" in r["1"][0], true)
- assert.equal(r["1"][0].fastp.length, 2)
-
-
-})
-
-QUnit.test( "graph validation", function( assert ) {
- GraphParser.VALIDATE_GRAPH_STRUCTURE = false;
- assert.equal( GraphAnalyzer.validate( $p(
- "dag { x -> y -> z }"
- )), true )
- assert.equal( GraphAnalyzer.validate( $p(
- "dag { x -> y -> z -> x }"
- )), false )
-
- assert.equal( GraphAnalyzer.validate( $p(
- "pdag { x -> y -> z }"
- )), true )
-
- assert.equal( GraphAnalyzer.validate( $p(
- "dag { x -- y -> z -> x }"
- )), false )
- assert.equal( GraphAnalyzer.validate( $p(
- "pdag { x -- y -> z }"
- )), true )
- GraphParser.VALIDATE_GRAPH_STRUCTURE = true;
-});
-
-QUnit.test( "graph types", function( assert ) {
- var graphs = {
- graph : $p( "graph { x -- y -- z }" ),
- dag : $p( "dag { x -> y -> z }" ),
- pdag : $p( "pdag { x -- y -> z }" ),
- mag : $p( "mag { x <-> y -> z }" )
- };
-
- _.each( Object.keys(graphs), function(t){
- assert.equal( GraphTransformer.inducedSubgraph(graphs[t],
- graphs[t].getVertex(["x","y"])).getType(), t )
- });
-
- _.each( Object.keys(graphs), function(t){
- assert.equal( GraphTransformer.edgeInducedSubgraph(graphs[t],
- graphs[t].edges).getType(), t )
- });
-
- _.each( Object.keys(graphs), function(t){
- assert.equal( GraphTransformer.ancestorGraph(graphs[t],
- graphs[t].getVertex(["x","y"])).getType(), t )
- });
-
- _.each( ["backDoorGraph","indirectGraph","activeBiasGraph"], function(f){
- _.each( Object.keys(graphs), function(t){
- assert.equal( GraphTransformer[f](graphs[t],
- graphs[t].getVertex(["x"]),graphs[t].getVertex(["z"])).getType(), t )
- })
- });
-
- _.each( Object.keys(graphs), function(t){
- assert.equal( GraphTransformer.canonicalDag(graphs[t]).g.getType(), "dag" )
- });
-
- _.each( ["moralGraph","skeleton"], function(f){
- _.each( Object.keys(graphs), function(t){
- assert.equal( GraphTransformer[f](graphs[t]).getType(), "graph" )
- });
- });
-
-});
-
-QUnit.test( "dseparation", function( assert ) {
- assert.equal((function(){
- var g = $p( "digraph G { x <-> m -> y }" )
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [] )
- })(), true )
-
- assert.equal((function(){
- var g = $p( "digraph G { x <-> m -> y }" )
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [g.getVertex("m")] )
- })(), false )
-
- assert.equal((function(){
- var g = $p( "digraph G { x <-> m <-> b <-> y }" )
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [g.getVertex("m")] )
- })(), false )
-
- assert.equal((function(){
- var g = $p( "digraph G { x <-> m <-> b <-> y }" )
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [g.getVertex("m"),g.getVertex("b")] )
- })(), true )
-
- assert.equal((function(){
- var g = $p( "digraph G { x -> m -> y }" )
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [] )
- })(), true )
-
- assert.equal((function(){
- var g = $p( "digraph G { x -> m -> y }" )
- return !GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [g.getVertex("m")] )
- })(), true )
-
- assert.equal((function(){
- var g = $p( "digraph G { x -> m -> y }" )
- return !GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")], [] )
- })(), false )
-
- assert.equal((function(){
- var g = $p("dag{R->S->T<-U}")
- g = GraphAnalyzer.listPaths( g, false, 1, [g.getVertex("R")], [g.getVertex("U")] )[0]
- return GraphAnalyzer.dConnected( g, [g.getVertex("R")], [g.getVertex("U")],
- g.getVertex(["T"]) )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ a->x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("a")], [g.getVertex("y")],
- g.getVertex(["m"]) )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ a->x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, g.getVertex(["x"]), [g.getVertex("y")],
- g.getVertex(["m"]), g.getVertices(["x"]) )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [g.getVertex("m")] )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- g.getVertex(["p"]), g.getVertex(["m","p"]) )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ x[e] y[o] x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- g.getVertex([]), [] )
- })(), false )
-
- assert.equal((function(){
- var g = $p("dag{ x[e] y[o] x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- g.getVertex([]), g.getVertex(["m","p"]) )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [g.getVertex("m")] )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [g.getVertex("p")] )
- })(), true )
-
- assert.equal((function(){
- var g = $p("dag{ x->m<-y m->p }")
- return GraphAnalyzer.dConnected( g, [g.getVertex("x")], [g.getVertex("y")],
- [] )
- })(), false )
-
- assert.equal((function(){
- var g = TestGraphs.findExample("onfound")
- return GraphAnalyzer.dConnected( g, [g.getVertex("E")], [g.getVertex("B")],
- [g.getVertex("Z")] )
- })(), true )
-});
-
-QUnit.test( "uncategorized tests", function( assert ) {
-
-assert.equal((function(){
- var g = TestGraphs.small3();
- g.addSource("S");
- g.addTarget("T");
- g.addAdjustedNode("p");
- var abg = GraphTransformer.activeBiasGraph(g);
- var gbd = GraphTransformer.backDoorGraph(abg);
- var gbdan = GraphTransformer.ancestorGraph(gbd);
- var gam = GraphTransformer.moralGraph( gbdan )
- // the undirected edges from the active bias graph graph should
- // not yield an edge x -- y in the moral graph, hence {p} again
- // becomes a valid separator
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( abg ) );
-})(), "{p, x}\n{p, z}" )
-
-assert.equal((function(){
- var g = TestGraphs.big1();
- g.addAdjustedNode("y");
- var g_bias = GraphTransformer.activeBiasGraph( g )
- g = GraphTransformer.edgeInducedSubgraph( g, g_bias.edges )
- g = GraphTransformer.moralGraph( g )
- g.deleteVertex(g.getVertex("x"))
- return sep_2_str( GraphAnalyzer.listMinimalSeparators( g ) )
-})(), "{a, h}\n{e, h}\n{f, h}\n{h, n}" )
-
-assert.equal((function(){
- var g = TestGraphs.small2();
- g = GraphTransformer.activeBiasGraph(g);
- return g.toAdjacencyList();
-})(), "a b s\nc b t\ng c s" )
-
-assert.equal((function(){
- var g = TestGraphs.findExample("Schipf");
- g.addAdjustedNode("WC");
- g.addAdjustedNode("U");
- g = GraphTransformer.activeBiasGraph(g);
- return $es(g);
-})(), "A -> PA\nA -> S\nA -> TT\nA -> WC\nPA -> T2DM\nPA -> WC\nS -> T2DM\nS -> TT" )
-
-assert.equal((function(){
- var g = TestGraphs.extended_confounding_triangle()
- var gbias = GraphTransformer.activeBiasGraph(g)
- var gmor = GraphTransformer.moralGraph( gbias )
- var gsep = GraphAnalyzer.listMinimalSeparators(
- gmor, [g.getVertex("D")], [] )
- return sep_2_str( gsep )
-})(), "{C, D}" )
-
-assert.equal((function(){
- var g = TestGraphs.findExample("Acid");
- return sep_2_str(
- GraphAnalyzer.listMinimalSeparators(
- GraphTransformer.moralGraph( GraphTransformer.activeBiasGraph(g) ), [], g.descendantsOf(g.getSources()) ) );
-})(), "{x1}\n{x4}" )
-
-assert.equal((function(){
- var g = TestGraphs.intermediate_adjustment_graph();
- return sep_2_str(
- GraphAnalyzer.listMinimalSeparators(
- GraphTransformer.moralGraph(GraphTransformer.activeBiasGraph(g)), [], [g.getVertex('I')] ) );
-})(), "{Z}" )
-
-assert.equal((function(){
- var g = TestGraphs.intermediate_adjustment_graph();
- g.getVertex('I').latent = true;
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{Z}" )
-
-assert.equal((function(){
- var g = TestGraphs.small_mixed();
- var cc = GraphAnalyzer.connectedComponents(g);
- var r = "";
- _.each(cc, function(c) {
- r += ("["+_.pluck(c,'id').sort().join(",")+"] ");
- } );
- return r;
-})(), "[a,b,c] [d,e,f] " )
-
-assert.equal((function(){
- // This test verifies that the below methods have
- // no side effects (which they had in an earlier, buggy
- // version of the code)
- var g = TestGraphs.extended_confounding_triangle();
- GraphTransformer.ancestorGraph(g);
- GraphTransformer.ancestorGraph(g);
- GraphTransformer.activeBiasGraph(g);
- GraphTransformer.activeBiasGraph(g);
- return g.oldToString();
-})(), "A E\nB O\nC 1\nD 1\nE 1\n\nA B\nC A B\nD A C\nE B C" )
-
-assert.equal((function(){
- var g = GraphTransformer.moralGraph( $p( "x 1\ny 1\nm 1\na 1\nb 1\n\nm x\nm y\na m x\nb m y" ) )
- return _.pluck(GraphAnalyzer.connectedComponentAvoiding( g,
- [g.getVertex("x")], [g.getVertex("m"), g.getVertex("b")] ),'id')
- .sort().join(",");
-})(), "a,x" )
-
-assert.equal((function(){
- GraphParser.VALIDATE_GRAPH_STRUCTURE = false;
- var g = $p( "xobs 1 @0.350,0.000\n"+
-"y 1 @0.562,0.000\n"+
-"t 1 @0.351,-0.017\n"+
-"\n"+
-"xobs y\n"+
-"y t\n"+
-"t xobs" );
- GraphParser.VALIDATE_GRAPH_STRUCTURE = true;
- GraphAnalyzer.containsCycle( g );
- return GraphAnalyzer.containsCycle( g );
-})(), "xobs→y→t→xobs" )
-
-assert.equal((function(){
- var g = $p( "xobs E @0.350,0.000\n"+
-"y O @0.562,0.000\n"+
-"t 1 @0.351,-0.017\n"+
-"u1 1 @0.476,-0.013\n"+
-"u2 1 @0.175,-0.017\n"+
-"\n"+
-"t xobs\n"+
-"u1 t y\n"+
-"u2 t xobs\n"+
-"xobs y" );
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{t, u2}\n{u1}" )
-
-assert.equal((function(){
- var g = TestGraphs.small5()
- g.addAdjustedNode("A")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "T A\nU A I" )
-
-assert.equal((function(){
- var g = TestGraphs.small5();
- return GraphTransformer.causalFlowGraph(g).toAdjacencyList();
-})(), "A I\nT A" )
-
-assert.equal((function(){
- var g = TestGraphs.small5();
- g.addAdjustedNode("A");
- return GraphTransformer.causalFlowGraph(g).toAdjacencyList();
-})(), "" )
-
-assert.equal((function(){
- var g = TestGraphs.small4();
- g.addAdjustedNode("A");
- var abg = GraphTransformer.activeBiasGraph(g);
- return abg.oldToString()
-})(), "I O\nT E\n\n" )
-
-assert.equal((function(){;
- var g = TestGraphs.small3();
- g.addAdjustedNode("p");
- g.addSource("S");
- g.addTarget("T");
- var abg = GraphTransformer.activeBiasGraph(g);
- g.deleteVertex( "p" )
- return GraphTransformer.edgeInducedSubgraph(g,abg.edges).toAdjacencyList()
-})(), "x S\nz T" )
-
-assert.equal((function(){;
- var g = TestGraphs.small3();
- g.addSource("S");
- g.addTarget("T");
- g.addAdjustedNode("p");
- // this should yield the same result as listing the MSAS of g
- // the vertex p should not be listed as contained in the separators
- // because it is not listed as compulsory in the call to "listSeparators()"
- // (see the api of the function there)
- var g_bias = GraphTransformer.activeBiasGraph( g )
- var g_can = GraphTransformer.canonicalDag( g_bias )
- g = GraphTransformer.moralGraph( g_can.g )
- return sep_2_str( GraphAnalyzer.listMinimalSeparators( g, [],
- g.getAdjustedNodes() ) )
-})(), "{x}\n{z}" )
-
-assert.equal((function(){
- var g = TestGraphs.commentator1();
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "" )
-
-assert.equal((function(){
- var g = $p("S E @0.395,0.046\n"+
-"T O @0.715,0.039\n"+
-"h 1 @0.544,0.017\n"+
-"i 1 @0.544,0.017\n"+
-"x 1 @0.424,0.072\n"+
-"z 1 @0.610,0.071\n"+
-"\n"+
-"S T\n"+
-"h S\n"+
-"i h T\n"+
-"x S z\n"+
-"z T\n");
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{h, x}\n{h, z}\n{i, x}\n{i, z}" )
-
-assert.equal((function(){
- var g = TestGraphs.big1();
- g.addAdjustedNode("y");
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{a, h, x, y}\n{a, h, y, z}\n{e, h, x, y}\n{e, h, y, z}\n{f, h, x, y}\n{f, h, y, z}\n{h, n, x, y}\n{h, n, y, z}" )
-
-assert.equal((function(){
- var g = TestGraphs.findExample("Shrier");
- var must = [g.getVertex("FitnessLevel")];
- var must_not = [g.getVertex("Genetics"),
- g.getVertex("ConnectiveTissueDisorder"),
- g.getVertex("IntraGameProprioception")];
-
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g, must, must_not ) );
-})(), "{Coach, FitnessLevel}\n{FitnessLevel, NeuromuscularFatigue, TissueWeakness}\n{FitnessLevel, TeamMotivation}" )
-
-assert.equal((function(){
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( TestGraphs.very_large_dag() ) );
-})(), "{Allergenexposition, Antibiotika, Begleiterkrankungen, BetreuungKind, Darmflora, Erregerexposition, Geschwister, Hausstaub, Haustiere, Infektionen, RauchenAnderer, RauchenMutter, Stillen}\n{Allergenexposition, Antibiotika, Begleiterkrankungen, Darmflora, Erregerexposition, Geburtsmodus, Hausstaub, Haustiere, Infektionen, RauchenAnderer, RauchenMutter, Stillen}\n{Allergenexposition, Begleiterkrankungen, Darmflora, Erregerexposition, Impfungen, Infektionen, RauchenAnderer, RauchenMutter}" )
-
-assert.equal((function(){
- var g = GraphTransformer.moralGraph( $p( "x E\ny O\nm\na\nb\n\nm x\nm y\na m x\nb m y" ) )
- return sep_2_str( GraphAnalyzer.listMinimalSeparators(g) );
-})(), "{a, m}\n{b, m}" )
-
-assert.equal((function(){
- // the function "neighboursOf" should, also when called on a vertex set,
- // not return any vertices from those sets as neighbours of the set itself
- var g = GraphTransformer.moralGraph( $p( "x\ny\nm\na\nb\n\nm x\nm y\na m x\nb m y" ) )
- return _.pluck(g.neighboursOf( [g.getVertex("m"), g.getVertex("b")] ),'id')
- .sort().join(",");
-})(), "a,x,y" )
-
-assert.equal((function(){
- var g = $p("E E @-1.897,0.342\n"+
- "D O @-0.067,0.302\n"+
- "g A @-0.889,1.191\n"+
- "\n"+
- "D g\n"+
- "E D");
- return GraphAnalyzer.violatesAdjustmentCriterion( g )
-})(), true )
-
-assert.equal((function(){
- var g = $p("x E @0.083,-0.044\n"+
- "y O @0.571,-0.043\n"+
- "i1 1 @0.331,-0.037\n"+
- "i2 1 @0.328,-0.030\n"+
- "y2 A @0.333,-0.054\n"+
- "y3 1 @0.334,-0.047\n"+
- "\n"+
- "i1 y\n"+
- "i2 y\n"+
- "x y2 i2 i1 y\n"+
- "y3 y x");
- return _.pluck(GraphAnalyzer.intermediates(g),'id').join(",");
-})(), "i1,i2" )
-
-assert.equal((function(){
- var g = $p("x 1 @0.264,-0.027\n"+
- "y 1 @0.537,-0.015\n"+
- "y2 A @0.216,-0.015\n"+
- "\n"+
- "x y2 y");
- return _.pluck(GraphAnalyzer.intermediates(g),'id').join(",");
-})(), "" )
-
-assert.equal((function(){
- var g = $p("x E @0.264,-0.027\n"+
-"y O @0.537,-0.015\n"+
-"y2 A @0.216,-0.015\n"+
-"\n"+
-"x y2 y");
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{y2}" )
-
-assert.equal((function(){
- var g = TestGraphs.findExample( "Many variables" );
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{7}\n{8}" )
-
-assert.equal((function(){
- var g = TestGraphs.findExample( "Extended confounding" );
- g.addLatentNode( "A" );
- return imp_2_str( GraphAnalyzer.listMinimalImplications( g ) );
-})(), "" )
-
-assert.equal((function(){
- var g = TestGraphs.findExample( "Sebastiani" );
- return imp_2_str( GraphAnalyzer.listMinimalImplications( g, 7 ) );
-})(), "EDN1.3 _||_ SELP.22 | SELP.17, Stroke\n"+
- "EDN1.3 _||_ SELP.22 | ECE1.13, Stroke\n"+
- "EDN1.3 _||_ SELP.22 | ECE1.12, Stroke\n"+
- "EDN1.3 _||_ SELP.22 | ANXA2.8\n"+
- "EDN1.3 _||_ SELP.17 | ECE1.13\n"+
- "EDN1.3 _||_ SELP.17 | ECE1.12, Stroke\n"+
- "EDN1.3 _||_ SELP.17 | ANXA2.8" )
-
-assert.equal((function(){
- // X -> I -> Y, I <- M -> Y, I -> A = bias
- var g = $p("X E\nY O\nI 1\nJ A\nM 1\n\nX I\nI J Y\nM I Y")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "I J Y\nM I Y\nX I" )
-
-assert.equal((function(){
- // X -> I -> Y, I <- M -> Y = bias
- var g = $p("X E\nY O\nI A\nM 1\n\nX I\nI Y\nM I Y")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "M I Y\nX I" )
-
-assert.equal((function(){
- // X -> I -> Y, I -> A = bias
- var g = $p("X E\nY O\nI 1\nJ A\n\nX I\nI Y J")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "I J Y\nX I" )
-
-assert.equal((function(){
- // A <- X -> Y = no bias
- var g = $p("X E\nY O\nI A\n\nX Y\nX I")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- // X -> Y -> A = bias
- var g = $p("X E\nY O\nI A\n\nX Y\nY I")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "X Y\nY I" )
-
-assert.equal((function(){
- // X -> A -> Y = no bias
- var g = $p("X E\nY O\nI A\n\nX I\nI Y")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- return GraphTransformer.activeBiasGraph(TestGraphs.felixadjust).toAdjacencyList()
-})(), "s1 s2 z\ns2 s3\ns3 y\nx s1" )
-
-assert.equal((function(){
- var g = $p("A E @1,1\nB O @3,1\nC 1 @2,1\n\nA B\nB C")
- return g.hasCompleteLayout()
-})(), true )
-
-assert.equal((function(){
- var g = $p("A E @1,1\nB O\nC 1 @1,1\n\nA B\nB C")
- return g.hasCompleteLayout()
-})(), false )
-
-assert.equal((function(){
- var g = $p("A E\nB O\nC 1\n\nA B\nB C");
- return g.hasCompleteLayout()
-})(), false )
-
-assert.equal((function(){
- var g = $p("A E\nB O\nC 1\n\nA B\nB C");
- g.deleteVertex(g.getVertex("A"));
- return g.getSources().length;
-})(), 0 )
-
-assert.equal((function(){
- var g = $p("D O\nD2 O\nE E\nE2 E\n\nD E\nD2 E2")
- //console.log(g.toString())
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "D E\nD2 E2" )
-
-assert.equal((function(){
- var g = $p("ein A 1\n"+
-"ein B 1\n"+
-"\n"+
-"ein A ein B");
- return g.oldToString();
-})(), "ein%20A 1\nein%20B 1\n\nein%20A ein%20B" )
-
-assert.equal((function(){
- var g = $p("A E\nB O\nE E\nZ\nU\n\nA U\nB Z\nZ E\nU Z");
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{U, Z}" )
-
-assert.equal((function(){
- var g = $p("E E\nD O\nA 1\nB U\nZ 1\n\nA E Z\nB D Z\nZ E D\nE D");
- return GraphAnalyzer.directEffectEqualsTotalEffect( g )
-})(), true )
-
-assert.equal((function(){
- var g = $p("E E\nD O\nA 1\nB U\nZ 1\n\nA E Z\nB D Z\nZ D\nE D Z");
- return GraphAnalyzer.directEffectEqualsTotalEffect( g )
-})(), false )
-
-assert.equal((function(){
- var g = $p("E E\nD O\nA 1\nB U\nZ 1\n\nA E Z\nB D Z\nZ E D");
- return sep_2_str( GraphAnalyzer.listMsasTotalEffect( g ) );
-})(), "{A, Z}" )
-
-assert.equal((function(){
- var g = $p("E E\nD O\nA 1\nB U\nZ 1\n\nA E Z\nB D Z\nZ E D");
- return sep_2_str( GraphAnalyzer.listMinimalSeparators(GraphTransformer.moralGraph(g)) );
-})(), "{A, Z}\n{B, Z}" )
-
-assert.equal((function(){;
- var g = TestGraphs.small3();
- g.addAdjustedNode("p");
- var abg = GraphTransformer.activeBiasGraph(g);
- return GraphTransformer.edgeInducedSubgraph(g,abg.edges).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- var g = $p("E E @-1.897,0.342\n"+
-"D O @-0.067,0.302\n"+
-"g A @-0.889,1.191\n"+
-"\n"+
-"D g\n"+
-"E D");
- return _.pluck(GraphAnalyzer.nodesThatViolateAdjustmentCriterion( g ),'id').join(",");
-})(), "g" )
-
-assert.equal((function(){
- var g = $p("X1 E\nX2 E\nY1 O\nY2 O\nU1 1\nU2 1\n\nU1 X1 X2\nU2 Y1 Y2")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- var g = $p("A E\nB O\nC O\nD A\n\nA B\nB C\nC D")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "A B\nB C\nC D" )
-
-assert.equal((function(){
- var g = $p("A E\nB O\nC O\n\nA B\nB C")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- var g = $p("X1 E\nY1 O\nY2 O\nD A\n\nX1 Y1\nY1 Y2\nY2 D")
- return GraphAnalyzer.directEffectEqualsTotalEffect( g )
-})(), true )
-
-assert.equal((function(){
- var g = $p("X1 E\nY1 O\nY2 O\nD A\n\nX1 Y1\nY2 D")
- return GraphAnalyzer.directEffectEqualsTotalEffect( g )
-})(), true )
-
-assert.equal((function(){
- var g = $p("X1 E\nY1 O\nY2 O\nD A\n\nX1 Y1\nY1 Y2\nY2 D")
- return sep_2_str( GraphAnalyzer.listMsasDirectEffect( g ) )
-})(), "" )
-
-assert.equal((function(){
- var g = $p("X1 E\nY1 O\nY2 O\nD A\n\nX1 Y1\nY2 D")
- return sep_2_str( GraphAnalyzer.listMsasDirectEffect( g ) )
-})(), "{D}" )
-
-assert.equal((function(){
- var g = $p("X1 E\nY1 O\nY2 O\nD A\n\nX1 Y1\nY1 Y2\nY2 D")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "X1 Y1\nY1 Y2\nY2 D" )
-
-assert.equal((function(){
- var g = $p("X1 E\nY1 O\nY2 O\nD A\n\nX1 Y1\nY2 D")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- var g = $p("X1 E\nX2 E\nY1 O\nY2 O\n\nX1 Y1 X2\nY2 X2")
- //console.log(g.toString())
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "Y2 X2" )
-
-assert.equal((function(){
- var g = $p("X1 E\nX2 E\n\nX1 X2")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- var g = $p("X1 E\nX2 E\nY1 O\nY2 O\n\nX1 Y1 X2\nX2 Y2")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- var g = $p("X1 E\nX2 E\nY1 O\nY2 O\n\nX1 Y1 X2\nX2 Y2")
- return _.pluck(
- _.difference(GraphAnalyzer.properPossibleCausalPaths(g),g.getSources()),
- "id").sort().join(",")
-})(), "Y1,Y2" )
-
-
-assert.equal((function(){
- // X -> I -> Y, I -> A, adjust I = no bias
- var g = $p("X E\nY O\nI A\nJ A\n\nX I\nI J Y")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- // X -> I -> Y, I <- M -> Y, I -> A, adjust M, I = no bias
- var g = $p("X E\nY O\nI A\nJ A\nM A\n\nX I\nI J Y\nM I Y")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- // X -> I -> Y, I <- M -> Y, I -> A, adjust M = bias
- var g = $p("X E\nY O\nI 1\nJ A\nM A\n\nX I\nI J Y\nM I Y")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "I J Y\nX I" )
-
-
-assert.equal((function(){
- var g = TestGraphs.findExample( "Shrier" )
- var r = ""
- var v1,v2,vv=g.getVertices()
- for( var i = 0 ; i < vv.length ; i ++ ){
- for( var j = 0 ; j < vv.length ; j ++ ){
- var c = GraphAnalyzer.minVertexCut( g, [vv[i]], [vv[j]] )
- if( c > 0 ) r += vv[i].id + " " + vv[j].id + " " + c + "\n"
- }
- }
- return r
-})(), "WarmUpExercises Injury 1\nCoach WarmUpExercises 2\nCoach Injury 2\nCoach PreGameProprioception 1\nCoach PreviousInjury 1\nCoach IntraGameProprioception 2\nCoach NeuromuscularFatigue 1\nGenetics WarmUpExercises 1\nGenetics Injury 3\nGenetics PreGameProprioception 1\nGenetics TissueWeakness 1\nGenetics IntraGameProprioception 2\nTeamMotivation Injury 1\nTeamMotivation IntraGameProprioception 1\nPreGameProprioception Injury 1\nPreGameProprioception IntraGameProprioception 1\nConnectiveTissueDisorder Injury 2\nConnectiveTissueDisorder IntraGameProprioception 1\nContactSport Injury 1\nFitnessLevel WarmUpExercises 1\nFitnessLevel Injury 2\nFitnessLevel IntraGameProprioception 2\n" )
-
-assert.equal((function(){
- var g = $p("X E\nY O\nM 1\nN A\n\nX M\nM N Y")
- return GraphTransformer.flowNetwork(g).graph.toAdjacencyList()
-})(), "M N X Y\nN M\nX M __SRC\nY M __SNK\n__SNK Y\n__SRC X" )
-
-assert.equal((function(){
- var g = $p("X E\nY O\nM 1\nN A\n\nX M\nM N Y")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "M N Y\nX M" )
-
-assert.equal((function(){
- var g = $p("X E\nY O\nM 1\nN A\n\nX M\nM N\nY M")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "X M\nY M" )
-
-assert.equal((function(){
- // our non-X-ancestor MSAS example from the UAI paper w/o causal edge
- var g = $p("X1 E\nX2 E\nY O\nM1 1\nM2 A\n\nX1 M1\nY M2\nM1 M2\nM2 X2")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "M1 M2\nX1 M1\nY M2" )
-
-assert.equal((function(){
- var g = $p("X E\nY O\nM 1\n\nY M\nM X")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "M X\nY M" )
-
-assert.equal((function(){
- var g = $p("X E\nY O\n\nY X")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "Y X" )
-
-assert.equal((function(){
- // our non-X-ancestor MSAS example from the UAI paper w/o causal edge
- var g = $p("X1 E\nX2 E\nY O\nM1 1\nM2 1\n\nX1 M1\nY M2\nM1 M2\nM2 X2")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "M2 X2\nY M2" )
-
-assert.equal((function(){
- var g = $p("X1 E\nY1 O\nY2 O\nM 1\n\nY1 M\nM Y2")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-assert.equal((function(){
- var g = $p("X1 E\nX2 E\nY1 O\nY2 O\nU1 1\nU2 1\n\nX1 U1\nU1 X2\nY1 U2\nU2 Y2")
- return GraphTransformer.activeBiasGraph(g).toAdjacencyList()
-})(), "" )
-
-
-assert.equal((function(){
- var g = TestGraphs.findExample( "Thoemmes" )
- return GraphAnalyzer.minVertexCut( g,
- [g.getVertex("e0"),g.getVertex("s2")],
- [g.getVertex("y")] )
-})(), 2 )
-
-assert.equal((function(){
- var g = $p("a 1\nb 1\nc 1\nd 1\ne 1\nm 1\nn 1\np 1\nu 1\nx E\ny O\n\n"
- +"a b\nb u\nc u n\nd e\ne c\nm a\nn p\np y\nu y\nx c d m")
- return GraphAnalyzer.minVertexCut( g, [g.getVertex("x")], [g.getVertex("y")] )
-})(), 2 )
-
-assert.equal((function(){
- var g = TestGraphs.findExample( "Confounding" )
- var r = ""
- var v1,v2,vv=g.getVertices()
- for( var i = 0 ; i < vv.length ; i ++ ){
- for( var j = 0 ; j < vv.length ; j ++ ){
- var c = GraphAnalyzer.minVertexCut( g, [vv[i]], [vv[j]] )
- if( c > 0 ) r += vv[i].id + " " + vv[j].id + " " + c + "\n"
- }
- }
- return r
-})(), "A D 2\nB E 1\n" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { y -> m \n m -> x }"
- ).addSource("x").addTarget("y")
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "m -> x\ny -> m" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { x [exposure]\ny [outcome]\na [adjusted]\n"+
- "x -> a\nu -> x\nu -> y }" )
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "u -> x\nu -> y" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { x [exposure]\ny [outcome]\na [adjusted]\n b [adjusted]\n"+
- "x -> a\nx -> b\nb -> a\ny -> b }" )
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "x -> b\ny -> b" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { x [exposure]\ny [outcome]\nm [adjusted]\nx -> m\ny -> m }" )
- g = GraphTransformer.canonicalDag( g ).g
- g = GraphTransformer.ancestorGraph( g )
- return ""+$es(g)
-})(), "x -> m\ny -> m" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { x [exposure]\ny [outcome]\nm [adjusted]\nx -> m\ny -> m }" )
- return $es(GraphTransformer.ancestorGraph(g))
-})(), "x -> m\ny -> m" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { b [exposure]\nc [outcome]\na [adjusted]\na -- b\na -- c }" )
- return GraphAnalyzer.connectedComponents(g).length
-})(), 1 )
-
-assert.equal((function(){
- var g = $p(
- "digraph G {a -- b }" )
- return GraphAnalyzer.connectedComponents(g).length
-})(), 1 )
-
-assert.equal((function(){
- var g = $p(
- "digraph G {a [exposure]\nb [outcome]\nc [adjusted]\na -> c\nb -> c }" )
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "a -> c\nb -> c" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G {a [exposure]\nb [outcome]\nc [adjusted]\na -> b\nb -> c }" )
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "a -> b\nb -> c" )
-
-assert.equal((function(){
- var g = TestGraphs.findExample("Acid")
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "x1 -> x3\nx1 -> x4\nx10 -> x15\nx4 -> x5\nx5 -> x7\nx7 -> x9\nx9 -> x10" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { a [exposure] \n b [outcome] \n a <-> c \n c -> b }" )
- return $es(GraphTransformer.canonicalDag(g).g)
-})(), "L1 -> a\nL1 -> c\nc -> b" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { a [exposure] \n b [outcome] \n a <-> c \n c -> b }" )
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "a <-> c\nc -> b" )
-
-assert.equal((function(){
- var g = $p( "digraph G { a -- b }" )
- var ids = _.pluck(GraphAnalyzer.connectedComponentAvoiding( g, [g.getVertex("a")] )
- ,"id")
- ids=ids.sort(); return ids.join(" ")
-})(), "a b" )
-
-assert.equal((function(){
- var g = $p(
- "digraph G { x [source] \n y [outcome] \n a [adjusted] \n "
- +"a -> x \n b -> a \n b -> y }"
- )
- return $es(GraphTransformer.activeBiasGraph(g))
-})(), "" )
-
-
-assert.equal( _.pluck(GraphAnalyzer.dpcp(
- $p( "digraph{ x [exposure]\n y [outcome]\n x -> y -- z }" ) ),"id").
- sort().join(","),
- "y,z" )
-
-assert.equal( _.pluck(GraphAnalyzer.dpcp(
- $p( "digraph{ x [exposure]\n y [outcome]\n x -- y -- z }" ) ),"id").
- sort().join(","),
- "x,y,z" )
-
-
-}); // end uncategorized tests
-