15

I was wondering if there is any way to iteratively define a matrix in LaTeX? For example, say I wanted to write the following matrix:

Source: https://en.wikipedia.org/wiki/Inverse_problem#An_elementary_example_:_Earth's_gravitational_field

Of course, I could write this matrix by hand using a bmatrix enviroment, but for argument's sake, what if the example was much larger, such that it would be a pain to add each entry by hand. Then it would be much better to be able to define the matrix like so with macros (using pseudocode syntax for clarity):

#the matrix is size [m,n]
mymatrix = []
for i in range(m)
    for j in range(n)
        mymatrix[i,j] = \frac{G}{r^{2}_{i,j}}
    endfor
endfor

Unfortunately, although I have used LaTeX before, I have never used macros, so I don't know where to start doing something like this, or if it is even possible. I am re-posting this question as I posted it on stack overflow before and it didn't get any comments.

Thanks for the help!

2 Answers 2

18

It is easy with nicematrix.

\documentclass{article}
\usepackage{nicematrix}

\begin{document}
\NiceMatrixOptions{cell-space-top-limit = 2pt,cell-space-bottom-limit = 2pt}
\[
  F=\bAutoNiceMatrix{5-5}{\frac{G}{r^{2}_{\arabic{iRow}, \arabic{jCol}}}}
\]
\end{document}

enter image description here

9

A fairly general matrix generation macro:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse,xfp}

\ExplSyntaxOn

\NewDocumentCommand{\generatematrix}{O{b}mmmO{0pt}}
 {% #1 = fence (default b)
  % #2 = n. of rows
  % #3 = n. of cols
  % #4 = entry template
  % #5 = extra spacing
  \sandalwood_matrix_generate:nnnnn { #1 } { #2 } { #3 } { #4 } { #5 }
 }

\tl_new:N \l__sandalwood_matrix_body_tl

\cs_new_protected:Nn \sandalwood_matrix_generate:nnnnn
 {
  \group_begin:
  \cs_set_protected:Nn \__sandalwood_matrix_entry:nn { #4 }
  \tl_clear:N \l__sandalwood_matrix_body_tl
  % generate the first m-1 rows, with the possible extra spacing in between
  \int_step_inline:nn { #2 - 1 }
   {
    % the first object in a row gobbles a spurious &
    \tl_put_right:Nn \l__sandalwood_matrix_body_tl { \use_none:n }
    % fill the row
    \int_step_inline:nn { #3 }
     {
      \tl_put_right:Nn \l__sandalwood_matrix_body_tl
       {
        & \__sandalwood_matrix_entry:nn { ##1 } { ####1 }
       }
     }
    % add the extra spacing at the end of a row
    \tl_put_right:Nn \l__sandalwood_matrix_body_tl { \\ \noalign{\vspace{#5}} }
   }
  % fill the last row
  \tl_put_right:Nn \l__sandalwood_matrix_body_tl { \use_none:n }
  \int_step_inline:nn { #3 }
   {
    \tl_put_right:Nn \l__sandalwood_matrix_body_tl
     {
      & \__sandalwood_matrix_entry:nn { #2 } { ##1 }
     }
   }
  \begin{#1matrix}
  \tl_use:N \l__sandalwood_matrix_body_tl
  \end{#1matrix}
  \group_end:
 }

\ExplSyntaxOff

\newcommand{\hilbertmatrix}[1]{%
  \generatematrix{#1}{#1}{\frac{1}{\inteval{##1+##2-1}}}[1ex]%
}

\begin{document}

\[
\generatematrix{5}{5}{\dfrac{G}{r_{#1#2}^2}}[1ex]=
\generatematrix[v]{6}{4}{a_{#1,#2}}+\hilbertmatrix{4}
\]

\end{document}

The leading optional argument (default b) is meant to state the shape of the fences, in the standard amsmath way. The trailing mandatory argument should be a length (extra space between rows).

The third mandatory argument to \generatematrix is a template, where #1 denotes the row index and #2 the column index. I added how to define a macro based on \generatematrix to show that if we use it in a definition, we need to transform them into ##1 and ##2.

enter image description here

I know that the operations don't make sense. 😉

This is the output of

\[
\generatematrix{2}{3}{\generatematrix[p]{2}{2}{A_{#1,##1}^{#2,##2}}[2pt]}[1ex]
\]

enter image description here

3
  • I have some trouble understanding the effect of \group_begin: and \group_end: in your code or some general case. Would you explain the effect of these command? Thanks a lot
    – ZhiyuanLck
    Commented Jun 11, 2020 at 9:25
  • @ZhiyuanLck They're in just in case you plan to nest \generatematrix, so the setting of the template macro inside will not clobber the setting at the upper level. I added an example.
    – egreg
    Commented Jun 11, 2020 at 9:31
  • Get it. Thanks again.
    – ZhiyuanLck
    Commented Jun 11, 2020 at 10:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .