\newcommand 内の LaTeX ループ

\newcommand 内の LaTeX ループ

私は約 1 年間 LaTeX を使用していますが、論文を書くたびに知識を深めようと努めており、最近では時間を節約するために独自のコマンドを作成しています。LaTeX で「for ループ」を使用して、\newcommand次のように作成できるかどうか興味があります。

\newcommand{idmatrix}[1]

ここで、パラメータはサイズで、 x単位行列nを出力します。これは、行列計算を表示したいが、毎回 などを使用して 3x3 または 2x2 行列を作成するという日常的な作業を行う必要がない方程式に役立ちます。nn\bmatrix

答え1

これはLaTeX3の機能を使った実装です。\idmatrix{}初めて呼び出されると、マトリックスを生成するためのコードを含む新しいトークン リスト変数が設定され、毎回構築することなく再利用できるようになります。

したがって、\idmatrix{2}はトークン リスト変数を構築して\g_julian_idmatrix_1_tlそれを使用します。 の後続の の呼び出しでは、\idmatrix{2}単にその変数が使用されます。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\idmatrix}{ m }
 {
  \justin_idmatrix:n { #1 }
 }

\cs_new_protected:Npn \justin_idmatrix:n #1
 {
  \tl_if_exist:cF { g_justin_idmatrix_#1_tl }
   {
    \justin_make_idmatrix:n { #1 }
   }
  \tl_use:c { g_justin_idmatrix_#1_tl }
 }

\cs_new_protected:Npn \justin_make_idmatrix:n #1
 {
  \tl_new:c { g_justin_idmatrix_#1_tl }
  \tl_gput_right:cn { g_justin_idmatrix_#1_tl }
   {
    \left[ % or the delimiter you like best
    % there's a column more for accommodating the empty value after the last 0& (or 1&)
    \begin{array}{ @{} *{#1}{c} @{} c @{} }
   }
  \int_step_inline:nnnn { 1 } { 1 } { #1 }
   {
    % At step k add k-1 zeroes
    \prg_replicate:nn { ##1 - 1 }
     {
      \tl_gput_right:cn { g_justin_idmatrix_#1_tl } { 0 & }
     }
    % Add a 1
    \tl_gput_right:cn { g_justin_idmatrix_#1_tl } { 1 & }
    % Add n - k zeroes
    \prg_replicate:nn { #1 - ##1 }
     {
      \tl_gput_right:cn { g_justin_idmatrix_#1_tl } { 0 & }
     }
    % End the line
    \tl_gput_right:cn { g_justin_idmatrix_#1_tl } { \\ }
   }
  \tl_gput_right:cn { g_justin_idmatrix_#1_tl }
   {
    \end{array}
    \right] % or the delimiter you like best
   }
 }

\ExplSyntaxOff

\begin{document}
\[
\idmatrix{1}\quad
\idmatrix{2}\quad
\idmatrix{3}\quad
\idmatrix{4}
\]
\[
\idmatrix{12}
\]
\end{document}

ここに画像の説明を入力してください

答え2

あなたの質問に答えるには、言ったことを少し修正するだけで十分ですここ:

\documentclass{article}

\usepackage{amsmath,amssymb,mathtools}
\usepackage{ifthen}

\newcommand{\forLoop}[5][1]
{%
\setcounter{#4}{#2}%
\ifthenelse{ \value{#4} < #3 }%
{%
#5%
\addtocounter{#4}{#1}%
\forLoop[#1]{\value{#4}}{#3}{#4}{#5}%
}%
% Else
{%
\ifthenelse{\value{#4} = #3}%
    {%
    #5%
    }%
% Else
    {}%
}%
}

\newcounter{identRow}
\newcounter{identCol}
\newcommand{\idmatrixn}[1]
{
\begin{bmatrix}
\forLoop{1}{#1}{identRow}
    {
    \forLoop{1}{#1}{identCol}
        {
        \ifthenelse{\equal{\value{identRow}}{\value{identCol}}}{1}{0}
        \ifthenelse{\equal{\value{identCol}}{#1}}{}{&}
        }
    \\
    }
\end{bmatrix}
}

\begin{document}
\idmatrixn{10}
\end{document}

bmatrix 環境では より大きい行列 10x mm x 10の行列をサポートしていないことに気づいたので注意してください 。 より大きな行列が必要な場合は、代わりに次のように0<m<11使用できます。array

\newcounter{identRow}
\newcounter{identCol}
\newcommand{\idmatrixn}[1]
{
\left[\begin{array}{*{#1}c}
\forLoop{1}{#1}{identRow}
    {
    \forLoop{1}{#1}{identCol}
        {
        \ifthenelse{\equal{\value{identRow}}{\value{identCol}}}{1}{0}
        \ifthenelse{\equal{\value{identCol}}{#1}}{}{&}
        }
    \\
    }
\end{array}\right]
}

関連情報