# How to automatically construct an mxn matrix with same coefficients and different pedices?

Let's suppose I have an mxn matrix like the following

\documentclass{article}
\usepackage{amsmath}
\newcommand*{\vth}{\vartheta}
\newcommand*{\vph}{\varphi}
\newcommand*{\pt}[1]{\left(#1\right)}

\begin{document}

$$\begin{bmatrix}\vph_{11}&\vph_{12}&\vph_{13}&\vph_{14}&\vph_{15}&\vph_{16}&\dot{x}\pt{T}\\ \vph_{21}&\vph_{22}&\vph_{23}&\vph_{24}&\vph_{25}&\vph_{26}&\dot{y}\pt{T}\\ \vph_{31}&\vph_{32}&\vph_{33}&\vph_{34}&\vph_{35}&\vph_{36}&\dot{z}\pt{T}\\ \vph_{41}&\vph_{42}&\vph_{43}&\vph_{44}&\vph_{45}&\vph_{46}&\ddot{x}\pt{T}\\ \vph_{51}&\vph_{52}&\vph_{53}&\vph_{54}&\vph_{55}&\vph_{56}&\ddot{y}\pt{T}\\ \vph_{61}&\vph_{62}&\vph_{63}&\vph_{64}&\vph_{65}&\vph_{66}&\ddot{z}\pt{T}\end{bmatrix}$$

\end{document}


How can I construct with a macro such a matrix in order to say, for example, that I just want rows 1, 3, 5 and columns 1, 3, 5?

I was thinking to something like \automatrix{\vph}{1;3;5}{1;3;5}, in which the first input is the common variable \vph, the second are the rows I want to include (and therefore the first pedices) and the third input the columns (second pedices).

If it is possible to include also an additional column in the "automatic" matrix like in the picture it would be great!

Thank you!

You could use the tabularray package:

\documentclass{article}
\usepackage{amsmath}
\newcommand*{\vth}{\vartheta}
\newcommand*{\vph}{\varphi}
\newcommand*{\pt}[1]{\left(#1\right)}
\usepackage{tabularray}
\UseTblrLibrary{counter,amsmath}
\begin{document}

$$\begin{+bmatrix}[cell{1-Z}{1-Y}={cmd={\vph_{\arabic{rownum}\arabic{colnum}}}}] &&&&&&\dot{x}\pt{T}\\ &&&&&&\dot{x}\pt{T}\\ &&&&&&\dot{x}\pt{T}\\ &&&&&&\dot{x}\pt{T}\\ &&&&&&\dot{x}\pt{T}\\ &&&&&&\dot{x}\pt{T}\\ \end{+bmatrix}$$

\end{document}


• Very elegant looking solution! Commented Dec 6, 2023 at 17:33
• @Dr.ManuelKuehner Thanks! Commented Dec 6, 2023 at 17:58

I just want rows 1, 3, 5 and columns 1, 3, 5

This can be interpreted in at least three ways.

1. All the entries in both rows 1,3,5 and columns 1,3,5, collapsed into a filled-in matrix.
2. All the entries in both rows 1,3,5 and columns 1,3,5, left as they are in the original matrix.
3. All the entries in either rows 1,3,5 or columns 1,3,5, left as they are in the original matrix.

I'll provide some code for each interpretation. In each case the code is probably suboptimal in terms of efficiency, but for personal use it should be sufficient. Much inspiration was taken from egreg's answer here.

Each command below has the following keys. Hopefully they are self explanatory.

• symbol=<symbol>, initially \varphi
• rows=<integer>
• cols=<integer>
• row-spec=<comma list of integers>
• col-spec=<comma list of integers>
• final-col=<comma list of entries>

## Approach 1

Here you can provide either rows or row-spec but not both. Similarly for cols and col-spec.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand { \automatrix } { m }
{
\group_begin:
\keys_set:nn { mascolo/automatrix } { #1 }
\mascolo_automatrix:
\group_end:
}

\tl_new:N \l__mascolo_automatrix_tl

\keys_define:nn { mascolo/automatrix }
{
symbol    .tl_set:N    = \l__mascolo_automatrix_symbol_tl,
symbol    .initial:n   = \varphi,
rows      .int_set:N   = \l__mascolo_automatrix_totrows_int,
cols      .int_set:N   = \l__mascolo_automatrix_totcols_int,
row-spec  .clist_set:N = \l__mascolo_automatrix_rowspec_clist,
col-spec  .clist_set:N = \l__mascolo_automatrix_colspec_clist,
final-col .clist_set:N = \l__mascolo_automatrix_finalcol_clist,
}

\cs_new_protected:Nn \mascolo_automatrix:
{
\int_compare:nT
{
\int_max:nn { \l__mascolo_automatrix_totrows_int }
{ \l__mascolo_automatrix_totcols_int } > \value{MaxMatrixCols}
}
{
\setcounter{MaxMatrixCols}
{
\int_max:nn { \l__mascolo_automatrix_totrows_int }
{ \l__mascolo_automatrix_totcols_int }
}
}
\clist_if_empty:NTF \l__mascolo_automatrix_rowspec_clist
{
\int_step_function:nN { \l__mascolo_automatrix_totrows_int }
\__mascolo_automatrix_row:n
}
{
\int_step_inline:nn
{ \fp_eval:n { max( \l__mascolo_automatrix_rowspec_clist ) } }
{
\clist_if_in:NnTF \l__mascolo_automatrix_rowspec_clist { ##1 }
{ \__mascolo_automatrix_row:n { ##1 } }
{ \clist_pop:NN \l__mascolo_automatrix_finalcol_clist \l_tmpa_tl }
}
}
\begin{bmatrix}
\l__mascolo_automatrix_tl
\end{bmatrix}
}

\cs_new_protected:Nn \__mascolo_automatrix_row:n
{
\clist_if_empty:NTF \l__mascolo_automatrix_colspec_clist
{ \__mascolo_automatrix_row_nocolspec:n { #1 } }
{ \__mascolo_automatrix_row_withcolspec:n { #1 } }
}

\cs_new_protected:Nn \__mascolo_automatrix_row_nocolspec:n
{
\tl_put_right:Nn \l__mascolo_automatrix_tl
{ \l__mascolo_automatrix_symbol_tl \sb{ #1,1 } }
\int_step_inline:nnn { 2 } { \l__mascolo_automatrix_totcols_int }
{
\tl_put_right:Nn \l__mascolo_automatrix_tl
{
&
\l__mascolo_automatrix_symbol_tl \sb{ #1,##1 }
}
}
\clist_pop:NNTF \l__mascolo_automatrix_finalcol_clist \l_tmpa_tl
{
\tl_put_right:Nn \l__mascolo_automatrix_tl { & }
\tl_put_right:NV \l__mascolo_automatrix_tl \l_tmpa_tl
}
{ }
\tl_put_right:Nn \l__mascolo_automatrix_tl { \\ }
}

\cs_new_protected:Nn \__mascolo_automatrix_row_withcolspec:n
{
\tl_put_right:Nn \l__mascolo_automatrix_tl
{
\l__mascolo_automatrix_symbol_tl
\sb{ #1,\clist_item:Nn \l__mascolo_automatrix_colspec_clist{1} }
}
\int_step_inline:nnn { 2 } { \clist_count:N \l__mascolo_automatrix_colspec_clist }
{
\tl_put_right:Nn \l__mascolo_automatrix_tl
{
&
\l__mascolo_automatrix_symbol_tl
\sb{ #1,\clist_item:Nn \l__mascolo_automatrix_colspec_clist { ##1 } }
}
}
\clist_pop:NNTF \l__mascolo_automatrix_finalcol_clist \l_tmpa_tl
{
\tl_put_right:Nn \l__mascolo_automatrix_tl { & }
\tl_put_right:NV \l__mascolo_automatrix_tl \l_tmpa_tl
}
{ }
\tl_put_right:Nn \l__mascolo_automatrix_tl { \\ }
}

\ExplSyntaxOff

\begin{document}

$\automatrix{rows=4,cols=5,symbol=\xi,final-col={w,x,y,z}} \quad \automatrix{cols=5,row-spec={2,4},final-col={w,x,y,z}}$
$\automatrix{rows=4,col-spec={2,4}} \quad \automatrix{row-spec={2,4},col-spec={2,4}}$

\end{document}


## Approach 2

Here the keys rows and cols are required since we need to know in advance how big the original matrix is.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand { \automatrixalt } { m }
{
\group_begin:
\keys_set:nn { mascolo/automatrixalt } { #1 }
\mascolo_automatrixalt:
\group_end:
}

\tl_new:N \l__mascolo_automatrixalt_tl

\keys_define:nn { mascolo/automatrixalt }
{
symbol    .tl_set:N         = \l__mascolo_automatrixalt_symbol_tl,
symbol    .initial:n        = \varphi,
rows      .int_set:N        = \l__mascolo_automatrixalt_totrows_int,
rows      .value_required:n = true,
cols      .int_set:N        = \l__mascolo_automatrixalt_totcols_int,
cols      .value_required:n = true,
row-spec  .clist_set:N      = \l__mascolo_automatrixalt_rowspec_clist,
col-spec  .clist_set:N      = \l__mascolo_automatrixalt_colspec_clist,
final-col .clist_set:N      = \l__mascolo_automatrixalt_finalcol_clist,
}

\cs_new_protected:Nn \mascolo_automatrixalt:
{
\int_compare:nT
{
\int_max:nn { \l__mascolo_automatrixalt_totrows_int }
{ \l__mascolo_automatrixalt_totcols_int } > \value{MaxMatrixCols}
}
{
\setcounter{MaxMatrixCols}
{
\int_max:nn { \l__mascolo_automatrixalt_totrows_int }
{ \l__mascolo_automatrixalt_totcols_int }
}
}
\clist_if_empty:NTF \l__mascolo_automatrixalt_rowspec_clist
{
\int_step_function:nN { \l__mascolo_automatrixalt_totrows_int }
\__mascolo_automatrixalt_row:n
}
{
\int_step_inline:nn
{ \l__mascolo_automatrixalt_totrows_int }
{
\clist_if_in:NnTF \l__mascolo_automatrixalt_rowspec_clist { ##1 }
{ \__mascolo_automatrixalt_row:n { ##1 } }
{
\clist_pop:NN \l__mascolo_automatrixalt_finalcol_clist \l_tmpa_tl
\tl_put_right:Nn \l__mascolo_automatrixalt_tl { \\ }
}
}
}
\begin{bmatrix}
\l__mascolo_automatrixalt_tl
\end{bmatrix}
}

\cs_new_protected:Nn \__mascolo_automatrixalt_row:n
{
\clist_if_empty:NTF \l__mascolo_automatrixalt_colspec_clist
{ \__mascolo_automatrixalt_row_nocolspec:n { #1 } }
{ \__mascolo_automatrixalt_row_withcolspec:n { #1 } }
}

\cs_new_protected:Nn \__mascolo_automatrixalt_row_nocolspec:n
{
\tl_put_right:Nn \l__mascolo_automatrixalt_tl
{ \l__mascolo_automatrixalt_symbol_tl \sb{ #1,1 } }
\int_step_inline:nnn { 2 } { \l__mascolo_automatrixalt_totcols_int }
{
\tl_put_right:Nn \l__mascolo_automatrixalt_tl
{
&
\l__mascolo_automatrixalt_symbol_tl \sb{ #1,##1 }
}
}
\clist_pop:NNTF \l__mascolo_automatrixalt_finalcol_clist \l_tmpa_tl
{
\tl_put_right:Nn \l__mascolo_automatrixalt_tl { & }
\tl_put_right:NV \l__mascolo_automatrixalt_tl \l_tmpa_tl
}
{ }
\tl_put_right:Nn \l__mascolo_automatrixalt_tl { \\ }
}

\cs_new_protected:Nn \__mascolo_automatrixalt_row_withcolspec:n
{
\tl_put_right:Nn \l__mascolo_automatrixalt_tl
{
\clist_if_in:NnTF \l__mascolo_automatrixalt_colspec_clist { 1 }
{ \l__mascolo_automatrixalt_symbol_tl \sb{ #1,1 } }
{ \phantom{ \l__mascolo_automatrixalt_symbol_tl \sb{ #1,1 } } }
}
\int_compare:nNnT { \l__mascolo_automatrixalt_totcols_int } > { 1 }
{
\int_step_inline:nnn { 2 } { \l__mascolo_automatrixalt_totcols_int }
{
\tl_put_right:Nn \l__mascolo_automatrixalt_tl
{
&
\clist_if_in:NnTF \l__mascolo_automatrixalt_colspec_clist { ##1 }
{ \l__mascolo_automatrixalt_symbol_tl \sb{ #1,##1 } }
{ \phantom{ \l__mascolo_automatrixalt_symbol_tl \sb{ #1,##1 } } }
}
}
}
\clist_pop:NNTF \l__mascolo_automatrixalt_finalcol_clist \l_tmpa_tl
{
\tl_put_right:Nn \l__mascolo_automatrixalt_tl { & }
\tl_put_right:NV \l__mascolo_automatrixalt_tl \l_tmpa_tl
}
{ }
\tl_put_right:Nn \l__mascolo_automatrixalt_tl { \\ }
}

\ExplSyntaxOff

\begin{document}

$\automatrixalt{rows=4,cols=5,symbol=\xi,final-col={w,x,y,z}} \quad \automatrixalt{rows=4,cols=5,row-spec={2,4},final-col={w,x,y,z}}$
$\automatrixalt{rows=4,cols=5,col-spec={2,4}} \quad \automatrixalt{rows=4,cols=5,row-spec={2,4},col-spec={2,4}}$

\end{document}


## Approach 3

As with approach 2, the keys rows and cols are required here.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand { \automatrixaltii } { m }
{
\group_begin:
\keys_set:nn { mascolo/automatrixaltii } { #1 }
\mascolo_automatrixaltii:
\group_end:
}

\tl_new:N \l__mascolo_automatrixaltii_tl

\keys_define:nn { mascolo/automatrixaltii }
{
symbol    .tl_set:N         = \l__mascolo_automatrixaltii_symbol_tl,
symbol    .initial:n        = \varphi,
rows      .int_set:N        = \l__mascolo_automatrixaltii_totrows_int,
rows      .value_required:n = true,
cols      .int_set:N        = \l__mascolo_automatrixaltii_totcols_int,
cols      .value_required:n = true,
row-spec  .clist_set:N      = \l__mascolo_automatrixaltii_rowspec_clist,
col-spec  .clist_set:N      = \l__mascolo_automatrixaltii_colspec_clist,
final-col .clist_set:N      = \l__mascolo_automatrixaltii_finalcol_clist,
}

\cs_new_protected:Nn \mascolo_automatrixaltii:
{
\int_compare:nNnT
{
\int_max:nn { \l__mascolo_automatrixaltii_totrows_int }
{ \l__mascolo_automatrixaltii_totcols_int }
}
> { \value{MaxMatrixCols} }
{
\setcounter{MaxMatrixCols}
{
\int_max:nn { \l__mascolo_automatrixaltii_totrows_int }
{ \l__mascolo_automatrixaltii_totcols_int }
}
}
\clist_if_empty:NTF \l__mascolo_automatrixaltii_rowspec_clist
{
\int_step_function:nN { \l__mascolo_automatrixaltii_totrows_int }
\__mascolo_automatrixaltii_row:n
}
{
\int_step_inline:nn
{ \l__mascolo_automatrixaltii_totrows_int }
{
\clist_if_in:NnTF \l__mascolo_automatrixaltii_rowspec_clist { ##1 }
{ \__mascolo_automatrixaltii_row_nocolspec:n { ##1 } }
{ \__mascolo_automatrixaltii_row_notinrowspec:n { ##1 } }
}
}
\begin{bmatrix}
\l__mascolo_automatrixaltii_tl
\end{bmatrix}
}

\cs_new_protected:Nn \__mascolo_automatrixaltii_row:n
{
\clist_if_empty:NTF \l__mascolo_automatrixaltii_colspec_clist
{ \__mascolo_automatrixaltii_row_nocolspec:n { #1 } }
{ \__mascolo_automatrixaltii_row_notinrowspec:n { #1 } }
}

\cs_new_protected:Nn \__mascolo_automatrixaltii_row_nocolspec:n
{
\tl_put_right:Nn \l__mascolo_automatrixaltii_tl
{ \l__mascolo_automatrixaltii_symbol_tl \sb{ #1,1 } }
\int_step_inline:nnn { 2 } { \l__mascolo_automatrixaltii_totcols_int }
{
\tl_put_right:Nn \l__mascolo_automatrixaltii_tl
{
&
\l__mascolo_automatrixaltii_symbol_tl \sb{ #1,##1 }
}
}
\clist_pop:NNTF \l__mascolo_automatrixaltii_finalcol_clist \l_tmpa_tl
{
\tl_put_right:Nn \l__mascolo_automatrixaltii_tl { & }
\tl_put_right:NV \l__mascolo_automatrixaltii_tl \l_tmpa_tl
}
{ }
\tl_put_right:Nn \l__mascolo_automatrixaltii_tl { \\ }
}

\cs_new_protected:Nn \__mascolo_automatrixaltii_row_notinrowspec:n
{
\tl_put_right:Nn \l__mascolo_automatrixaltii_tl
{
\clist_if_in:NnTF \l__mascolo_automatrixaltii_colspec_clist { 1 }
{ \l__mascolo_automatrixaltii_symbol_tl \sb{ #1,1 } }
{ \phantom{ \l__mascolo_automatrixaltii_symbol_tl \sb{ #1,1 } } }
}
\int_compare:nNnT { \l__mascolo_automatrixaltii_totcols_int } > { 1 }
{
\int_step_inline:nnn { 2 } { \l__mascolo_automatrixaltii_totcols_int }
{
\tl_put_right:Nn \l__mascolo_automatrixaltii_tl
{
&
\clist_if_in:NnTF \l__mascolo_automatrixaltii_colspec_clist { ##1 }
{ \l__mascolo_automatrixaltii_symbol_tl \sb{ #1,##1 } }
{ \phantom{ \l__mascolo_automatrixaltii_symbol_tl \sb{ #1,##1 } } }
}
}
}
\tl_put_right:Nn \l__mascolo_automatrixaltii_tl { \\ }
\clist_pop:NN \l__mascolo_automatrixaltii_finalcol_clist \l_tmpa_tl
}

\ExplSyntaxOff

\begin{document}

$\automatrixaltii{rows=4,cols=5,symbol=\xi,final-col={w,x,y,z}} \quad \automatrixaltii{rows=4,cols=5,row-spec={2,4},final-col={w,x,y,z}}$
$\automatrixaltii{rows=4,cols=5,col-spec={2,4}} \quad \automatrixaltii{rows=4,cols=5,row-spec={2,4},col-spec={2,4}}$

\end{document}