Jacobsthal Elements
The Jacobsthal elements, \(\mathcal{J}_n\) of \(\text{TL}_n\) are defined by Boyd and Hepworth12. They are so named as the number of diagrams in their support is given by the Jacobsthal numbers. There is an exact sequence \[0 \xrightarrow{} \mathcal{F}_n \xrightarrow{} \text{TL}_n\xrightarrow{-\cdot\mathcal{J}_n} \text{TL}_n\] where \(\mathcal{F}_n\) is the mysterious “Fineberg” module.
We present some of the Jacobsthal elements and some information about them below. In these calculations, \(X = \mu/ \lambda = -v\) and the loop resolves to a factor of \(v + v^{-1} = -X - X^{-1}\).
\(\mathcal{J}_1\) | data | \(\mathcal{J}_2\) | data | \(\mathcal{J}_3\) | data | |||||
\(\mathcal{J}_4\) | data | \(\mathcal{J}_5\) | data | \(\mathcal{J}_6\) | data | |||||
\(\mathcal{J}_7\) | data | \(\mathcal{J}_8\) | data | \(\mathcal{J}_9\) | data |
Derivation
The Jacobsthal elements are defined as
\[\mathcal{J}_n = (-1)^{n-1}\sum_{\substack{n > a_1> \cdots > a_r > 0\\n-a_1 \text{odd}}} \left(\frac \mu\lambda\right)^r U_{a_1}\cdots U_{a_r}\]
The relevant code to generate the above is this:
use itertools::Itertools;
use temperley_lieb_cat::structures::*;
use temperley_lieb_cat::*;
/// Returns all sequences l-1 >= a_1 > a_2 > ... > a_r >= 1 with l - a_1 odd
/// If r = 0 then either return nothing if l even or an empty sequence if l odd.
fn good_runs(l: usize, r: usize) -> Vec<Vec<usize>> {
match (l, r) {
(l, 0) if l % 2 == 1 => {
vec![vec![]]
}
(l, 0) if l % 2 == 0 => {
vec![]
}
(l, r) => {
(1..l)
.combinations(r)
.filter(|x| (l - x.last().unwrap()) % 2 == 1)
.collect()
}
}
}
// We assume run is sorted from smallest to largest
fn make_run_elt(n: usize, l: usize, run: &[usize]) -> TLMorphism<Laurent> {
let mut ans = TLMorphism::id(n);
ans.repoint(Some(-Laurent::gen() - Laurent::inv_gen()));
for ai in run {
ans = TLMorphism::u(n, n - (ai + n - l)) * ans;
}
ans
}
fn jacobsthal(n: usize, l: usize) -> TLMorphism<Laurent> {
assert!(n >= l);
let mut ans = TLMorphism::id_zero(n);
let mut mu_by_lambda = if n % 2 == 1 {
Laurent::one()
} else {
-Laurent::one()
};
for r in 0..=l - 1 {
for run in good_runs(l, r) {
ans = ans + make_run_elt(n, l, &run) * &mu_by_lambda;
}
mu_by_lambda = mu_by_lambda * Laurent::gen();
}
ans
}
fn main() {
let n = std::env::args()
.nth(1)
.expect("pass in n as a parameter")
.parse()
.expect("pass in a number");
let mut elt = jacobsthal(n, n);
elt.repoint(Some(-Laurent::gen() - Laurent::inv_gen()));
elt.to_file(std::path::Path::new("./j.data"));
let after = if n > 4 {
String::new()
} else {
let basis_diagrams = TLDiagram::all(n, n);
let matrix_r = matrix_for_elt(&elt, true, &basis_diagrams);
let matrix_l = matrix_for_elt(&elt, false, &basis_diagrams);
format!(
"$\\\\\n\nIn the basis\\\\\n\n${}$\\\\\n\nthis acts by right multiplication as\\\\\n\n${}$\\\\\n\nand by left multiplication by\\\\\n\n${}",
basis_diagrams.into_tex(),
matrix_r,
matrix_l
)
};
render_tex(&format!(
"\\mathcal{{J}}_{{ {0} }} = {1}$\\\\\n\n$\\mathcal{{J}}_{{ {0} }}^2 = {2}{3}",
n,
elt.into_tex(),
(&elt * &elt).into_tex(),
after
));
}
fn matrix_for_elt(e: &TLMorphism<Laurent>, right: bool, basis_diagrams: &[TLDiagram]) -> String {
let mut rows = Vec::new();
let basis: Vec<_> = basis_diagrams
.iter()
.map(|x| TLMorphism::<Laurent>::from(*x))
.collect();
for col in basis {
let mul = if right { &col * e } else { e * &col };
let mut row = Vec::new();
for b in basis_diagrams {
row.push(mul.coeffs.get(b).unwrap_or(&Laurent::zero()).clone());
}
rows.push(row);
}
matrix_for_rows(&rows)
}
fn matrix_for_rows<T: Tex>(rows: &[Vec<T>]) -> String {
let mut matrix = "\\begin{pmatrix}".to_owned();
let mut first_row = true;
for row in rows {
if !first_row {
matrix = matrix + "\\\\\n";
}
first_row = false;
let mut first = true;
for col in row {
if !first {
matrix = matrix + "&";
}
matrix = matrix + &col.into_tex();
first = false;
}
}
matrix + "\\end{pmatrix}"
}