public boolean isIndependent(Node x, Node y, List<Node> z) {
    int[] all = new int[z.size() + 2];
    all[0] = variablesMap.get(x);
    all[1] = variablesMap.get(y);
    for (int i = 0; i < z.size(); i++) {
      all[i + 2] = variablesMap.get(z.get(i));
    }

    int sampleSize = data.get(0).rows();
    List<Double> pValues = new ArrayList<Double>();

    for (int m = 0; m < ncov.size(); m++) {
      TetradMatrix _ncov = ncov.get(m).getSelection(all, all);
      TetradMatrix inv = _ncov.inverse();
      double r = -inv.get(0, 1) / sqrt(inv.get(0, 0) * inv.get(1, 1));

      double fisherZ =
          sqrt(sampleSize - z.size() - 3.0) * 0.5 * (Math.log(1.0 + r) - Math.log(1.0 - r));
      double pValue;

      if (Double.isInfinite(fisherZ)) {
        pValue = 0;
      } else {
        pValue = 2.0 * (1.0 - RandomUtil.getInstance().normalCdf(0, 1, abs(fisherZ)));
      }

      pValues.add(pValue);
    }

    double _cutoff = alpha;

    if (fdr) {
      _cutoff = StatUtils.fdrCutoff(alpha, pValues, false);
    }

    Collections.sort(pValues);
    int index = (int) round((1.0 - percent) * pValues.size());
    this.pValue = pValues.get(index);

    //        if (this.pValue == 0) {
    //            System.out.println("Zero pvalue "+ SearchLogUtils.independenceFactMsg(x, y, z,
    // getPValue()));
    //        }

    boolean independent = this.pValue > _cutoff;

    if (verbose) {
      if (independent) {
        TetradLogger.getInstance()
            .log("independencies", SearchLogUtils.independenceFactMsg(x, y, z, getPValue()));
        //            System.out.println(SearchLogUtils.independenceFactMsg(x, y, z, getPValue()));
      } else {
        TetradLogger.getInstance()
            .log("dependencies", SearchLogUtils.dependenceFactMsg(x, y, z, getPValue()));
      }
    }

    return independent;
  }
Example #2
0
  /**
   * Step C of PC; orients colliders using specified sepset. That is, orients x *-* y *-* z as x *->
   * y <-* z just in case y is in Sepset({x, z}).
   */
  public Map<Triple, Double> findCollidersUsingSepsets(
      SepsetProducer sepsetProducer, Graph graph, boolean verbose, IKnowledge knowledge) {
    TetradLogger.getInstance().log("details", "Starting Collider Orientation:");
    Map<Triple, Double> colliders = new HashMap<>();

    System.out.println("Looking for colliders");

    List<Node> nodes = graph.getNodes();

    for (Node b : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(b);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node a = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(a, c)) {
          continue;
        }

        List<Node> sepset = sepsetProducer.getSepset(a, c);

        if (sepset == null) continue;

        //                if (sepsetProducer.getPValue() < 0.5) continue;

        if (!sepset.contains(b)) {
          if (verbose) {
            //                        boolean dsep = this.dsep.isIndependent(a, c);
            //                        System.out.println("QQQ p = " + independenceTest.getPValue() +
            // " " + dsep);

            System.out.println(
                "\nCollider orientation <" + a + ", " + b + ", " + c + "> sepset = " + sepset);
          }

          colliders.put(new Triple(a, b, c), sepsetProducer.getPValue());

          TetradLogger.getInstance()
              .log("colliderOrientations", SearchLogUtils.colliderOrientedMsg(a, b, c, sepset));
        }
      }
    }

    TetradLogger.getInstance().log("details", "Finishing Collider Orientation.");

    System.out.println("Done finding colliders");

    return colliders;
  }
