% \iffalse meta-comment % % causalmodels.dtx % % Copyright (C) 2026 by Alex Markham % % This work may be distributed and/or modified under the conditions of % the LaTeX Project Public License, either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in https://www.latex-project.org/lppl.txt and % version 1.3c or later is part of all distributions of LaTeX version % 2005/12/01 or later. % % This work has the LPPL maintenance status 'author-maintained'. % % The Current Maintainer of this work is Alex Markham. % % This work consists of the files causalmodels.dtx, causalmodels.ins, and % causalmodels.bib, and the derived files causalmodels.sty, % causalmodels-doc.tex, and causalmodels-doc.pdf. % %<*driver> \ProvidesFile{causalmodels.dtx} \documentclass{ltxdoc} \usepackage[T1]{fontenc} \usepackage{xcolor} \definecolor{causaldevpurple}{HTML}{7C4DFF} \definecolor{causaldevgreen}{HTML}{43A047} \usepackage{causalmodels} \usepackage{amssymb} \usetikzlibrary{positioning} \usepackage[most]{tcolorbox} \usepackage[numbers]{natbib} \usepackage[hyperindex=false,colorlinks=true,linkcolor=causaldevpurple,% citecolor=causaldevpurple,urlcolor=causaldevpurple]{hyperref} \newcommand{\doi}[1]{\href{https://doi.org/#1}{doi:~#1}} \EnableCrossrefs \RecordChanges \begin{document} \DocInput{causalmodels.dtx} \PrintChanges \end{document} % % \fi % % \changes{v1.0.0}{2026/08/22}{Initial release} % % \GetFileInfo{causalmodels.sty} % % \title{The \textsf{causalmodels} package} % \author{Alex Markham \\ \texttt{alex.markham@causal.dev}} % \date{\filedate\ \fileversion} % % \newcommand{\doccolsep}{@{\hspace{3em}}} % % \maketitle % % \begin{tcolorbox}[breakable, title=Quickstart, colframe=causaldevgreen, % colback=causaldevgreen!8, colbacktitle=causaldevgreen, coltitle=white] % Loading the package with \verb|\usepackage{causalmodels}| provides % macros for common operators, relations, and edges. For example, % some common operators include % \begin{center} % \begin{tabular}{rl \doccolsep rl} % $\pa{u}$ & \verb|\pa{u}| & $\ch{u}$ & \verb|\ch{u}| \\ % $\nei{u}$ & \verb|\nei{u}| & $\doo{X}$ & \verb|\doo{X}|, % \end{tabular} % \end{center} % separation relations include % \begin{center} % \begin{tabular}{rl \doccolsep rl} % $\indep{X}{Y}{}$ & \verb|\indep{X}{Y}{}| & $\nindep{X}{Y}{Z}$ & \verb|\nindep{X}{Y}{Z}|, % \end{tabular} % \end{center} % and edge types include % \begin{center} % \begin{tabular}{rl \doccolsep rl} % $u \undir v$ & \verb|u \undir v| & $u \rightdir v$ & \verb|u \rightdir v| \\ % $u \leftdir v$ & \verb|u \leftdir v| & $u \bidir v$ & \verb|u \bidir v|. % \end{tabular} % \end{center} % See Section~\ref{sec:usage} for more macros and usage details. % \end{tcolorbox} % % \tableofcontents % % \section{Introduction} % % This package is a collection of macros for notation and symbols % commonly used in the causal graphical models literature. On the one % hand, these macros are relatively simply built from tools in % \textsf{amsmath} and \textsf{PGF/TikZ}. On the other hand, I find % myself redefining these macros almost every time I start a new % \LaTeX document, and I regularly read new papers that (should) do % the same, so I expect collecting them into a single \TeX package to % be useful nevertheless. % % Besides typesetting common operators like $\pa[\mathcal{G}]{u}$ % properly using \textsf{amsmath}'s \verb|\operatorname|---which is % subtly different from using \verb|$\mathrm{pa}$| and more noticeably % so from plain \verb|$pa$|---this package makes three modest % innovations: it uses \textsf{PGF/TikZ} to define (i) a well-behaved % independence symbol ($\indep{}{}{}$) without the issues of other % approaches\footnote{For example, approaches suggested at % \url{https://tex.stackexchange.com/q/719657} tend to require using % other fonts and can ignore scaling of surrounding math text; and the % overlapping \texttt{\textbackslash perp} approach discussed at % \url{https://tex.stackexchange.com/q/79434} and in the % \textsf{comprehensive} package documentation at % \url{https://ctan.org/pkg/comprehensive}, with attribution to a post % by Donald Arseneau on \texttt{comp.text.tex} in June 2000, produces % a slightly thicker stroke weight where the symbols overlap.} and % (ii) a set of edges with uniform width when used inline (like % $\tailhead$ and $\circhead$), and it (iii) provides two macros for % simply and consistently defining new operators and edges. % % If you find yourself regularly redefining a macro because it is not % in this package---or modifying one that is part of this % package---please send me an % email\footnote{\href{mailto:alex.markham@causal.dev?subject=causalatex}{\texttt{alex.markham@causal.dev}}} % or open an issue/make a pull % request\footnote{\href{https://codeberg.org/alex-markham/causalatex}{\texttt{https://codeberg.org/alex-markham/causalatex}}} % describing it. % % \section{Usage} % \label{sec:usage} % % This section covers the package's four macro families---graph % operators, the do-operator, separation relations, and edge % marks---after loading it: % \begin{verbatim} % \usepackage{causalmodels} % \end{verbatim} % It requires \textsf{amsmath}, \textsf{tikz} (with the % \textsf{arrows.meta} library), and \textsf{centernot}. % % \subsection{Graph operators} % % Each of the eleven graph operators below (e.g., \cs{pa}) shares one % syntax, % \begin{quote} % \meta{op}[\meta{graph}]\{\meta{vertex}\}, % \end{quote} % which is unary and prefix, takes a vertex (set) as its argument, % plus an optional leading subscript (any graph label, e.g., % \verb|\pa[G]{u}|) to disambiguate between multiple graphs: % \begin{center} % \begin{tabular}{rl \doccolsep rl \doccolsep rl} % $\pa{u}$ & \verb|\pa{u}| & $\ch{u}$ & \verb|\ch{u}| & $\an{u}$ & \verb|\an{u}| \\ % $\de{u}$ & \verb|\de{u}| & $\nd{u}$ & \verb|\nd{u}| & $\mb{u}$ & \verb|\mb{u}| \\ % $\nei{u}$ & \verb|\nei{u}| & $\spo{u}$ & \verb|\spo{u}| & $\dis{u}$ & \verb|\dis{u}| \\ % $\ant{u}$ & \verb|\ant{u}| & $\cc{u}$ & \verb|\cc{u}| & & % \end{tabular} % \end{center} % In addition to the usual \cs{nei} (neighbors), \cs{pa} (parents), % \cs{ch} (children), \cs{an} (ancestors), and \cs{de} (descendants), % we have \cs{nd} (non-descendants) and \cs{mb} (Markov blanket) % \citep{pearl1988}, \cs{spo} (spouse) and \cs{ant} (anterior) % \citep{richardsonspirtes2002}, \cs{dis} (district) % \citep{richardson2003}, and \cs{cc} (chain component) % \citep{anderssonmadiganperlman1997}. % % For an operator not named above, % \cs{newgraphop}\{\meta{macro}\}\{\meta{name}\} defines \meta{macro} % as a new operator, with the same syntax as above, that displays as % \meta{name}: \verb|\newgraphop{\eg}{eg}| makes \verb|\eg[G]{u}| % available. % % \subsection{The do-operator} % % Pearl's $do(\cdot)$ notation \citep{pearl1995} is typeset with % \cs{doo}\{\meta{variable}\}, which is unary, prefix, and takes no % optional argument: % \begin{center} % \begin{tabular}{ll} % $\doo{X}$ & \verb|\doo{X}| \\ % \end{tabular} % \end{center} % % \subsection{Separation relations} % % Each of the four separation relations below (e.g., \cs{sep}) shares % one syntax, % \begin{quote} % \meta{relation}[\meta{sub}]\{\meta{X}\}\{\meta{Y}\}\{\meta{Z}\}, % \end{quote} % which is ternary and prefix, asserting that \meta{X} and \meta{Y} % are (conditionally) separated given \meta{Z} \citep{pearl1988}. An % optional leading subscript names the distribution, graph, or % criterion it's relative to, e.g., \verb|\indep[P]{X}{Y}{Z}|, or % using \verb|m| or \verb|\sigma| as \meta{sub} in \cs{sep} to denote % m-separation \citep{richardsonspirtes2002} or $\sigma$-separation % \citep{forremooij2017}. Leaving \meta{Z} empty (\verb|{}|) gives % the unconditional form, omitting the conditioning bar entirely. % % \begin{center} % \begin{tabular}{rl \doccolsep rl} % $\indep{X}{Y}{Z}$ & \verb|\indep{X}{Y}{Z}| & $\sep{u}{v}{w}$ & \verb|\sep{u}{v}{w}| \\ % $\nindep{X}{Y}{Z}$ & \verb|\nindep{X}{Y}{Z}| & $\nsep{u}{v}{w}$ & \verb|\nsep{u}{v}{w}| % \end{tabular} % \end{center} % % \subsection{Edge marks} % \label{sec:usage-edges} % % Edge marks (used across DAGs \citep{pearl1988}, CPDAGs % \citep{anderssonmadiganperlman1997}, MPDAGs % \citep{perkovic2020}, ADMGs \citep{richardson2003}, ancestral % graphs \citep{richardsonspirtes2002}, and PAGs % \citep{spirtesmeekrichardson1999}) % use \meta{u} \meta{name} \meta{v}, which is binary, infix notation, % built from four end marks at each end, so there are $4^2$ different % marks: % \begin{center} % \begin{tabular}{rl \doccolsep rl} % $u \tailtail v$ & \verb|u \tailtail v| & $u \tailhead v$ & \verb|u \tailhead v| \\ % $u \tailcirc v$ & \verb|u \tailcirc v| & $u \tailwild v$ & \verb|u \tailwild v| \\ % $u \headtail v$ & \verb|u \headtail v| & $u \headhead v$ & \verb|u \headhead v| \\ % $u \headcirc v$ & \verb|u \headcirc v| & $u \headwild v$ & \verb|u \headwild v| \\ % $u \circtail v$ & \verb|u \circtail v| & $u \circhead v$ & \verb|u \circhead v| \\ % $u \circcirc v$ & \verb|u \circcirc v| & $u \circwild v$ & \verb|u \circwild v| \\ % $u \wildtail v$ & \verb|u \wildtail v| & $u \wildhead v$ & \verb|u \wildhead v| \\ % $u \wildcirc v$ & \verb|u \wildcirc v| & $u \wildwild v$ & \verb|u \wildwild v| % \end{tabular} % \end{center} % Four of the sixteen also have short, colloquial aliases---either % name draws the same edge: % \begin{center} % \begin{tabular}{rrcl} % $u \undir v$ & \verb|u \undir v| & or & \verb|u \tailtail v| \\ % $u \rightdir v$ & \verb|u \rightdir v| & or & \verb|u \tailhead v| \\ % $u \leftdir v$ & \verb|u \leftdir v| & or & \verb|u \headtail v| \\ % $u \bidir v$ & \verb|u \bidir v| & or & \verb|u \headhead v| % \end{tabular} % \end{center} % % Every edge mark above also has a matching % \texttt{causalmodels/\meta{name}} \textsf{TikZ} style, for drawing % edges between arbitrarily-positioned nodes in a real % \texttt{tikzpicture} rather than typesetting a fixed-length inline % glyph: % \begin{verbatim} % \usetikzlibrary{positioning} % \begin{tikzpicture} % \node (u) {$u$}; % \node (v) [right=1.5cm of u] {$v$}; % \draw[causalmodels/circhead] (u) -- (v); % \end{tikzpicture} % \end{verbatim} % See Section~\ref{sec:diagram-styles} for the full set of style % names. % % Arrow length and width---for both inline glyphs and diagram % styles---are configurable via % \cs{causalmodelsset}\{arrow-length=\meta{len}, % arrow-width=\meta{wid}\}. For an edge type not named above, % \cs{mkedge}\{\meta{arrows.meta spec}\} builds one directly, e.g., % \verb|\mkedge{->}| is exactly \cs{rightdir}. % % \section{Implementation} % % This section documents how each macro from Section~\ref{sec:usage} % is built. It also covers \cs{causalmodelsset}, plus \cs{newgraphop} % and \cs{mkedge}, the helpers for custom operators and edge types. % % \begin{macrocode} %<*package> \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{causalmodels}% [2026/08/22 v1.0.0 Notation macros for causal graphical models] % % \end{macrocode} % % \subsection{Dependencies} % % \textsf{amsmath} provides \cs{operatorname} and \cs{mathrel}, used % throughout the graph operators, do-operator, and separation % relations. \textsf{tikz} draws every edge glyph and diagram style; % \textsf{arrows.meta} specifically supplies the circle and wildcard % tip shapes (\texttt{\{Circle[open]\}}, \texttt{\{Rays[n=7]\}}) used % by the edge marks (Section~\ref{sec:edges}): % \begin{macrocode} %<*package> \RequirePackage{amsmath} \RequirePackage{tikz} \usetikzlibrary{arrows.meta} % % \end{macrocode} % \cs{centernot} is needed for \cs{nindep}'s negation slash: plain % \cs{not} sizes and positions its slash assuming a normal % single-character-width symbol, and lands off-center on \cs{indep}'s % wider hand-drawn glyph (Section~\ref{sec:sepop}). \cs{centernot} % measures the actual width of its argument and centers accordingly: % \begin{macrocode} %<*package> \RequirePackage{centernot} % % \end{macrocode} % % \subsection{Graph operators} % \label{sec:graphops} % % \DescribeMacro{\pa} % \DescribeMacro{\ch} % \DescribeMacro{\an} % \DescribeMacro{\de} % \DescribeMacro{\nd} % \DescribeMacro{\mb} % \DescribeMacro{\nei} % \DescribeMacro{\spo} % \DescribeMacro{\dis} % \DescribeMacro{\ant} % \DescribeMacro{\cc} % All eleven graph operators share \cs{causalmodels@graphop}, which % takes an operator name, an optional leading subscript, and one % required argument. % % \cs{nei}, not \cs{ne}: \cs{ne} is already \textsf{amsmath}'s ``not % equal'' ($\ne$)---only the callable name avoids the collision; it % still typesets ``ne'' (\cs{operatorname}\{ne\}). Likewise \cs{spo}, % not \cs{sp}: \cs{sp} is already plain \TeX's superscript primitive % (\verb|^|). It still typesets ``sp'' (\cs{operatorname}\{sp\}). % \begin{macrocode} %<*package> \newcommand{\causalmodels@graphop}[3]{% \def\causalmodels@graphopsub{#2}% \operatorname{#1}\ifx\causalmodels@graphopsub\@empty\else_{#2}\fi(#3)% } \newcommand{\pa}[2][]{\causalmodels@graphop{pa}{#1}{#2}} \newcommand{\ch}[2][]{\causalmodels@graphop{ch}{#1}{#2}} \newcommand{\an}[2][]{\causalmodels@graphop{an}{#1}{#2}} \newcommand{\de}[2][]{\causalmodels@graphop{de}{#1}{#2}} \newcommand{\nd}[2][]{\causalmodels@graphop{nd}{#1}{#2}} \newcommand{\mb}[2][]{\causalmodels@graphop{mb}{#1}{#2}} \newcommand{\nei}[2][]{\causalmodels@graphop{ne}{#1}{#2}} \newcommand{\spo}[2][]{\causalmodels@graphop{sp}{#1}{#2}} \newcommand{\dis}[2][]{\causalmodels@graphop{dis}{#1}{#2}} \newcommand{\ant}[2][]{\causalmodels@graphop{ant}{#1}{#2}} \newcommand{\cc}[2][]{\causalmodels@graphop{cc}{#1}{#2}} % % \end{macrocode} % % \DescribeMacro{\newgraphop} % \cs{newgraphop}\{\meta{macro}\}\{\meta{name}\} defines a new graph % operator, for one this package doesn't already name: \meta{macro} % is the macro it defines, and \meta{name} is the string % \cs{operatorname} displays. \cs{newgraphop}\{\cs{eg}\}\{eg\} % makes \verb|\eg[G]{u}| available, built the same way \cs{pa} is. % \begin{macrocode} %<*package> \newcommand{\newgraphop}[2]{% \newcommand{#1}[2][]{\causalmodels@graphop{#2}{##1}{##2}}% } % % \end{macrocode} % % \subsection{The do-operator} % \label{sec:doo} % % Unlike the graph operators and separation relations, \cs{doo} needs % no shared helper---it's a single \cs{operatorname} call: % \DescribeMacro{\doo} % \begin{macrocode} %<*package> \newcommand{\doo}[1]{\operatorname{do}(#1)} % % \end{macrocode} % % \subsection{Separation relations} % \label{sec:sepop} % % \DescribeMacro{\indep} % \DescribeMacro{\nindep} % \DescribeMacro{\sep} % \DescribeMacro{\nsep} % \cs{indep}, \cs{nindep}, \cs{sep}, and \cs{nsep} all share % \cs{causalmodels@sepop}, which takes a glyph, an optional leading % subscript, and three required arguments---the third left empty omits % the ``\cs{mid}''. % % \cs{indep}'s glyph is built the same way $\vDash$ relates to % $\vdash$: $\vdash$ is a single vertical spine with one centered % horizontal tick; $\vDash$ is the same spine with two horizontal % ticks straddling that center. \cs{indep} applies that to $\perp$: % its horizontal bar, with the one centered vertical tick replaced by % two ticks straddling the same center, at the same offset ratio % (measured from \TeX's own $\vdash$/$\vDash$ font outlines). The % glyph is drawn directly from $\perp$'s own measured dimensions, % remeasured on every use, so it tracks the surrounding font size, % math style, and whatever math font is loaded. % \begin{macrocode} %<*package> \newcommand{\causalmodels@sepop}[5]{% \def\causalmodels@sepopsub{#2}% \def\causalmodels@sepopz{#5}% #3 \mathrel{#1\ifx\causalmodels@sepopsub\@empty\else_{#2}\fi} #4% \ifx\causalmodels@sepopz\@empty\else\mid #5\fi } \newsavebox{\causalmodels@perpbox} \newlength{\causalmodels@perpht} \newlength{\causalmodels@perpwd} \newlength{\causalmodels@indeptickoffset} \newlength{\causalmodels@indepbarmid} \newlength{\causalmodels@indeptick} \newcommand{\causalmodels@indeptickoffsetratio}{0.1398} \newcommand{\causalmodels@indepstrokewidth}{0.04em} \newcommand{\causalmodels@indepstyled}[2]{% \sbox{\causalmodels@perpbox}{$#1\perp$}% \settoheight{\causalmodels@perpht}{\usebox{\causalmodels@perpbox}}% \settowidth{\causalmodels@perpwd}{\usebox{\causalmodels@perpbox}}% \pgfmathsetlength{\causalmodels@indeptickoffset}% {\causalmodels@indeptickoffsetratio*\causalmodels@perpwd}% \pgfmathsetlength{\causalmodels@indepbarmid}{0.5\causalmodels@perpwd}% \mathrel{\tikz[baseline=0pt]{% \draw[line width=\causalmodels@indepstrokewidth]% (0pt,0pt) -- (\causalmodels@perpwd,0pt);% \pgfmathsetlength{\causalmodels@indeptick}% {\causalmodels@indepbarmid-\causalmodels@indeptickoffset}% \draw[line width=\causalmodels@indepstrokewidth]% (\causalmodels@indeptick,0pt) --% (\causalmodels@indeptick,\causalmodels@perpht);% \pgfmathsetlength{\causalmodels@indeptick}% {\causalmodels@indepbarmid+\causalmodels@indeptickoffset}% \draw[line width=\causalmodels@indepstrokewidth]% (\causalmodels@indeptick,0pt) --% (\causalmodels@indeptick,\causalmodels@perpht);% }}% } \newcommand{\causalmodels@indepglyph}% {\mathpalette\causalmodels@indepstyled\relax} \newcommand{\causalmodels@nindepglyph}% {\centernot{\causalmodels@indepglyph}} \newcommand{\causalmodels@nsepglyph}{\centernot{\perp}} \newcommand{\indep}[4][]% {\causalmodels@sepop{\causalmodels@indepglyph}{#1}{#2}{#3}{#4}} \newcommand{\nindep}[4][]% {\causalmodels@sepop{\causalmodels@nindepglyph}{#1}{#2}{#3}{#4}} \newcommand{\sep}[4][]{\causalmodels@sepop{\perp}{#1}{#2}{#3}{#4}} \newcommand{\nsep}[4][]% {\causalmodels@sepop{\causalmodels@nsepglyph}{#1}{#2}{#3}{#4}} % % \end{macrocode} % % \subsection{Configuration: \cs{causalmodelsset}} % % \DescribeMacro{\causalmodelsset} % Its \texttt{arrow-length} and \texttt{arrow-width} keys resolve % where the edge is actually drawn, not where \cs{causalmodelsset} is % called, so they always match its surrounding font size: % \begin{center} % {\normalsize $u \rightdir v \bidir w \circhead x$} \\[4pt] % {\LARGE $u \rightdir v \bidir w \circhead x$} % \end{center} % \begin{macrocode} %<*package> \newcommand{\causalmodels@arrowlength}{2.5ex} \newcommand{\causalmodels@arrowwidth}{0.045em} \pgfkeys{ /causalmodels/.cd, arrow-length/.store in=\causalmodels@arrowlength, arrow-width/.store in=\causalmodels@arrowwidth, } \newcommand{\causalmodelsset}[1]{\pgfkeys{/causalmodels/.cd,#1}} % % \end{macrocode} % % \subsection{The \cs{mkedge} helper} % % \DescribeMacro{\mkedge} % Every edge mark below is built from \cs{mkedge}\{\meta{arrows.meta % spec}\}: a short \textsf{TikZ} line with that tip decoration, % wrapped as an inline math relation. % \begin{macrocode} %<*package> \newcommand{\causalmodels@mkedge}[1]{% \mathrel{\tikz[baseline=-0.5ex]{% \draw[line width=\causalmodels@arrowwidth,#1]% (0,0) -- (\causalmodels@arrowlength,0);% }}% } \newcommand{\mkedge}[1]{\ensuremath{\causalmodels@mkedge{#1}}} % % \end{macrocode} % % \cs{causalmodels@defedge}\{name\}\{spec\} defines both the inline % glyph and the matching \texttt{causalmodels/name} diagram style % (Section~\ref{sec:diagram-styles}) from one spec. % \begin{macrocode} %<*package> \newcommand{\causalmodels@defedge}[2]{% \expandafter\newcommand\csname #1\endcsname{\mkedge{#2}}% \tikzset{causalmodels/#1/.style={#2,line width=\causalmodels@arrowwidth}}% } % % \end{macrocode} % % \subsection{Edge marks} % \label{sec:edges} % % Every edge mark, regardless of how many marks decorate its ends, % spans the same tip-to-tip width, so a plain \cs{undir} line and a % doubly-decorated \cs{wildwild} line drawn to the same length look % the same length, even though \cs{wildwild}'s decorations eat into % more of that span. Every edge mark works in text and math mode. % % Every edge is named compositionally, left-to-right, from a fixed % vocabulary: \texttt{tail} (a plain line end), \texttt{head} (an % arrowhead), \texttt{circ}, and \texttt{wild} (a wildcard mark, % standing in for any of the other three). % % \DescribeMacro{\tailtail} % \DescribeMacro{\tailhead} % \DescribeMacro{\headtail} % \DescribeMacro{\headhead} % \DescribeMacro{\tailcirc} % \DescribeMacro{\tailwild} % \DescribeMacro{\headcirc} % \DescribeMacro{\headwild} % \DescribeMacro{\circtail} % \DescribeMacro{\circhead} % \DescribeMacro{\circcirc} % \DescribeMacro{\circwild} % \DescribeMacro{\wildtail} % \DescribeMacro{\wildhead} % \DescribeMacro{\wildcirc} % \DescribeMacro{\wildwild} % For example, \cs{circhead} is circle-then-right-arrow and % \cs{headcirc} is left-arrow-then-circle. Sixteen edges in total: % every pairing of the four end marks (tail, head, circ, wild) at the % two ends of the edge, $4^2 = 16$. % \begin{macrocode} %<*package> \causalmodels@defedge{tailtail}{-} \causalmodels@defedge{tailhead}{->} \causalmodels@defedge{headtail}{<-} \causalmodels@defedge{headhead}{<->} \causalmodels@defedge{tailcirc}{-{Circle[open]}} \causalmodels@defedge{tailwild}{-{Rays[n=7]}} \causalmodels@defedge{headcirc}{<-{Circle[open]}} \causalmodels@defedge{headwild}{<-{Rays[n=7]}} \causalmodels@defedge{circtail}{{Circle[open]}-} \causalmodels@defedge{circhead}{{Circle[open]}->} \causalmodels@defedge{circcirc}{{Circle[open]}-{Circle[open]}} \causalmodels@defedge{circwild}{{Circle[open]}-{Rays[n=7]}} \causalmodels@defedge{wildtail}{{Rays[n=7]}-} \causalmodels@defedge{wildhead}{{Rays[n=7]}-{>}} \causalmodels@defedge{wildcirc}{{Rays[n=7]}-{Circle[open]}} \causalmodels@defedge{wildwild}{{Rays[n=7]}-{Rays[n=7]}} % \end{macrocode} % % \DescribeMacro{\undir} % \DescribeMacro{\rightdir} % \DescribeMacro{\leftdir} % \DescribeMacro{\bidir} % Four of the sixteen also get short, colloquial aliases ending in % \texttt{dir}---exactly equivalent to the names above: \cs{undir}, % \cs{rightdir}, \cs{leftdir}, \cs{bidir}. % \begin{macrocode} \let\undir\tailtail \let\rightdir\tailhead \let\leftdir\headtail \let\bidir\headhead % % \end{macrocode} % % \subsection{Diagram styles} % \label{sec:diagram-styles} % % The edge marks above are complete, self-contained inline glyphs, not % path styles, so they cannot be dropped into \texttt{\cs{draw} (u) -- % (v);} inside a real \texttt{tikzpicture} to connect two % arbitrarily-positioned nodes. The styles below, namespaced under % \texttt{causalmodels/}, expose the same arrow-tip specs and % configurable line width instead (\cs{causalmodelsset} affects diagrams % and inline glyphs together, so a figure can match a paper's inline % notation exactly). % % One style exists per edge mark above (including the four colloquial % aliases), by the same name: \texttt{causalmodels/\allowbreak % tailhead}, \texttt{causalmodels/\allowbreak circhead}, \dots. The % sixteen non-alias styles are defined alongside their inline macros % in Section~\ref{sec:edges}, via \cs{causalmodels@defedge}; only the % four alias styles below are defined directly here. Diagram styles % deliberately don't include arrow length---unlike the inline glyphs, % diagram edges span whatever distance node positions dictate. % Compare against the inline glyphs directly: $u \circhead v$, % $u \tailhead w$, $v \wildwild w$. % \begin{center} % \begin{tikzpicture} % \node (u) {$u$}; % \node (v) [right=1.5cm of u] {$v$}; % \node (w) [below=1cm of v] {$w$}; % \draw[causalmodels/circhead] (u) -- (v); % \draw[causalmodels/tailhead] (u) -- (w); % \draw[causalmodels/wildwild] (v) -- (w); % \end{tikzpicture} % \end{center} % Alias styles work the same way. % \begin{macrocode} %<*package> \tikzset{ causalmodels/undir/.style={causalmodels/tailtail}, causalmodels/rightdir/.style={causalmodels/tailhead}, causalmodels/leftdir/.style={causalmodels/headtail}, causalmodels/bidir/.style={causalmodels/headhead}, } % % \end{macrocode} % % \begin{macrocode} %<*package> \endinput % % \end{macrocode} % % \bibliographystyle{plainnat} % \bibliography{causalmodels} % % \Finale % \endinput