定义一个向量宏,使其在内联/显示数学模式下以不同的方式显示

定义一个向量宏,使其在内联/显示数学模式下以不同的方式显示

我想定义一个命令,根据向量是处于显示模式还是内联数学模式来定义向量。到目前为止,我已经尝试过这个,但没有成功:

\newcommand{\ve}[1]{\ensuremath{%
    \mathchoice{%
        \begin{pmatrix}%
            \StrSubstitute{#1}{,}{\\}%
        \end{pmatrix}%
    }{%
        \left(\begin{smallmatrix}%
            \StrSubstitute{#1}{,}{\\}%
        \end{smallmatrix}\right)%
    }{#1}{#1}%
}}

我希望能够$$\ve{1,2,x}$$扩展到

\begin{pmatrix}
    1\\2\\x
\end{pmatrix}

$\ve{1,2,x}$扩展至

\left(\begin{smallmatrix}
    1\\2\\x
\end{smallmatrix}\right)

答案1

\displaystyle区分内联和显示数学与区分\textstyle和可能很棘手,因为align类似环境的amsmath内部使用$\displaystyle...$\ensuremath此外,如果您在数学模式之外调用宏,您的定义将始终使用\textstyle。在我看来(当然值得怀疑),\ensuremath除非可爱的小猫和毛茸茸的兔子的生命取决于它,否则不应使用它;而且在这种情况下也不应该轻易使用它。

幸运的是,amsmath提供了一个布尔值\if@display,因此我们可以(滥用)使用它。我会加载mathtools,这是的扩展amsmath,其中除其他外,它已经定义了一个psmallmatrix环境。

\documentclass{article}

\usepackage{mathtools}% loads amsmath

\makeatletter

\newcommand*{\ve}[1]{%
   \begingroup
   \if@display
      \def\@tempa{{pmatrix}}
   \else
      \def\@tempa{{psmallmatrix}}
   \fi
   \expandafter\begin\@tempa
   \@ve#1,\@@nil,
   \expandafter\end\@tempa
   \endgroup
}
   
\def\@ve#1,{\ifx\@@nil#1\else#1\\\expandafter\@ve\fi}

\makeatother

\begin{document}

\hsize=4cm % for the snapshot

\[
\ve{a}\ve{a,b}\ve{a,b,c}
\]

\begin{align*}
\ve{a}\ve{a,b}\ve{a,b,c}
\end{align*}

$\ve{a}\ve{a,b}\ve{a,b,c}$

\end{document}

在此处输入图片描述

编辑一个版本就像 egreg 的回答一样使用\mathchoice。为了完整性,我还添加了一个行向量。这需要更多的技巧,因为\\在列向量的末尾添加没有什么坏处(就像我的第一个代码一样),但是当你&在行的末尾添加一个时就会出错。

\documentclass{article}

\usepackage{mathtools}

\makeatletter

\newcommand*{\cvector}[1]{\cr@vector{\\}{#1}}
\newcommand*{\rvector}[1]{\cr@vector{&}{#1}}

\newcommand*{\cr@vector}[2]{%
   \mathchoice{\cr@@vector{#1}{#2}{}}%
              {\cr@@vector{#1}{#2}{small}}%
              {\cr@@vector{#1}{#2}{small}}%
              {\cr@@vector{#1}{#2}{small}}%
}

\newcommand*{\cr@@vector}[3]{%
   \def\@tempa{\gdef\@tempa{#1}}% first time does nothing, afterwards it's \\ or &
   \def\@tempb##1,{\ifx\@@nil##1\else\@tempa##1\expandafter\@tempb\fi}%
   \begin{p#3matrix}
   \@tempb#2,\@@nil,
   \end{p#3matrix}
}

\makeatother


\begin{document}

\hsize=5cm % for smaller snapshot

Display
\begin{align*}
\rvector{a,b,c} \cvector{a,b,c}
= \frac{\rvector{x,y} \cvector{u,v}}{\rvector{1,2,3}\cvector{4,5,6}}
\end{align*}
and inline $\rvector{a,b,c}$, $\cvector{a,b,c,d,e}$

\end{document}

在此处输入图片描述

可以在和\mathchoice的定义中直接使用并省去一个中间宏,但我发现代码的可读性较差。\cvector\rvector

答案2

这个想法很好。\ensuremath当然,事实并非如此。

\documentclass[twocolumn]{article} % twocolumn is just to get a smaller picture
\usepackage{amsmath}

\ExplSyntaxOn
\NewDocumentCommand{\ve}{m}
 {
  \mathchoice
    {\raymo_ve_display:n {#1}}
    {\raymo_ve_inline:n {#1}}
    {\raymo_ve_inline:n {#1}}
    {\raymo_ve_inline:n {#1}}
 }
\cs_new_protected:Nn \__raymo_ve_make:n
 {
  \seq_set_split:Nnn \l__raymo_ve_body_seq { , } { #1 }
  \seq_use:Nn \l__raymo_ve_body_seq { \\ }
 }
\cs_new_protected:Nn \raymo_ve_display:n
 {
  \begin{pmatrix}
  \__raymo_ve_make:n { #1 }
  \end{pmatrix}
 }
\cs_new_protected:Nn \raymo_ve_inline:n
 {
  \left(\begin{smallmatrix}
  \__raymo_ve_make:n { #1 }
  \end{smallmatrix}\right)
 }
\ExplSyntaxOff

\begin{document}

This is inline $\ve{1,2,x}$ and there is also a display
\[
\ve{1,2,x}
\]

\end{document}

如果您没有运行最新的 LaTeX 内核(2020-10-01),那么您需要\usepackage{xparse}

我发现expl3比好多了xstrings

在此处输入图片描述

“优化”代码也支持行向量:

\documentclass[twocolumn]{article} % twocolumn is just to get a smaller picture
\usepackage{amsmath,mathtools}

\ExplSyntaxOn
\NewDocumentCommand{\gve}{mm}
 {% #1 = c or r
  \mathchoice
    {\raymo_ve_build:nnn {#1}{#2}{}}
    {\raymo_ve_build:nnn {#1}{#2}{small}}
    {\raymo_ve_build:nnn {#1}{#2}{small}}
    {\raymo_ve_build:nnn {#1}{#2}{small}}
 }
\NewDocumentCommand{\ve}{m}{\gve{c}{#1}}
\NewDocumentCommand{\rve}{m}{\gve{r}{#1}}

\cs_new_protected:Nn \__raymo_ve_make:nn
 {
  \seq_set_split:Nnn \l__raymo_ve_body_seq { , } { #2 }
  \seq_use:Nn \l__raymo_ve_body_seq { \str_case:nn {#1}{{c}{\\}{r}{&}} }
 }
\cs_new_protected:Nn \raymo_ve_build:nnn
 {
  \begin{p#3matrix}
  \__raymo_ve_make:nn { #1 } { #2 }
  \end{p#3matrix}
 }
\ExplSyntaxOff

\begin{document}

This is inline $\ve{1,2,x}\rve{1,2,x}$ and there is also a display
\[
\ve{1,2,x}\rve{1,2,x}
\]

\end{document}

在此处输入图片描述

相关内容