Example #3
0
  /**
   * Completes a pattern that was modified by an insertion/deletion operator Based on the algorithm
   * described on Appendix C of (Chickering, 2002).
   */
  private void rebuildPattern(Graph graph) {
    SearchGraphUtils.basicPattern(graph, false);
    addRequiredEdges(graph);
    meekOrient(graph, getKnowledge());

    if (TetradLogger.getInstance().isEventActive("rebuiltPatterns")) {
      TetradLogger.getInstance().log("rebuiltPatterns", "Rebuilt pattern = " + graph);
    }
  }
  public static boolean meekR1Locally2(
      Graph graph, Knowledge knowledge, IndependenceTest test, int depth) {
    List<Node> nodes = graph.getNodes();
    boolean changed = true;

    while (changed) {
      changed = false;

      for (Node a : nodes) {
        List<Node> adjacentNodes = graph.getAdjacentNodes(a);

        if (adjacentNodes.size() < 2) {
          continue;
        }

        ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
        int[] combination;

        while ((combination = cg.next()) != null) {
          Node b = adjacentNodes.get(combination[0]);
          Node c = adjacentNodes.get(combination[1]);

          // Skip triples that are shielded.
          if (graph.isAdjacentTo(b, c)) {
            continue;
          }

          if (graph.getEndpoint(b, a) == Endpoint.ARROW && graph.isUndirectedFromTo(a, c)) {
            if (existsLocalSepsetWithoutDet(b, a, c, test, graph, depth)) {
              continue;
            }

            if (isArrowpointAllowed(a, c, knowledge)) {
              graph.setEndpoint(a, c, Endpoint.ARROW);
              TetradLogger.getInstance()
                  .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R1", graph.getEdge(a, c)));
              changed = true;
            }
          } else if (graph.getEndpoint(c, a) == Endpoint.ARROW && graph.isUndirectedFromTo(a, b)) {
            if (existsLocalSepsetWithoutDet(b, a, c, test, graph, depth)) {
              continue;
            }

            if (isArrowpointAllowed(a, b, knowledge)) {
              graph.setEndpoint(a, b, Endpoint.ARROW);
              TetradLogger.getInstance()
                  .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R1", graph.getEdge(a, b)));
              changed = true;
            }
          }
        }
      }
    }

    return changed;
  }
  /**
   * Performs step C of the algorithm, as indicated on page xxx of CPS, with the modification that
   * X--W--Y is oriented as X-->W<--Y if W is *determined by* the sepset of (X, Y), rather than W
   * just being *in* the sepset of (X, Y).
   */
  public static void pcdOrientC(
      SepsetMap set, IndependenceTest test, Knowledge knowledge, Graph graph) {
    TetradLogger.getInstance().log("info", "Staring Collider Orientation:");

    List<Node> nodes = graph.getNodes();

    for (Node y : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(y);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node x = adjacentNodes.get(combination[0]);
        Node z = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(x, z)) {
          continue;
        }

        List<Node> sepset = set.get(x, z);

        if (sepset == null) {
          continue;
        }

        List<Node> augmentedSet = new LinkedList<Node>(sepset);
        augmentedSet.add(y);

        if (test.determines(sepset, y)) {
          continue;
        }
        //
        if (!test.splitDetermines(sepset, x, z) && test.splitDetermines(augmentedSet, x, z)) {
          continue;
        }

        if (!isArrowpointAllowed(x, y, knowledge) || !isArrowpointAllowed(z, y, knowledge)) {
          continue;
        }

        graph.setEndpoint(x, y, Endpoint.ARROW);
        graph.setEndpoint(z, y, Endpoint.ARROW);

        TetradLogger.getInstance()
            .log("colliderOriented", SearchLogUtils.colliderOrientedMsg(x, y, z));
      }
    }

    TetradLogger.getInstance().log("info", "Finishing Collider Orientation.");
  }
 public void configurationActived(TetradLoggerEvent evt) {
   TetradLoggerConfig config = evt.getTetradLoggerConfig();
   // if logging is actually turned on, then open display.
   if (TetradLogger.getInstance().isLogging()
       && config.isActive()
       && TetradLogger.getInstance().isDisplayLogEnabled()) {
     // if the log display isn't already up, open it.
     if (!isDisplayLogging() && allowAutomaticLogPopup()) {
       setDisplayLogging(true);
     }
   }
 }
  /** Orients according to background knowledge. */
  public static void pcOrientbk(Knowledge bk, Graph graph, List<Node> nodes) {
    TetradLogger.getInstance().log("info", "Staring BK Orientation.");
    for (Iterator<KnowledgeEdge> it = bk.forbiddenEdgesIterator(); it.hasNext(); ) {
      KnowledgeEdge edge = it.next();

      // match strings to variables in the graph.
      Node from = translate(edge.getFrom(), nodes);
      Node to = translate(edge.getTo(), nodes);

      if (from == null || to == null) {
        continue;
      }

      if (graph.getEdge(from, to) == null) {
        continue;
      }

      // Orient to-->from
      graph.removeEdge(from, to);
      graph.addDirectedEdge(from, to);
      graph.setEndpoint(from, to, Endpoint.TAIL);
      graph.setEndpoint(to, from, Endpoint.ARROW);

      TetradLogger.getInstance()
          .edgeOriented(SearchLogUtils.edgeOrientedMsg("Knowledge", graph.getEdge(to, from)));
    }

    for (Iterator<KnowledgeEdge> it = bk.requiredEdgesIterator(); it.hasNext(); ) {
      KnowledgeEdge edge = it.next();

      // match strings to variables in this graph
      Node from = translate(edge.getFrom(), nodes);
      Node to = translate(edge.getTo(), nodes);

      if (from == null || to == null) {
        continue;
      }

      if (graph.getEdge(from, to) == null) {
        continue;
      }

      // Orient from-->to
      graph.setEndpoint(to, from, Endpoint.TAIL);
      graph.setEndpoint(from, to, Endpoint.ARROW);
      TetradLogger.getInstance()
          .edgeOriented(SearchLogUtils.edgeOrientedMsg("Knowledge", graph.getEdge(from, to)));
    }
    TetradLogger.getInstance().log("info", "Finishing BK Orientation.");
  }
Example #8
0
  private void ruleR1(Graph skeleton, Graph graph, List<Node> nodes) {
    for (Node node : nodes) {
      SortedMap<Double, String> scoreReports = new TreeMap<Double, String>();

      List<Node> adj = skeleton.getAdjacentNodes(node);

      DepthChoiceGenerator gen = new DepthChoiceGenerator(adj.size(), adj.size());
      int[] choice;
      double maxScore = Double.NEGATIVE_INFINITY;
      List<Node> parents = null;

      while ((choice = gen.next()) != null) {
        List<Node> _parents = GraphUtils.asList(choice, adj);

        double score = score(node, _parents);
        scoreReports.put(-score, _parents.toString());

        if (score > maxScore) {
          maxScore = score;
          parents = _parents;
        }
      }

      for (double score : scoreReports.keySet()) {
        TetradLogger.getInstance()
            .log(
                "score",
                "For " + node + " parents = " + scoreReports.get(score) + " score = " + -score);
      }

      TetradLogger.getInstance().log("score", "");

      if (parents == null) {
        continue;
      }

      if (normal(node, parents)) continue;

      for (Node _node : adj) {
        if (parents.contains(_node)) {
          Edge parentEdge = Edges.directedEdge(_node, node);

          if (!graph.containsEdge(parentEdge)) {
            graph.addEdge(parentEdge);
          }
        }
      }
    }
  }
  private boolean isIndependentMultinomialLogisticRegression(Node x, Node y, List<Node> z) {
    double p = dependencePvalsLogit(x, y, z)[0];
    boolean indep = p > alpha;
    // 0 corresponds to y
    this.lastP = p;

    if (indep) {
      TetradLogger.getInstance()
          .log("independencies", SearchLogUtils.independenceFactMsg(x, y, z, p));
    } else {
      TetradLogger.getInstance().log("dependencies", SearchLogUtils.dependenceFactMsg(x, y, z, p));
    }

    return indep;
  }
  public static void orientUsingMeekRulesLocally2(
      Knowledge knowledge, Graph graph, IndependenceTest test, int depth) {
    TetradLogger.getInstance().log("info", "Starting Orientation Step D.");
    boolean changed;

    do {
      changed =
          meekR1Locally2(graph, knowledge, test, depth)
              || meekR2(graph, knowledge)
              || meekR3(graph, knowledge)
              || meekR4(graph, knowledge);
    } while (changed);

    TetradLogger.getInstance().log("info", "Finishing Orientation Step D.");
  }
  private void log(String s, boolean toLog) {
    if (toLog) {
      TetradLogger.getInstance().log("info", s);
    }

    //        System.out.println(s);
  }
Example #12
0
  private void bes(Graph graph) {
    TetradLogger.getInstance().log("info", "** BACKWARD EQUIVALENCE SEARCH");

    initializeArrowsBackward(graph);

    while (!sortedArrows.isEmpty()) {
      Arrow arrow = sortedArrows.first();
      sortedArrows.remove(arrow);

      Node x = arrow.getX();
      Node y = arrow.getY();

      clearArrow(x, y);

      if (!validDelete(arrow.getHOrT(), arrow.getNaYX(), graph)) {
        continue;
      }

      List<Node> h = arrow.getHOrT();
      double bump = arrow.getBump();

      delete(x, y, h, graph, bump);
      score += bump;
      rebuildPattern(graph);

      storeGraph(graph);

      initializeArrowsBackward(
          graph); // Rebuilds Arrows from scratch each time. Fast enough for backwards.
    }
  }
  private boolean isIndependentRegression(Node x, Node y, List<Node> z) {
    double p = dependencePvalsLinear(x, y, z)[0];
    // result.getP()[1];
    this.lastP = p;

    boolean indep = p > alpha;

    if (verbose) {
      if (indep) {
        TetradLogger.getInstance()
            .log("independencies", SearchLogUtils.independenceFactMsg(x, y, z, p));
      } else {
        TetradLogger.getInstance()
            .log("dependencies", SearchLogUtils.dependenceFactMsg(x, y, z, p));
      }
    }

    return indep;
  }
Example #14
0
  /**
   * Searches for the Markov blanket of the node by the given name.
   *
   * @param targetName The name of the target node.
   * @return The Markov blanket of the target.
   */
  public List<Node> findMb(String targetName) {
    TetradLogger.getInstance().log("info", "target = " + targetName);
    numIndTests = 0;
    long time = System.currentTimeMillis();

    pc = new HashMap<>();
    trimmed = new HashSet<>();

    Node target = getVariableForName(targetName);
    List<Node> nodes = mmmb(target);

    long time2 = System.currentTimeMillis() - time;
    TetradLogger.getInstance().log("info", "Number of seconds: " + (time2 / 1000.0));
    TetradLogger.getInstance()
        .log("info", "Number of independence tests performed: " + numIndTests);
    //        System.out.println("Number of calls to mmpc = " + pc.size());

    return nodes;
  }
  /** Meek's rule R3. If a--b, a--c, a--d, c-->b, c-->b, then orient a-->b. */
  public static boolean meekR3(Graph graph, Knowledge knowledge) {

    List<Node> nodes = graph.getNodes();
    boolean changed = false;

    for (Node a : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(a);

      if (adjacentNodes.size() < 3) {
        continue;
      }

      for (Node b : adjacentNodes) {
        List<Node> otherAdjacents = new LinkedList<Node>(adjacentNodes);
        otherAdjacents.remove(b);

        if (!graph.isUndirectedFromTo(a, b)) {
          continue;
        }

        ChoiceGenerator cg = new ChoiceGenerator(otherAdjacents.size(), 2);
        int[] combination;

        while ((combination = cg.next()) != null) {
          Node c = otherAdjacents.get(combination[0]);
          Node d = otherAdjacents.get(combination[1]);

          if (graph.isAdjacentTo(c, d)) {
            continue;
          }

          if (!graph.isUndirectedFromTo(a, c)) {
            continue;
          }

          if (!graph.isUndirectedFromTo(a, d)) {
            continue;
          }

          if (graph.isDirectedFromTo(c, b) && graph.isDirectedFromTo(d, b)) {
            if (isArrowpointAllowed(a, b, knowledge)) {
              graph.setEndpoint(a, b, Endpoint.ARROW);
              TetradLogger.getInstance()
                  .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R3", graph.getEdge(a, b)));
              changed = true;
              break;
            }
          }
        }
      }
    }

    return changed;
  }
  /**
   * Step C of PC; orients colliders using specified sepset. That is, orients x *-* y *-* z as x *->
   * y <-* z just in case y is in Sepset({x, z}).
   */
  public static void orientCollidersUsingSepsets(SepsetMap set, Knowledge knowledge, Graph graph) {
    TetradLogger.getInstance().log("info", "Starting Collider Orientation:");

    //        verifySepsetIntegrity(set, graph);

    List<Node> nodes = graph.getNodes();

    for (Node a : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(a);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node b = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(b, c)) {
          continue;
        }

        List<Node> sepset = set.get(b, c);
        if (sepset != null
            && !sepset.contains(a)
            && isArrowpointAllowed(b, a, knowledge)
            && isArrowpointAllowed(c, a, knowledge)) {
          graph.setEndpoint(b, a, Endpoint.ARROW);
          graph.setEndpoint(c, a, Endpoint.ARROW);
          TetradLogger.getInstance()
              .log("colliderOriented", SearchLogUtils.colliderOrientedMsg(b, a, c, sepset));
        }
      }
    }

    TetradLogger.getInstance().log("info", "Finishing Collider Orientation.");
  }
  /** If */
  public static boolean meekR2(Graph graph, Knowledge knowledge) {
    List<Node> nodes = graph.getNodes();
    boolean changed = false;

    for (Node a : nodes) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(a);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node b = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        if (graph.isDirectedFromTo(b, a)
            && graph.isDirectedFromTo(a, c)
            && graph.isUndirectedFromTo(b, c)) {
          if (isArrowpointAllowed(b, c, knowledge)) {
            graph.setEndpoint(b, c, Endpoint.ARROW);
            TetradLogger.getInstance()
                .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R2", graph.getEdge(b, c)));
          }
        } else if (graph.isDirectedFromTo(c, a)
            && graph.isDirectedFromTo(a, b)
            && graph.isUndirectedFromTo(c, b)) {
          if (isArrowpointAllowed(c, b, knowledge)) {
            graph.setEndpoint(c, b, Endpoint.ARROW);
            TetradLogger.getInstance()
                .edgeOriented(SearchLogUtils.edgeOrientedMsg("Meek R2", graph.getEdge(c, b)));
          }
        }
      }
    }

    return changed;
  }
  public static void orientCollidersLocally(
      Knowledge knowledge, Graph graph, IndependenceTest test, int depth, Set<Node> nodesToVisit) {
    TetradLogger.getInstance().log("info", "Starting Collider Orientation:");

    if (nodesToVisit == null) {
      nodesToVisit = new HashSet<Node>(graph.getNodes());
    }

    for (Node a : nodesToVisit) {
      List<Node> adjacentNodes = graph.getAdjacentNodes(a);

      if (adjacentNodes.size() < 2) {
        continue;
      }

      ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
      int[] combination;

      while ((combination = cg.next()) != null) {
        Node b = adjacentNodes.get(combination[0]);
        Node c = adjacentNodes.get(combination[1]);

        // Skip triples that are shielded.
        if (graph.isAdjacentTo(b, c)) {
          continue;
        }

        if (isArrowpointAllowed1(b, a, knowledge) && isArrowpointAllowed1(c, a, knowledge)) {
          if (!existsLocalSepsetWith(b, a, c, test, graph, depth)) {
            graph.setEndpoint(b, a, Endpoint.ARROW);
            graph.setEndpoint(c, a, Endpoint.ARROW);
            TetradLogger.getInstance()
                .log("colliderOriented", SearchLogUtils.colliderOrientedMsg(b, a, c));
          }
        }
      }
    }

    TetradLogger.getInstance().log("info", "Finishing Collider Orientation.");
  }
 /**
  * Sets whether the display log output should be displayed or not. If true then a text area
  * roughly 20% of the screen size will appear on the bottom and will display any log output,
  * otherwise just the standard tetrad workbend is shown.
  *
  * @param displayLogging
  */
 public void setDisplayLogging(boolean displayLogging) {
   if (displayLogging) {
     this.logArea = new TetradLogArea(this);
   } else {
     if (this.logArea != null) {
       TetradLogger.getInstance().removeOutputStream(this.logArea.getOutputStream());
     }
     this.logArea = null;
   }
   setupDesktop();
   revalidate();
   repaint();
 }
  /**
   * States whether the log display should be automatically displayed, if there is no value in the
   * user's prefs then it will display a prompt asking the user whether they would like to disable
   * automatic popups.
   */
  private boolean allowAutomaticLogPopup() {
    Boolean allowed = TetradLogger.getInstance().isAutomaticLogDisplayEnabled();
    // ask the user whether they way the feature etc.
    if (allowed == null) {
      String message =
          "<html>Whenever Tetrad's logging features are active any generated log <br>"
              + "output will be automatically display in Tetrad's log display. Would you like Tetrad<br>"
              + "to continue to automatically open the log display window whenever there is logging output?</html>";
      int option =
          JOptionPane.showConfirmDialog(
              this, message, "Automatic Logging", JOptionPane.YES_NO_OPTION);
      if (option == JOptionPane.NO_OPTION) {
        JOptionPane.showMessageDialog(
            this, "This feature can be enabled later by going to Logging>Setup Logging.");
      }
      TetradLogger.getInstance().setAutomaticLogDisplayEnabled(option == JOptionPane.YES_OPTION);
      // return true, so that opens this time, in the future the user's pref will be used.
      return true;
    }

    return allowed;
  }
  /** Constructs a new desktop. */
  public TetradDesktop() {
    setBackground(new Color(204, 204, 204));
    sessionNodeKeys = new ArrayList();
    // Create the desktop pane.
    this.desktopPane = new JDesktopPane();

    // Do layout.
    setLayout(new BorderLayout());
    desktopPane.setDesktopManager(new DefaultDesktopManager());
    desktopPane.setBorder(new BevelBorder(BevelBorder.LOWERED));
    desktopPane.addPropertyChangeListener(this);

    this.setupDesktop();
    TetradLogger.getInstance().addTetradLoggerListener(new LoggerListener());
  }
