Class PagCache

java.lang.Object
edu.cmu.tetrad.util.PagCache

public final class PagCache extends Object
A thread-safe, identity-preserving cache that converts DAGs or MAGs to PAGs.

Design rationale.

  • Preserves identity. For a given input Graph object, getPag(Graph) always returns the same PAG instance. This is required because higher-level algorithms (e.g., FCI, GFCI) retain Node and Edge references from the returned PAG and assume their object identity remains stable across calls.
  • Detects and repairs external mutation. Callers may unintentionally mutate the cached PAG (for example, by adjusting endpoints). To guard against this, each cached entry stores a lightweight structural signature of the PAG. On every cache hit, PagCache recomputes this signature; if it has changed, the PAG is rebuilt from the original DAG/MAG and the cached instance is refreshed in place so that existing Node and Edge identities are preserved but the structure is restored to a legal state.
  • Source change detection. The cache also fingerprints the source graph’s structure (node names, edges, and endpoints). If that signature changes, the PAG is recomputed from scratch and the cache entry replaced.
  • No weak references. This implementation uses an IdentityHashMap rather than a WeakHashMap. Weak keys caused unpredictable evictions in long-running batch jobs; identity-based keys avoid that while keeping the semantics simple and deterministic.

In summary, PagCache ensures that each unique source graph maps to a single, internally consistent PAG object, automatically repaired if modified. This behavior is essential for FCI-style algorithms that rely on persistent object identity while still guaranteeing deterministic, legal PAGs across repeated calls.

  • Method Summary

    Modifier and Type
    Method
    Description
    void
    Clears the internal cache, removing all stored entries.
    static PagCache
    Provides access to the singleton instance of the PagCache class.
    @NotNull Graph
    getPag(Graph g, boolean excludeSelectionBias)
    Retrieves or computes a Partial Ancestral Graph (PAG) from the given input graph.
    @NotNull Graph
    getPag(Graph g, Knowledge knowledge, boolean excludeSelectionBias, int recursiveDepth)
    Retrieves or computes a PAG (Partial Ancestral Graph) from the given input graph.

    Methods inherited from class Object

    equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • getInstance

      public static PagCache getInstance()
      Provides access to the singleton instance of the PagCache class. If the instance does not yet exist, it is created in a thread-safe manner.
      Returns:
      the singleton instance of PagCache
    • clear

      public void clear()
      Clears the internal cache, removing all stored entries. This method should be called when the cache needs to be reset or discarded.
    • getPag

      @NotNull public @NotNull Graph getPag(Graph g, boolean excludeSelectionBias)
      Retrieves or computes a Partial Ancestral Graph (PAG) from the given input graph. If the input graph is already cached and has not been externally modified, the cached version is returned. Otherwise, a new PAG is computed with default knowledge. The input graph must be either a Directed Acyclic Graph (DAG) or a Maximal Ancestral Graph (MAG).
      Parameters:
      g - the input graph, which must be either a DAG or a MAG
      excludeSelectionBias - True to exclude selection bias, false otherwise.
      Returns:
      the corresponding PAG for the provided graph
      Throws:
      IllegalArgumentException - if the input graph is neither a DAG nor a MAG
      IllegalStateException - if a discriminating path cannot be found.
    • getPag

      @NotNull public @NotNull Graph getPag(Graph g, Knowledge knowledge, boolean excludeSelectionBias, int recursiveDepth)
      Retrieves or computes a PAG (Partial Ancestral Graph) from the given input graph. If the graph is already in the cache and hasn't been externally modified, the cached version is returned. Otherwise, a new PAG is computed, stored in the cache, and returned. The input graph must be either a DAG (Directed Acyclic Graph) or a MAG (Maximal Ancestral Graph).

      Note that the input graph must either be a legal DAG, possibly with latents, or a legal MAG. (Legal MAGs cannot have latents; we treat DAGs, therefore, as a special case. A legal DAG without latents would be a legal MAG.)

      Parameters:
      g - the input graph, which must be either a DAG or a MAG
      knowledge - the knowledge object containing additional information for PAG computation
      excludeSelectionBias - whether to exclude selection bias during PAG computation
      recursiveDepth - the depth of recursion to consider during PAG computation
      Returns:
      the corresponding PAG for the provided graph
      Throws:
      IllegalArgumentException - if the input graph is neither a DAG nor a MAG
      IllegalStateException - if a discriminating path cannot be found.