Class PagCache
java.lang.Object
edu.cmu.tetrad.util.PagCache
A thread-safe, identity-preserving cache that converts DAGs or MAGs to PAGs.
Design rationale.
- Preserves identity. For a given input
Graphobject,getPag(Graph)always returns the same PAG instance. This is required because higher-level algorithms (e.g., FCI, GFCI) retainNodeandEdgereferences 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,
PagCacherecomputes 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 existingNodeandEdgeidentities 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
IdentityHashMaprather than aWeakHashMap. 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 TypeMethodDescriptionvoidclear()Clears the internal cache, removing all stored entries.static PagCacheProvides access to the singleton instance of the PagCache class.@NotNull GraphRetrieves or computes a Partial Ancestral Graph (PAG) from the given input graph.@NotNull GraphRetrieves or computes a PAG (Partial Ancestral Graph) from the given input graph.
-
Method Details
-
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
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 MAGexcludeSelectionBias- 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 MAGIllegalStateException- 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 MAGknowledge- the knowledge object containing additional information for PAG computationexcludeSelectionBias- whether to exclude selection bias during PAG computationrecursiveDepth- 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 MAGIllegalStateException- if a discriminating path cannot be found.
-