Example #22
0
  /**
   * Forward equivalence search.
   *
   * @param graph The graph in the state prior to the forward equivalence search.
   */
  private void fes(Graph graph, List<Node> nodes) {
    TetradLogger.getInstance().log("info", "** FORWARD EQUIVALENCE SEARCH");

    lookupArrows = new HashMap<OrderedPair, Set<Arrow>>();

    initializeArrowsForward(nodes);

    while (!sortedArrows.isEmpty()) {
      Arrow arrow = sortedArrows.first();
      sortedArrows.remove(arrow);

      Node x = arrow.getX();
      Node y = arrow.getY();

      clearArrow(x, y);

      if (graph.isAdjacentTo(x, y)) {
        continue;
      }

      if (!validInsert(x, y, arrow.getHOrT(), arrow.getNaYX(), graph)) {
        continue;
      }

      List<Node> t = arrow.getHOrT();
      double bump = arrow.getBump();

      Set<Edge> edges = graph.getEdges();

      insert(x, y, t, graph, bump);
      score += bump;
      rebuildPattern(graph);

      // Try to avoid duplicating scoring calls. First clear out all of the edges that need to be
      // changed,
      // then change them, checking to see if they're already been changed. I know, roundabout, but
      // there's
      // a performance boost.
      for (Edge edge : graph.getEdges()) {
        if (!edges.contains(edge)) {
          reevaluateForward(graph, nodes, edge.getNode1(), edge.getNode2());
        }
      }

      storeGraph(graph);
    }
  }
Example #23
0
  /** @return the p value for the most recent test. */
  @Override
  public double getPValue() {
    double cdf = ProbUtils.chisqCdf(this.chisq, this.df);
    double p = 1.0 - cdf;

    String s = "";

    for (int i = 0; i < storedSextads.length; i++) {
      s += storedSextads[i] + " ";
    }

    s += "value = " + nf.format(storedValue) + " p = " + nf.format(p);

    TetradLogger.getInstance().log("sextadPValues", s);

    return p;
  }
  public static boolean existsLocalSepsetWithoutDet(
      Node x, Node y, Node z, IndependenceTest test, Graph graph, int depth) {
    Set<Node> __nodes = new HashSet<Node>(graph.getAdjacentNodes(x));
    __nodes.addAll(graph.getAdjacentNodes(z));
    __nodes.remove(x);
    __nodes.remove(z);
    List<Node> _nodes = new LinkedList<Node>(__nodes);
    TetradLogger.getInstance()
        .log("adjacencies", "Adjacents for " + x + "--" + y + "--" + z + " = " + _nodes);

    int _depth = depth;
    if (_depth == -1) {
      _depth = 1000;
    }
    _depth = Math.min(_depth, _nodes.size());

    for (int d = 0; d <= _depth; d++) {
      if (_nodes.size() >= d) {
        ChoiceGenerator cg2 = new ChoiceGenerator(_nodes.size(), d);
        int[] choice;

        while ((choice = cg2.next()) != null) {
          List<Node> condSet = asList(choice, _nodes);

          if (condSet.contains(y)) {
            continue;
          }

          if (test.determines(condSet, y)) {
            continue;
          }

          //        LogUtils.getInstance().finest("Trying " + condSet);

          if (test.isIndependent(x, z, condSet)) {
            return true;
          }
        }
      }
    }

    return false;
  }
Example #25
0
  private List<Node> mmpc(Node t) {
    List<Node> pc = new LinkedList<>();
    boolean pcIncreased = true;

    // First optimization: Don't consider adding again variables that have
    // already been found independent of t.
    List<Node> indepOfT = new LinkedList<>();

    // Phase 1
    while (pcIncreased) {
      pcIncreased = false;

      MaxMinAssocResult ret = maxMinAssoc(t, pc, indepOfT);
      Node f = ret.getNode();
      List<Node> assocSet = ret.getAssocSet();

      if (f == null) {
        break;
      }

      numIndTests++;

      if (!independenceTest.isIndependent(f, t, assocSet)) {
        pcIncreased = true;
        pc.add(f);
      }
    }

    // Phase 2.
    backwardsConditioning(pc, t);

    TetradLogger.getInstance().log("details", "PC(" + t + ") = " + pc);
    //        System.out.println("PC(" + t + ") = " + pc);

    return pc;
  }
Example #26
0
 private void log(BayesIm im) {
   TetradLogger.getInstance().log("info", "Maximum likelihood Bayes IM: Observed Variables Only");
   TetradLogger.getInstance().log("im", im.toString());
 }
Example #27
0
/**
 * Implements the PC ("Peter/Clark") algorithm, as specified in Chapter 6 of Spirtes, Glymour, and
 * Scheines, "Causation, Prediction, and Search," 2nd edition, with a modified rule set in step D
 * due to Chris Meek. For the modified rule set, see Chris Meek (1995), "Causal inference and causal
 * explanation with background knowledge."
 *
 * <p>In addition, the PC Stable modification to PC has been included (Colombo and Maathuis).
 *
 * @author Joseph Ramsey.
 */
public class PcStable implements GraphSearch {

  /** The independence test used for the PC search. */
  private IndependenceTest independenceTest;

  /** Forbidden and required edges for the search. */
  private IKnowledge knowledge = new Knowledge();

  /** Sepset information accumulated in the search. */
  private SepsetMap sepsets;

  /** The maximum number of nodes conditioned on in the search. The default it 1000. */
  private int depth = 1000;

  /** The graph that's constructed during the search. */
  private Graph graph;

  /** Elapsed time of the most recent search. */
  private long elapsedTime;

  /**
   * True if cycles are to be aggressively prevented. May be expensive for large graphs (but also
   * useful for large graphs).
   */
  private boolean aggressivelyPreventCycles = false;

  /** The logger for this class. The config needs to be set. */
  private TetradLogger logger = TetradLogger.getInstance();

  /** The initial graph for the Fast Adjacency Search, or null if there is none. */
  private Graph initialGraph = null;

  /** Prints independencies info to out. */
  private boolean verbose = false;

  private PrintStream out = System.out;

  // =============================CONSTRUCTORS==========================//

  /**
   * Constructs a new PC search using the given independence test as oracle.
   *
   * @param independenceTest The oracle for conditional independence facts. This does not make a
   *     copy of the independence test, for fear of duplicating the data set!
   */
  public PcStable(IndependenceTest independenceTest) {
    if (independenceTest == null) {
      throw new NullPointerException();
    }

    this.independenceTest = independenceTest;
  }

  // ==============================PUBLIC METHODS========================//

  /** @return true iff edges will not be added if they would create cycles. */
  public boolean isAggressivelyPreventCycles() {
    return this.aggressivelyPreventCycles;
  }

  /**
   * @param aggressivelyPreventCycles Set to true just in case edges will not be addeds if they
   *     would create cycles.
   */
  public void setAggressivelyPreventCycles(boolean aggressivelyPreventCycles) {
    this.aggressivelyPreventCycles = aggressivelyPreventCycles;
  }

  /** @return the independence test being used in the search. */
  public IndependenceTest getIndependenceTest() {
    return independenceTest;
  }

  /** @return the knowledge specification used in the search. Non-null. */
  public IKnowledge getKnowledge() {
    return knowledge;
  }

  /** Sets the knowledge specification to be used in the search. May not be null. */
  public void setKnowledge(IKnowledge knowledge) {
    if (knowledge == null) {
      throw new NullPointerException();
    }

    this.knowledge = knowledge;
  }

  /**
   * @return the sepset map from the most recent search. Non-null after the first call to <code>
   *     search()</code>.
   */
  public SepsetMap getSepsets() {
    return this.sepsets;
  }

  /**
   * @return the current depth of search--that is, the maximum number of conditioning nodes for any
   *     conditional independence checked.
   */
  public int getDepth() {
    return depth;
  }

  /**
   * Sets the depth of the search--that is, the maximum number of conditioning nodes for any
   * conditional independence checked.
   *
   * @param depth The depth of the search. The default is 1000. A value of -1 may be used to
   *     indicate that the depth should be high (1000). A value of Integer.MAX_VALUE may not be
   *     used, due to a bug on multi-core machines.
   */
  public void setDepth(int depth) {
    if (depth < -1) {
      throw new IllegalArgumentException("Depth must be -1 or >= 0: " + depth);
    }

    if (depth > 1000) {
      throw new IllegalArgumentException("Depth must be <= 1000.");
    }

    this.depth = depth;
  }

  /**
   * Runs PC starting with a complete graph over all nodes of the given conditional independence
   * test, using the given independence test and knowledge and returns the resultant graph. The
   * returned graph will be a pattern if the independence information is consistent with the
   * hypothesis that there are no latent common causes. It may, however, contain cycles or
   * bidirected edges if this assumption is not born out, either due to the actual presence of
   * latent common causes, or due to statistical errors in conditional independence judgments.
   */
  public Graph search() {
    return search(independenceTest.getVariables());
  }

  /**
   * Runs PC starting with a commplete graph over the given list of nodes, using the given
   * independence test and knowledge and returns the resultant graph. The returned graph will be a
   * pattern if the independence information is consistent with the hypothesis that there are no
   * latent common causes. It may, however, contain cycles or bidirected edges if this assumption is
   * not born out, either due to the actual presence of latent common causes, or due to statistical
   * errors in conditional independence judgments.
   *
   * <p>All of the given nodes must be in the domain of the given conditional independence test.
   */
  public Graph search(List<Node> nodes) {
    this.logger.log("info", "Starting PC algorithm");
    this.logger.log("info", "Independence test = " + getIndependenceTest() + ".");

    //        this.logger.log("info", "Variables " + independenceTest.getVariables());

    long startTime = System.currentTimeMillis();

    if (getIndependenceTest() == null) {
      throw new NullPointerException();
    }

    List allNodes = getIndependenceTest().getVariables();
    if (!allNodes.containsAll(nodes)) {
      throw new IllegalArgumentException(
          "All of the given nodes must " + "be in the domain of the independence test provided.");
    }

    graph = new EdgeListGraph(nodes);

    IFas fas = new FasStableConcurrent(initialGraph, getIndependenceTest());
    fas.setKnowledge(getKnowledge());
    fas.setDepth(getDepth());
    fas.setVerbose(verbose);

    graph = fas.search();
    sepsets = fas.getSepsets();

    SearchGraphUtils.pcOrientbk(knowledge, graph, nodes);
    //        SearchGraphUtils.orientCollidersUsingSepsets(this.sepsets, knowledge, graph,
    // initialGraph, verbose);
    //        SearchGraphUtils.orientCollidersUsingSepsets(this.sepsets, knowledge, graph, verbose);
    //        SearchGraphUtils.orientColeelidersLocally(knowledge, graph, independenceTest, depth);
    SearchGraphUtils.orientCollidersUsingSepsets(this.sepsets, knowledge, graph, verbose);

    MeekRules rules = new MeekRules();
    rules.setAggressivelyPreventCycles(this.aggressivelyPreventCycles);
    rules.setKnowledge(knowledge);
    rules.orientImplied(graph);

    this.logger.log("graph", "\nReturning this graph: " + graph);

    this.elapsedTime = System.currentTimeMillis() - startTime;

    this.logger.log("info", "Elapsed time = " + (elapsedTime) / 1000. + " s");
    this.logger.log("info", "Finishing PC Algorithm.");
    this.logger.flush();

    return graph;
  }

  /** @return the elapsed time of the search, in milliseconds. */
  public long getElapsedTime() {
    return elapsedTime;
  }

  // ===============================PRIVATE METHODS=======================//

  public List<Node> getNodes() {
    return graph.getNodes();
  }

  public void setInitialGraph(Graph initialGraph) {
    this.initialGraph = initialGraph;
  }

  public void setVerbose(boolean verbose) {
    this.verbose = verbose;
  }

  public void setOut(PrintStream out) {
    this.out = out;
  }

  public PrintStream getOut() {
    return out;
  }
}
  /**
   * Determines whether variable x is independent of variable y given a list of conditioning
   * variables z.
   *
   * @param x the one variable being compared.
   * @param y the second variable being compared.
   * @param z the list of conditioning variables.
   * @return true iff x _||_ y | z.
   * @throws RuntimeException if a matrix singularity is encountered.
   */
  public boolean isIndependent(Node x, Node y, List<Node> z) {
    TetradMatrix submatrix = subMatrix(x, y, z);
    double r = 0;

    try {
      r = StatUtils.partialCorrelation(submatrix);

      if (Double.isNaN((r)) || r < -1. || r > 1.) throw new RuntimeException();
    } catch (Exception e) {
      DepthChoiceGenerator gen = new DepthChoiceGenerator(z.size(), z.size());
      int[] choice;

      while ((choice = gen.next()) != null) {
        try {
          List<Node> z2 = new ArrayList<Node>(z);
          z2.removeAll(GraphUtils.asList(choice, z));
          submatrix = subMatrix(x, y, z2);
          r = StatUtils.partialCorrelation(submatrix);
        } catch (Exception e2) {
          continue;
        }

        //                if (Double.isNaN(r)) continue;
        //
        //                if (r > 1.) r = 1.;
        //                 if (r < -1.) r = -1.;

        if (Double.isNaN(r) || r < -1. || r > 1.) continue;

        break;
      }
    }

    // Either dividing by a zero standard deviation (in which case it's dependent) or doing a
    // regression
    // (effectively) with a multicolliarity
    if (Double.isNaN(r)) {
      int[] _z = new int[z.size()];
      //            for (int i = 0; i < _z.length; i++) _z[i] = i + 2;
      //
      ////            double varx = StatUtils.partialVariance(submatrix, 0, _z); // submatrix.get(0,
      // 0);
      ////            double vary = StatUtils.partialVariance(submatrix, 1, _z); //submatrix.get(1,
      // 1);
      //
      //            double varx = submatrix.get(0, 0);
      //            double vary = submatrix.get(1, 1);
      //
      //            if (varx * vary == 0) {
      return true;
      //            }
    }

    if (r > 1.) r = 1.;
    if (r < -1.) r = -1.;

    this.fisherZ =
        Math.sqrt(sampleSize() - z.size() - 3.0) * 0.5 * (Math.log(1.0 + r) - Math.log(1.0 - r));

    if (Double.isNaN(this.fisherZ)) {
      throw new IllegalArgumentException(
          "The Fisher's Z "
              + "score for independence fact "
              + x
              + " _||_ "
              + y
              + " | "
              + z
              + " is undefined. r = "
              + r);
    }

    boolean independent = getPValue() > alpha;

    if (independent) {
      TetradLogger.getInstance()
          .log("independencies", SearchLogUtils.independenceFactMsg(x, y, z, getPValue()));
    } else {
      TetradLogger.getInstance()
          .log("dependencies", SearchLogUtils.dependenceFactMsg(x, y, z, getPValue()));
    }

    return independent;
  }
Example #29
0
 private void log(BayesIm im) {
   TetradLogger.getInstance().log("info", "Maximum likelihood Bayes IM");
   TetradLogger.getInstance().log("im", im.toString());
 }
  public static CpcTripleType getCpcTripleType(
      Node x, Node y, Node z, IndependenceTest test, int depth, Graph graph) {
    //    	System.out.println("getCpcTripleType 1");

    boolean existsSepsetContainingY = false;
    boolean existsSepsetNotContainingY = false;

    Set<Node> __nodes = new HashSet<Node>(graph.getAdjacentNodes(x));
    __nodes.remove(z);

    //    	System.out.println("getCpcTripleType 2");

    List<Node> _nodes = new LinkedList<Node>(__nodes);
    TetradLogger.getInstance()
        .log("adjacencies", "Adjacents for " + x + "--" + y + "--" + z + " = " + _nodes);

    //        System.out.println("getCpcTripleType 3");

    int _depth = depth;
    if (_depth == -1) {
      _depth = 1000;
    }
    _depth = Math.min(_depth, _nodes.size());

    //    	System.out.println("getCpcTripleType 4");

    for (int d = 0; d <= _depth; d++) {
      //        	System.out.println("getCpcTripleType 5");

      ChoiceGenerator cg = new ChoiceGenerator(_nodes.size(), d);
      int[] choice;

      while ((choice = cg.next()) != null) {
        //            	System.out.println("getCpcTripleType 6");

        List<Node> condSet = GraphUtils.asList(choice, _nodes);

        //            	System.out.println("getCpcTripleType 7");

        if (test.isIndependent(x, z, condSet)) {
          if (condSet.contains(y)) {
            existsSepsetContainingY = true;
          } else {
            existsSepsetNotContainingY = true;
          }
        }
      }
    }

    //    	System.out.println("getCpcTripleType 8");

    __nodes = new HashSet<Node>(graph.getAdjacentNodes(z));
    __nodes.remove(x);

    _nodes = new LinkedList<Node>(__nodes);
    TetradLogger.getInstance()
        .log("adjacencies", "Adjacents for " + x + "--" + y + "--" + z + " = " + _nodes);

    //    	System.out.println("getCpcTripleType 9");

    _depth = depth;
    if (_depth == -1) {
      _depth = 1000;
    }
    _depth = Math.min(_depth, _nodes.size());

    //    	System.out.println("getCpcTripleType 10");

    for (int d = 0; d <= _depth; d++) {
      //        	System.out.println("getCpcTripleType 11");

      ChoiceGenerator cg = new ChoiceGenerator(_nodes.size(), d);
      int[] choice;

      while ((choice = cg.next()) != null) {
        List<Node> condSet = GraphUtils.asList(choice, _nodes);

        if (test.isIndependent(x, z, condSet)) {
          if (condSet.contains(y)) {
            existsSepsetContainingY = true;
          } else {
            existsSepsetNotContainingY = true;
          }
        }
      }
    }

    //    	System.out.println("getCpcTripleType 12");

    if (existsSepsetContainingY == existsSepsetNotContainingY) {
      return CpcTripleType.AMBIGUOUS;
    } else if (!existsSepsetNotContainingY) {
      return CpcTripleType.NONCOLLIDER;
    } else {
      return CpcTripleType.COLLIDER;
    }
  }