Vertical Alignment of Matrices with spalign Package
This is not supported by spalign
.
Here's a different implementation.
\documentclass[12pt]{report}
\usepackage{xparse}
\usepackage{amsmath}
\usepackage{delarray}
\ExplSyntaxOn
\NewDocumentCommand{\extraalign}{O{}m}
{
\group_begin:
\keys_set:nn { extraalign } { #1 }
\extraalign_make:n { #2 }
\group_end:
}
\NewDocumentCommand{\extraalignset}{m}
{
\keys_set:nn { extraalign } { #1 }
}
\tl_new:N \l__extraalign_cols_tl
\tl_new:N \l__extraalign_row_tl
\seq_new:N \l__extraalign_rows_in_seq
\seq_new:N \l__extraalign_rows_out_seq
\seq_new:N \l__extraalign_row_seq
\int_new:N \l__extraalign_cols_int
\keys_define:nn { extraalign }
{
h .code:n = \tl_set:Nn \l__extraalign_cols_tl { *{\l__extraalign_cols_int}{#1} },
h .initial:n = c,
v .tl_set:N = \l__extraalign_vertical_tl,
v .initial:n = c,
p .code:n = \tl_set:Nn \l__extraalign_cols_tl { #1 },
l .tl_set:N = \l__extraalign_left_tl,
l .initial:n = (,
r .tl_set:N = \l__extraalign_right_tl,
r .initial:n = ),
}
\cs_new_protected:Nn \extraalign_make:n
{
\__extraalign_body:n { #1 }
\__extraalign_preamble:VVVV
\l__extraalign_vertical_tl % vertical alignment
\l__extraalign_left_tl % left delimiter
\l__extraalign_right_tl % right delimiter
\l__extraalign_cols_tl % column spec
% deliver the matrix
\seq_use:Nn \l__extraalign_rows_out_seq { \\ }
\end{array}
}
\cs_new_protected:Nn \__extraalign_preamble:nnnn
{
\begin{array}[#1]#2{@{}#4@{}}#3
}
\cs_generate_variant:Nn \__extraalign_preamble:nnnn { VVVV }
\cs_new_protected:Nn \__extraalign_body:n
{
\seq_set_split:Nnn \l__extraalign_rows_in_seq { ; } { #1 }
\seq_clear:N \l__extraalign_rows_out_seq
\seq_map_variable:NNn \l__extraalign_rows_in_seq \l__extraalign_row_tl
{
\__extraalign_makerow:V \l__extraalign_row_tl
}
}
\cs_new_protected:Nn \__extraalign_makerow:n
{
\seq_set_split:Nnn \__extraalign_row_seq { ~ } { #1 }
\int_compare:nT { \l__extraalign_cols_int = 0 }
{
\int_set:Nn \l__extraalign_cols_int { \seq_count:N \__extraalign_row_seq }
}
\seq_put_right:Nx \l__extraalign_rows_out_seq
{ \seq_use:Nn \__extraalign_row_seq { & } }
}
\cs_generate_variant:Nn \__extraalign_makerow:n { V }
\ExplSyntaxOff
\begin{document}
\begin{gather*}
A=\begin{pmatrix}1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9\end{pmatrix}
\quad
A=\extraalign{1 2 3;4 5 6;7 8 9}
\\
A=\extraalign[v=t]{1 2 3;4 5 6;7 8 9}
\quad
A=\extraalign[p=rcl,v=t]{-1 2 3;4 5 66;700 8 9000}
\\
A=\extraalign[l=\{,r=.,h=l]{aaaa ; bbb ; c}
\end{gather*}
\end{document}
The optional argument to \extraalign
contains a key-value list of options
h
for the general format of columns (defaultc
), with as many columns as requiredp
for a special preamble, specifying all columnsv
for the vertical alignment,t
,c
orb
(defaultc
)l
for the left delimiter (default(
); use.
for no delimiterr
for the right delimiter (default)
); use.
for no delimiter
Should you want to change the default values, use \extraalignset
with the values you want. For instance, if you do
\extraalignset{ l = [, r = ] }
all matrices (in the current scope or globally if done in the preamble) will use brackets unless locally countermanded.
Just for completeness, here's how you can do augmented matrices.
\extraalignset{l=[,r=]}
\begin{gather*}
A=\extraalign[p=cccc|cc]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\quad
A=\extraalign[p=cccc|cc,v=t]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\\
A=\extraalign[p=ccc|ccc]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\quad
A=\extraalign[p=ccc|ccc,v=t]{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}
\end{gather*}
\documentclass{article}
\usepackage{tabstackengine,scalerel}
\TABstackMath
\setstacktabbedgap{1ex}
\strutlongstacks{T}
\begin{document}
\[
A = \tabbedLongunderstack{1&2&3\\4&5&6\\7&8&9}
\]
\[
A = \scaleleftright[1.5ex]{\Biggl(}
{\tabbedLongunderstack{1&2&3\\4&5&6\\7&8&9}}{\Biggr)}
\]
\[
\savestack\mysystem{\setstacktabbedgap{0pt}%
\tabbedCenterstack[r]{2x +& 3y =& 1\\x -& y =& 10}}
\renewcommand\stackalignment{r}
\stackunder[10pt]
{$A = \tabbedLongunderstack{1&2&3\\4&5&6\\7&8&9}$}
{A system using tabstackengine: $\biggl\{\mysystem$}
\]
\end{document}
I appreciate the other answers. This was bothering me for a while, and as it sat unanswered for so long (I think it is too specific, no one but me apparently needed to be able to do this) I had found a way to do it by patching the spalign
commands. Just in case anyone else ever wonders how to do this, I'll post my answer here.
I had to dig into the existing spalign
code a bit. The matrices are built using array
s as expected, so I initially thought to just replace \begin{align}
by \begin{align}[t]
. However, this creates a problem where the delimiters are also centered on the top line:
To solve that problem, I used delarray
as suggested in this answer (and as suggested again by egreg's answer this question).
However, this required a much more complicated find-and-replace in the existing code of spalign
, since the macros in that package put the delimiters outside of the array
environment (as is usual when not using delarray
. At any rate, I became a little obsessed with solving this problem and managed it with xpatch
and some trial-and-error. I think it's a bit of a mess (partly because of the way *
s are handled in spalign
), but the following code creates duplicates of several of the spalign
environments, aligned with their top rows, with all optional arguments and starred versions intact:
\documentclass[12pt]{report}
\usepackage{amsmath}
\usepackage[delims={[}{]},sysdelims={.}{.}]{spalign} %set to square brackets on matrices and no delimiters on systems
\usepackage{letltxmacro}
\usepackage{delarray}
\usepackage{xpatch}
\makeatletter
\let\tmat=\spalignmat
\let\tmatx=\spalignmat@x
\LetLtxMacro\tmatstar\spalignmat@star
\xpatchcmd{\tmat}{\spalignmat@x}{\tmatx}{}{}
\xpatchcmd{\tmatx}{\spalignmat@star}{\tmatstar}{}{}
\xpatchcmd{\tmatstar}{\spalign@maybedelim}{\spalignenv}{}{}
\xpatchcmd{\tmatstar}{\begin{array}{\spalign@repeated}}%
{\begin{array}[t]\ifspalign@star\else\spalign@leftdelim\fi%
{@{\spalignmatdelimskip}\spalign@repeated @{\spalignmatdelimskip}}%
\ifspalign@star\else\spalign@rightdelim\fi}{}{}
\xpatchcmd{\tmatstar}{{\hskip-\arraycolsep\spalignmatdelimskip}}{}{}{}
\providecommand{\dtmat}[2][r]{{\detm \tmat[#1]{#2}}}
\let\tamatn=\spalignaugmatn
\let\tamatnx=\spalignaugmatn@x
\LetLtxMacro\tamatnstar\spalignaugmatn@star
\xpatchcmd{\tamatn}{\spalignaugmatn@x}{\tamatnx}{}{}
\xpatchcmd{\tamatnx}{\spalignaugmatn@star}{\tamatnstar}{}{}
\xpatchcmd{\tamatnstar}{\spalign@maybedelim}{\spalignenv}{}{}
\xpatchcmd{\tamatnstar}{\begin{array}{\spalign@repeated@one|\spalign@repeated@two}}%
{\begin{array}[t]\ifspalign@star\else\spalign@leftdelim\fi%
{@{\spalignmatdelimskip}\spalign@repeated@one|\spalign@repeated@two @{\spalignmatdelimskip}}\ifspalign@star\else\spalign@rightdelim\fi}{}{}
\xpatchcmd{\tamatnstar}{{\hskip-\arraycolsep\spalignmatdelimskip}}{}{}{}
\providecommand{\tamat}[1][r]{%
\tamatn[#1]{1}%
}%
\let\tamath=\spalignaugmathalf
\let\tamathx=\spalignaugmathalf@x
\LetLtxMacro\tamathstar\spalignaugmathalf@star
\xpatchcmd{\tamath}{\spalignaugmathalf@x}{\tamathx}{}{}
\xpatchcmd{\tamathx}{\spalignaugmathalf@star}{\tamathstar}{}{}
\xpatchcmd{\tamathstar}{\spalign@maybedelim}{\spalignenv}{}{}
\xpatchcmd{\tamathstar}{\begin{array}{\spalign@repeated@one|\spalign@repeated@two}}%
{\begin{array}[t]\ifspalign@star\else\spalign@leftdelim\fi%
{@{\spalignmatdelimskip}\spalign@repeated@one|\spalign@repeated@two @{\spalignmatdelimskip}}\ifspalign@star\else\spalign@rightdelim\fi}{}{}
\xpatchcmd{\tamathstar}{{\hskip-\arraycolsep\spalignmatdelimskip}}{}{}{}
\let\tsys=\spalignsys
\let\tsysx=\spalignsys@x
\let\tsysstar=\spalignsys@star
\xpatchcmd{\tsys}{\spalignsys@x}{\tsysx}{}{}
\xpatchcmd{\tsysx}{\spalignsys@star}{\tsysstar}{}{}
\xpatchcmd{\tsysstar}{\vcenter}{\vtop}{}{}
\makeatother
\begin{document}
\[
A=\spalignmat{1 2 3;4 5 6;7 8 9}. \quad A=\tmat{1 2 3;4 5 6;7 8 9}.
\]
\[
A=\spalignaugmat{1 2 3;4 5 6;7 8 9}. \quad A=\tamat{1 2 3;4 5 6;7 8 9}.
\]
\[
A=\spalignaugmatn{2}{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}. \quad A=\tamatn{2}{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}.
\]
\[
A=\spalignaugmathalf{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}. \quad A=\tamath{1 2 3 4 5 6;4 5 6 7 8 9;7 8 9 1 2 3}.
\]
System of equations:
$\spalignsys{2x + 3y = 1;x - y = 10}$.\quad
Top aligned:
$\tsys{2x + 3y = 1;x - y = 10}$.
\end{document}
Which produces:
Those were all I needed, so they're all I patched. Others could be done similarly.
The *
ed versions omit the delimiters, and the matrices take optional arguments to specify column alignments. Both of these features still work as in the original spalign
.
It would perhaps be easier to just define anew the macros I want instead of using \xpatchcmd
, but I found it instructive to do it this way. I had never used xpatch
before and learned a lot in this first attempt.
I was not able to get the delimiters top-aligned for a system of equations because spalign
uses halign
for that instead of the array
environment. For me, this was not a problem, since the book I am teaching from doesn't use delimiters on systems anyway, and I wanted to use consistent notation.