我尝试阅读有关 \newcommand* 的其他主题,以创建宏以便使用单个命令进行重复求和,但我无法理解其背后的逻辑。让我更好地解释一下:我想创建一个 \newcommand,只需输入 \repsum{9}{F}{u},其中 9 是重复次数,就可以创建一个输出,如下所示
F_1u_1+F_2u_2+F_3u_3+...+F_8u_8+F_9u_9。
有人能帮我解决这个问题吗?非常感谢 :)
编辑
感谢您的回答。如果我没有发布 MWE,我很抱歉。当前用户和 zarko 提供的答案可以解决问题,但它使用了 tikzpicture,而我想在数学模式下使用它。我将添加一个示例来向您展示我想要做的事情(在伪代码中 newcommand)
\documentclass{article}
\newcommand*{\repsum}[3]{
for i=1:#1
if i~=#1
#2_i#3_i+
else
#2_i#3_i
end
end
\begin{document}
The CUF Refined theory expands the summation as
\begin{equation}
u=\repsum{9}{F}{u}=F_\tau u_\tau
\end{equation}
where the last expression exploits the Einstein notation.
\end{document}
答案1
要在数学模式下使用它,您只需使用\foreach
外部a tikzpicture
. 这将需要pgffor
包(仅当您不使用 Ti钾z 已):
\documentclass[]{article}
\usepackage{mathtools}
\usepackage{pgffor}
\newcommand{\repsum}[3]{%
\foreach \i in {1,...,#1}{
\ifnum\i>1
+ #2_{\i} #3_{\i}
\else
#2_{\i} #3_{\i}
\fi
}
}
\begin{document}
\begin{equation*}
\mathbf{F}\bullet\mathbf{u} = \repsum{9}{F}{u}
\end{equation*}
\end{document}
答案2
您可以使用xparse
:
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\repsum}{O{3}mmm}
{% #1 = optional number of starting summands
% #2 = final number
% #3 = first symbol
% #4 = second symbol
\int_step_inline:nn { #1 } { #3\sb{##1}#4\sb{##1} + }
\dotsb
\int_step_inline:nnn { #2 - 1} { #2 } { + #3\sb{##1}#4\sb{##1} }
}
\ExplSyntaxOff
\begin{document}
First test: $\repsum{9}{F}{u}$
Second test: $\repsum[2]{6}{F}{u}$
The CUF Refined theory expands the summation as
\begin{equation}
u=\repsum{9}{F}{u}=F_\tau u_\tau
\end{equation}
where the last expression exploits the Einstein notation.
\end{document}
这个想法是从 1 到 3(或可选参数中指定的数字)进行循环,打印加数及其下标,后跟 + ;然后打印点和 +,后跟从#2-1
(#2
是最终的加数个数)到 的加数#2
。
使用此实现,您有责任确保不重叠。因此您可以执行\repsum[1]{4}{F}{u}
,但如果加数少于四个,则它将不起作用。
另一个版本是如果不需要点则自动跳过点。
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\repsum}{O{3}mmm}
{% #1 = optional number of starting summands
% #2 = final number
% #3 = first symbol
% #4 = second symbol
\int_compare:nTF { #2 - #1 < 3 }
{% no dots necessary
#3\sb{1}#4\sb{1}
\int_step_inline:nnn { 2 } { #2 } { + #3\sb{##1}#4\sb{##1} }
}
{
\int_step_inline:nn { #1 } { #3\sb{##1}#4\sb{##1} + }
\dotsb
\int_step_inline:nnn { #2 - 1} { #2 } { + #3\sb{##1}#4\sb{##1} }
}
}
\ExplSyntaxOff
\begin{document}
First test: $\repsum{9}{F}{u}$
Second test: $\repsum[2]{6}{F}{u}$
Third test: $\repsum{5}{F}{u}$
Fourth test: $\repsum{3}{F}{u}$
Fifth test: $\repsum{2}{F}{u}$
Sixth test: $\repsum{1}{F}{u}$
The CUF Refined theory expands the summation as
\begin{equation}
u=\repsum{9}{F}{u}=F_\tau u_\tau
\end{equation}
where the last expression exploits the Einstein notation.
\end{document}
答案3
也许是这个?
\documentclass{article}
\usepackage{tikz}
\newcommand{\cussum}[1]{
\begin{tikzpicture}[baseline=-.1cm]
\foreach \x in {1,2,...,#1}
{
\ifnum\x<#1
\node at (\x,0) {$F_{\x}u_{\x}+$};
\fi
\ifnum\x=#1
\node at (\x-.1,0) {$F_{\x}u_{\x}$};
\fi
}
\end{tikzpicture}
}
\begin{document}
\cussum{9} Minimal Working Examples are nice, aren't they \ldots
\end{document}
输出如下:
答案4
重新使用我\replaceiandreplicate
在讨论中提到的宏如何制作一个命令来自动创建类似素数分解的乘积?,处理此事的可能性可能是:
\documentclass{article}
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo,
%% \UD@PassFirstToSecond, \UD@Exchange, \UD@removespace
%% \UD@CheckWhetherNull, \UD@CheckWhetherBrace,
%% \UD@CheckWhetherLeadingSpace, \UD@ExtractFirstArg
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@removespace{}\UD@firstoftwo{\def\UD@removespace}{} {}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's first token is a catcode-1-character
%%.............................................................................
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has leading
%% catcode-1-token>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has no leading
%% catcode-1-token>}%
\newcommand\UD@CheckWhetherBrace[1]{%
\romannumeral0\expandafter\UD@secondoftwo\expandafter{\expandafter{%
\string#1.}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@firstoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether brace-balanced argument starts with a space-token
%%.............................................................................
%% \UD@CheckWhetherLeadingSpace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>}%
\newcommand\UD@CheckWhetherLeadingSpace[1]{%
\romannumeral0\UD@CheckWhetherNull{#1}%
{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
{\expandafter\UD@secondoftwo\string{\UD@CheckWhetherLeadingSpaceB.#1 }{}}%
}%
\newcommand\UD@CheckWhetherLeadingSpaceB{}%
\long\def\UD@CheckWhetherLeadingSpaceB#1 {%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#1{}}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter}\expandafter\expandafter
\expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%% \UD@ExtractFirstArg{ABCDE} yields {A}
%%
%% \UD@ExtractFirstArg{{AB}CDE} yields {AB}
%%.............................................................................
\newcommand\UD@RemoveTillUD@SelDOm{}%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
\newcommand\UD@ExtractFirstArg[1]{%
\romannumeral0%
\UD@ExtractFirstArgLoop{#1\UD@SelDOm}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
{ #1}%
{\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% \DefineReplacementMacro{<replacement-macro>}%
%% {<internal helper-macro>}%
%% {<item to replace>}%
%%
%% defines <replacement-macro> to fetch two arguments,
%% #1 = <replacement for item to replace>
%% #2 = <token sequence with item to replace>
%% , and -- after two expansion-steps to deliver:
%% <token sequence with all instances of <item to replace> replaced
%% by <replacement for item to replace>. >
%%
%% Internally an <internal helper-macro> is needed.
%%
%% (!!! <replacement-macro> does also replace all pairs of matching
%% explicit character tokens of catcode 1/2 by matching braces!!!)
%%-----------------------------------------------------------------------------
\newcommand\DefineReplacementMacro[3]{%
\newcommand#2{}\long\def#2##1#3{}%
\newcommand#1[2]{%
\romannumeral0\UD@ReplaceAllLoop{##2}{##1}{}{#2}{#3}%
}%
}%
\newcommand\UD@ReplaceAllLoop[5]{%
\UD@CheckWhetherNull{#1}{ #3}{%
\UD@CheckWhetherLeadingSpace{#1}{%
\expandafter\UD@ReplaceAllLoop
\expandafter{\UD@removespace#1}{#2}{#3 }{#4}{#5}%
}{%
\UD@CheckWhetherBrace{#1}{%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\expandafter\UD@PassFirstToSecond\expandafter{%
\romannumeral0\expandafter\UD@ReplaceAllLoop
\romannumeral0\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{#2}{}{#4}{#5}%
}{#3}}%
{\expandafter\UD@ReplaceAllLoop\expandafter{\UD@firstoftwo{}#1}{#2}}%
{#4}{#5}%
}{%
\expandafter\UD@CheckWhetherNoReplacement
\romannumeral0\UD@ExtractFirstArgLoop{#1\UD@SelDOm}{#1}{#2}{#3}{#4}{#5}%
}%
}%
}%
}%
\newcommand\UD@CheckWhetherNoReplacement[6]{%
\expandafter\UD@CheckWhetherNull\expandafter{#5#1#6}%
{%
\expandafter\UD@ReplaceAllLoop
\expandafter{\UD@firstoftwo{}#2}{#3}{#4#1}{#5}{#6}%
}{%
\expandafter\UD@ReplaceAllLoop
\expandafter{\UD@firstoftwo{}#2}{#3}{#4#3}{#5}{#6}%
}%
}%
%%=============================================================================
%% \UD@ReplaceAlli -- Replace all "i" in undelimited Argument:
%%
%% \UD@ReplaceAlli{<replacement for i>}{<token sequence with i>}
%% yields <token sequence with all i replaced by replacement for i>
%%
%% <replacement for i> may contain i.
%%
%% (This routine does also replace all pairs of matching explicit
%% character tokens of catcode 1/2 by matching braces!!!)
%%
%% The letter "i" as item to replace is hard-coded.
%% You cannot replace öetters other than I with this macro.
%%.............................................................................
\DefineReplacementMacro{\UD@ReplaceAlli}{\UD@gobbletoi}{i}%
%%
%%=============================================================================
%% \replaceiandreplicate{<term with i>}%
%% {<loop-start-index>}%
%% {<loop-end-index>}%
%%
%% e.g.,
%%
%% \replaceiandreplicate{p_i^{\epsilon_i}}{1}{3}
%%.............................................................................
\newcommand\replaceiandreplicate[3]{%
\romannumeral0\replaceiandreplicateloop{#3}{#2}{#1}{}%
}%
\newcommand\replaceiandreplicateloop[4]{%
\ifnum#1<#2 %
\expandafter\UD@firstoftwo
\else
\expandafter\UD@secondoftwo
\fi
{ #4}{%
\expandafter\expandafter\expandafter\UD@PassFirstToSecond
\expandafter\expandafter\expandafter{%
\UD@ReplaceAlli{#1}{#3}#4%
}{%
\expandafter\replaceiandreplicateloop
\expandafter{\number\numexpr\number#1-1\relax}{#2}{#3}%
}%
}%
}%
\makeatother
\parindent=0ex
\begin{document}
\begin{verbatim}
$\replaceiandreplicate{\ifnum i>1+\fi F_iu_i}{1}{9}$
\end{verbatim}
yields:\bigskip
$\replaceiandreplicate{\ifnum i>1+\fi F_iu_i}{1}{9}$
\begin{verbatim}
$\csname @gobble\expandafter\expandafter
\expandafter \endcsname
\replaceiandreplicate{+F_iu_i}{1}{9}$
\end{verbatim}
yields:\bigskip
$\csname @gobble\expandafter\expandafter
\expandafter \endcsname
\replaceiandreplicate{+F_iu_i}{1}{9}$
\end{document}