LaTeX-Schleifen in \newcommand

LaTeX-Schleifen in \newcommand

Ich verwende LaTeX jetzt seit etwa einem Jahr und versuche jedes Mal, wenn ich eine Arbeit schreibe, mein Wissen zu verbessern. Daher habe ich in letzter Zeit eigene Befehle erstellt, um Zeit zu sparen. Mich interessiert, ob es möglich ist, in LaTeX „for-Schleifen“ zu verwenden, um \newcommandFolgendes zu erstellen:

\newcommand{idmatrix}[1]

wobei mein Parameter beispielsweise die Größe ist, nund dann wird eine nx- nIdentitätsmatrix gedruckt. Dies wäre nützlich für Gleichungen, bei denen ich die Matrixberechnungen anzeigen möchte, aber nicht \bmatrixjedes Mal die banale Arbeit erledigen muss, usw. zu verwenden und eine 3x3- oder 2x2-Matrix zu erstellen.

Antwort1

Hier ist eine Implementierung mit LaTeX3-Funktionen. Wenn\idmatrix{N}zum ersten Mal aufgerufen wird, wird eine neue Token-Listenvariable eingerichtet, die den Code zur Erstellung der Matrix enthält, sodass sie wiederverwendet werden kann, ohne jedes Mal neu erstellt werden zu müssen.

Daher \idmatrix{2}wird die Token-Listenvariable erstellt \g_julian_idmatrix_1_tlund verwendet; nachfolgende Aufrufe \idmatrix{2}verwenden einfach die Variable.

\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}

Bildbeschreibung hier eingeben

Antwort2

Um Ihre Frage zu beantworten, ist lediglich eine geringfügige Modifikation des Gesagten erforderlich.Hier:

\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}

Seien Sie vorsichtig, da mir aufgefallen ist, dass die bmatrix Umgebung keine Matrizen unterstützt, die größer als 10x moder m x 10where sind 0<m<11. Wenn Sie größere Matrizen benötigen, können Sie stattdessen arraywie folgt verwenden:

\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]
}

verwandte Informationen