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!

17

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

| improve this answer | |
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

| improve this answer | |
  • 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 Jun 11 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 Jun 11 at 9:31
  • Get it. Thanks again. – ZhiyuanLck Jun 11 at 10:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.