Matrices with labeled rows and columns

Hi, I was wondering if there is any general way to display a matrix and label the rows and columns, like in latex here https://tex.stackexchange.com/questions/59517/label-rows-of-a-matrix-by-characters.

I have tried everything from here How can I label the columns and rows of a matrix? and could not find a method that works for any labels and matrix without having to adjust values by hand. Here’s an example of the type of labeling I need.

2 Likes

Could you share the code that makes your example in the image?

You could try:

#import "@preview/mannot:0.4.0": *

// Mark every matrix element so that it can be annotated later.
#let markmat(..args, tag: <mat>, tagsep: "", mark: mark) = {
  let mktag(i, j) = label(
    str(tag)
      + tagsep
      + str(i + 1)
      + tagsep
      + str(j + 1)
  )

  math.mat(
    ..args.named(),
    ..args.pos().enumerate().map(((i, row)) =>
      row.enumerate().map(((j, entry)) =>
        mark(entry, tag: mktag(i, j))
      )
    ),
  )
}

// Helper to generate tags such as <m11>, <m12>, and so on.
#let m = ((..args) =>
  label(args.pos().map(str).join())
).with("m")

// Reserve enough horizontal space for annotations placed on the left.
#let reserve-left(labels, gap: 1em) = context {
  let widths = labels.map(label => measure(label).width)
  h(calc.max(..widths) + gap)
}

#let row-labels = (
  $g_sigma^(x_1)$,
  $g_sigma^(x_2)$,
  $g_sigma^(x_3)$,
)

#let column-labels = (
  $r^(x_4)$,
  $r^(x_4)$,
)

#let row-label-gap = 1em
#let column-label-gap = 0.6em

#let leftannot = annot.with(
  pos: left,
  dx: -row-label-gap,
  leader: false,
)

#let topannot = annot.with(
  pos: top,
  dy: -column-label-gap,
  leader: false,
)

$
p_ell^1
= #reserve-left(
    row-labels,
    gap: row-label-gap,
  )
  markmat(
    delim: "(",
    1, 0;
    1, 1;
    0, 1;
    tag: #<m>
  )

// Row labels
#leftannot(m(1, 1))[#(row-labels.at(0))]
#leftannot(m(2, 1))[#(row-labels.at(1))]
#leftannot(m(3, 1))[#(row-labels.at(2))]

// Column labels
#topannot(m(1, 1))[#(column-labels.at(0))]
#topannot(m(1, 2))[#(column-labels.at(1))]
$

1 Like