This vignette demonstrates advanced techniques for using
latexSymb
to create complex mathematical documents. We’ll
explore how to organize your code effectively, create reusable
functions, and build sophisticated mathematical expressions.
When working with complex mathematical documents, it’s beneficial to separate your symbol definitions and helper functions from your main document content. This pattern offers several advantages:
Create a separate .R file for your symbols, for instance:
# my_symbols.R
library(latexSymb)
data(common)
attach(common)
#> The following objects are masked from common (pos = 3):
#>
#> Comps, Ints, Nats, Rats, Reals, al, be, bgs, ch, comma, de, des,
#> endl, ep, eq, et, f, g, ga, geq, gt, h, i, indic, infty, io, j, k,
#> ka, l, la, ldots, leq, lt, m, mapsto, minus, mu, n, neq, nu, om,
#> om, ph, pi, plus, ps, quad, rh, ruler, si, ta, th, thus, times, to,
#> up, x, xi, y, z, ze
#> The following object is masked from package:base:
#>
#> pi
# Define document-specific symbols
pt <- lsymb("x")
pt_prime <- lsymb("x'")
metric_space <- lsymb("\\mathcal{X}")
measure <- lsymb("\\mu")
# Create specialized functions
dist <- function(x, y) lsymb("d") * pths(x * comma * y)
Then, use a separate .Rmd to write the body of your document. In that file, set:
knitr::opts_chunk$set(results = "asis", echo = FALSE)
source("my_symbols.R")
to make sure that the LaTeX code gets correctly rendered.
You can use latexSymb
to handle complicated mathematical
expressions. The following patterns can be helpful.
Create functions that compose to build sophisticated expressions:
# Expectation operator
exp_val <- function(x) lsymb("\\mathbb{E}") * sqbr(x)
sq <- function(x) pths(x)^2
# Absolute value
abs <- function(x) lsymb("\\abs{", x, "}")
# Indicator function
indic <- function(condition) {
lsymb("\\mathbbm{1}") |> under(br(condition))
}
# Composed example
X <- lsymb("X")
Y <- lsymb("Y")
Then you can create expressions like
exp_val(sq(abs(X - Y))) |> il()
to obtain \(\mathbb{E} \left[ \left( \abs{ X - Y } \right) ^{
2 } \right]\) and
exp_val(X * indic(Y > 0)) |> il()
for \(\mathbb{E} \left[ X \mathbbm{1} _{ \lbrace NA
\rbrace } \right]\).
This pattern uses lists and the lenv()
function. Each
element of the list corresponds to a row of your displayed
expression:
# Build a proof step by step
proof_steps <- list(
ruler * dist(x, y) * leq * dist(x, z) + dist(z, y) * endl,
ruler * thus * dist(x, y) - dist(x, z) * leq * dist(z, y)
) |>
lenv("align*", rows = _)
\[\begin{align*}& d \left( x , y \right) \leq d \left( x , z \right) + d \left( z , y \right) \\& \Rightarrow d \left( x , y \right) - d \left( x , z \right) \leq d \left( z , y \right)\end{align*}\]
Here’s how these techniques combine in practice:
# Setup
sample_size <- lsymb("n")
observation <- lsymb("X") |> under(i)
sample_mean <- lsymb("\\bar{X}")
conv_distr <- lsymb("\\overset{d}{\\rightarrow}")
sqrt <- function(x) lsymb("\\sqrt{", x, "}")
# Build a Central Limit Theorem statement
clt_statement <- list(
ruler * sqrt(sample_size) * (pths(sample_mean - mu) / si) *
conv_distr * lsymb("N(0,1)") * endl,
ruler * lsymb("\\text{where }") *
sample_mean * eq * (1 / sample_size) * Sum(observation, from = i * eq * 1, to = sample_size)
) |>
lenv("align*", rows = _)
\[\begin{align*}& \sqrt{ n } \frac{ \left( \bar{X} - \mu \right) }{ \sigma } \overset{d}{\rightarrow} N(0,1) \\& \text{where } \bar{X} = \frac{ 1 }{ n } \sum _{ i = 1 } ^{ n } X _{ i }\end{align*}\]
By organizing your code into separate files, creating reusable
functions, and following consistent patterns, you can efficiently create
complex mathematical documents with latexSymb
. The key is
to: