Wie erstellt man Makros für Vektor-Matrix-Operatoren?

Wie erstellt man Makros für Vektor-Matrix-Operatoren?

Kann jemand Makros für die folgenden Vektoroperationen erstellen? Oder gibt es bereits solche Makros? Zum Beispiel:

1) Example data: \def\a{(5,3,0)}
                 \def\b{(5,1,6)}
                 \def\A{(1,0,1\\0,2,0\\0,0,3)}
2) Vector addition: $\a+\b$ returns (10,4,6)
3) Vector subtraction: $\a-\b$ returns (0,2,-6)
4) Vector matrix multiplication: $\A*\a$ returns (5,6,0)

Dank Davids Code habe ich Folgendes für 1) Vektoraddition, 2) Vektorsubtraktion, 3) Vektormultiplikation und 4) Vektordivision erweitert. Was ich tun werde, ist, den Code für die Listenverarbeitung auf 5) \car und \cdr zu erweitern. Folgendes ist der erste Schritt.

\documentclass{article}

\makeatletter

%main macros
\def\rvecadd#1#2{\edef\tmp{\noexpand\@rvecadd+#1,\relax#2,\relax}\tmp}
\def\rvecsub#1#2{\edef\tmp{\noexpand\@rvecadd-#1,\relax#2,\relax}\tmp}
\def\rvecmul#1#2{\edef\tmp{\noexpand\@rvecadd*#1,\relax#2,\relax}\tmp}
\def\rvecdiv#1#2{\edef\tmp{\noexpand\@rvecadd/#1,\relax#2,\relax}\tmp}
\def\rcar#1{\edef\tmp{\noexpand\@rcar#1,\relax}\tmp}
\def\rcdr#1{\edef\tmp{\noexpand\@rcdr#1,\relax}\tmp}

%recursive macros
\def\@rvecadd#1#2,#3\relax#4,#5\relax{%
\the\numexpr#2#1#4\relax
\ifx\@#3\@\expandafter\@gobble
\else\expandafter\@firstofone
\fi{,\@rvecadd#1#3\relax#5\relax} }

\def\@rcar#1,#2\relax{%
#1\relax
\ifx\@#2\@\expandafter\@gobble
\else\expandafter\@firstofone
\fi}

\def\@rcdr#1,#2\relax{%
#2\relax
\ifx\@#2\@\expandafter\@gobble
\else\expandafter\@firstofone
\fi}


\begin{document}
%Data
\def\a{5,3,0,100,1}
\def\b{5,1,6,1000,1}
\def\A{1,0,1\\0,2,0\\0,0,3}
\def\aT{5\\3\\0}

%Test
$(\a) + (\b) = (\rvecadd\a\b)$\par
$(\a) - (\b) = (\rvecsub\a\b)$\par
$(\a) * (\b) = (\rvecmul\a\b)$\par
$(\a) / (\b) = (\rvecdiv\a\b)$

%car test:
\rcar\a

%cdr test
(\rcdr\a)

\end{document}

Antwort1

Jetzt habe ich keine Zeit mehr für Multiplikationen, aber hier sind die einfachen Vektoradditionen/-subtraktionen.

\documentclass{article}

\def\a{5,3,0}
\def\b{5,1,6}
\def\A{1,0,1\\0,2,0\\0,0,3}
%2) Vector addition: $\a+\b$ returns (10,4,6)
%3) Vector subtraction: $\a-\b$ returns (0,2,-6)
%4) Vector matrix multiplication: $\A*\aT$ returns (5,6,0)

\makeatletter

\def\rvecadd#1#2{\edef\tmp{\noexpand\@rvecadd+#1,\relax#2,\relax}\tmp}
\def\rvecsub#1#2{\edef\tmp{\noexpand\@rvecadd-#1,\relax#2,\relax}\tmp}

\def\@rvecadd#1#2,#3\relax#4,#5\relax{%
\the\numexpr#2#1#4\relax
\ifx\@#3\@\expandafter\@gobble
\else\expandafter\@firstofone
\fi{,\@rvecadd#1#3\relax#5\relax}}

\begin{document}

\def\a{5,3,0}
\def\b{5,1,6}
\def\A{1,0,1\\0,2,0\\0,0,3}
\def\aT{5\\3\\0}


$(\a) + (\b) = (\rvecadd\a\b)$


$(\a) - (\b) = (\rvecsub\a\b)$

\end{document}

Antwort2

Ich habe die Syntax ein wenig geändert und die Klammern weggelassen, die Sie in Ihren Vektoren und Matrizen hatten. Mit dem folgenden Code können Sie Folgendes tun:

\setvector\a{5,3,0}
\setmatrix\A{1,0,1\\0,2,0\\0,0,3}
\begin{equation}
  \usematrix\A \cdot \usevvector\a
  = \matrixtimesvector\result\A\a  \usevvector\result
\end{equation}

\Aum die Matrix und den Vektor \a(vertikal) anzuzeigen , die \resultMultiplikation \Amit zu berechnen \aund \resultals vertikalen Vektor anzuzeigen.

\documentclass{article}
\usepackage{expl3, xparse}
\usepackage{amsmath}
\ExplSyntaxOn
\seq_new:N \l__mypkg_a_seq
\seq_new:N \l__mypkg_b_seq
\seq_new:N \l__mypkg_result_seq
\int_new:N \l__mypkg_entries_int

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Declaring vectors and matrices
%
\cs_new_protected:Npn \mypkg_set_vector:Nnn #1#2#3
  {
    \seq_set_split:Nnn #1 {#2} {#3} % Split into entries.
    \seq_set_map:NNn #1#1 { \fp_to_tl:n {##1} } % Evaluate each entry.
  }
\NewDocumentCommand { \setvector } { m O{,} m }
  {
    \mypkg_set_vector:Nnn \l__mypkg_result_seq {#2} {#3}
    \cs_set_eq:NN #1 \l__mypkg_result_seq
  }
\NewDocumentCommand { \setmatrix } { m O{\\} O{,} m }
  {
    \seq_clear:N \l__mypkg_result_seq
    \int_set_eq:NN \l__mypkg_entries_int \c_minus_one
    \seq_set_split:Nnn \l__mypkg_a_seq {#2} {#4} % Split into lines.
    \seq_map_inline:Nn \l__mypkg_a_seq
      {
        % Split each line |##1| into entries.  For the first line,
        % |\l__mypkg_entries_int| is -1 still; we set it to the
        % number of entries in the first line.  Then check that the line
        % has the right number of entries: if so, put it in the result
        % as a comma-delimited list, otherwise complain loudly and
        % ignore the line.
        %
        \mypkg_set_vector:Nnn \l__mypkg_b_seq {#3} {##1}
        \int_compare:nT { \l__mypkg_entries_int = \c_minus_one }
          {
            \int_set:Nn \l__mypkg_entries_int
              { \seq_count:N \l__mypkg_b_seq }
          }
        \int_compare:nTF
          { \seq_count:N \l__mypkg_b_seq = \l__mypkg_entries_int }
          {
            \seq_put_right:Nx \l__mypkg_result_seq
              { \seq_use:Nnnn \l__mypkg_b_seq { & } { & } { & } }
          }
          {
            \msg_error:nnxxx { mypkg } { mismatched-lines }
              { \token_to_str:N #1 }
              { \int_use:N \l__mypkg_entries_int }
              { \seq_count:N \l__mypkg_b_seq }
          }
      }
    \cs_set_eq:NN #1 \l__mypkg_result_seq
  }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Adding two vectors
%
\tl_new:N \l__mypkg_operation_tl
\NewDocumentCommand { \addvectors } { m m m }
  {
    \tl_set:Nn \l__mypkg_operation_tl { + }
    \mypkg_add_vectors:NN #2#3
    \cs_set_eq:NN #1 \l__mypkg_result_seq
  }
\NewDocumentCommand { \subvectors } { m m m }
  {
    \tl_set:Nn \l__mypkg_operation_tl { - }
    \mypkg_add_vectors:NN #2#3
    \cs_set_eq:NN #1 \l__mypkg_result_seq
  }
\cs_new_protected:Npn \mypkg_add_vectors:NN #1#2
  {
    \int_compare:nNnTF { \seq_count:N #1 } = { \seq_count:N #2 }
      {
        \seq_clear:N \l__mypkg_result_seq
        \seq_mapthread_function:NNN #1#2 \mypkg_add_vectors:nn
      }
      {
        \msg_error:nnxxxx { mypkg } { mismatched-vectors }
          { \token_to_str:N #1 } { \seq_count:N #1 }
          { \token_to_str:N #2 } { \seq_count:N #2 }
      }
  }
\cs_new_protected:Npn \mypkg_add_vectors:nn #1#2
  {
    \seq_put_right:Nx \l__mypkg_result_seq
      { \fp_to_tl:n { #1 \l__mypkg_operation_tl #2 } }
  }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Scalar product of two vectors
%
\NewDocumentCommand { \scalarproduct } { mmm }
  {
    \tl_set:Nx #1 { \mypkg_scalar_product:NN #2 #3 }
  }
\cs_new:Npn \mypkg_scalar_product:NN #1#2
  {
    \fp_to_tl:n
      { \seq_mapthread_function:NNN #1 #2 \mypkg_scalar_product_aux:nn }
  }
\cs_new:Npn \mypkg_scalar_product_aux:nn #1#2 { + #1 * #2 }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Multiplying matrix times vector
%
\NewDocumentCommand { \matrixtimesvector } { mmm }
  {
    \seq_clear:N \l__mypkg_result_seq
    \seq_map_inline:Nn #2
      {
        \seq_set_split:Nnn \l__mypkg_a_seq { & } {##1}
        \seq_put_right:Nx \l__mypkg_result_seq
          { \mypkg_scalar_product:NN \l__mypkg_a_seq #3 }
      }
    \cs_set_eq:NN #1 \l__mypkg_result_seq
  }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Displaying vectors and matrices
%
\NewDocumentCommand { \usehvector } { m }
  {
    \mode_if_math:F { \msg_warning:nn { mypkg } { text-mode } }
    \ensuremath
      {
        \begin{pmatrix}
          \seq_use:Nnnn #1 { , } { , } { , }
        \end{pmatrix}
      }
  }
\NewDocumentCommand { \usevvector } { m }
  {
    \mode_if_math:F { \msg_warning:nn { mypkg } { text-mode } }
    \ensuremath
      {
        \begin{pmatrix}
          \seq_use:Nnnn #1 { \\ } { \\ } { \\ }
        \end{pmatrix}
      }
  }
\NewDocumentCommand { \usematrix } { m }
  {
    \mode_if_math:F { \msg_warning:nn { mypkg } { text-mode } }
    \ensuremath
      {
        \begin{pmatrix}
          \seq_use:Nnnn #1 { \\ } { \\ } { \\ }
        \end{pmatrix}
      }
  }

\msg_new:nnn { mypkg } { mismatched-lines }
  { The~lines~of~#1~should~have~#2~entries,~but~this~one~has~#3. }
\msg_new:nnn { mypkg } { mismatched-vectors }
  { The~vector~#1~has~#2~entries,~but~the~vector~#3~has~#4~entries. }
\msg_new:nnn { mypkg } { text-mode }
  { The~\iow_char:N\\use...~commands~should~only~be~used~in~math~mode. }

\ExplSyntaxOff
\begin{document}
\setvector\a{5,3,0}
\setvector\b{5,1,6}
\setmatrix\A{1,0,1\\0,2,0\\0,0,3}

Vector addition: $\usehvector\a+\usehvector\b$ returns
$\addvectors\result\a\b \usehvector\result$.  Subtraction:
\begin{equation}
  \usevvector\a - \usevvector\b
  = \subvectors\result\a\b \usevvector\result .
\end{equation}

Scalar product:
\begin{equation}
  \usehvector\a \cdot \usevvector\b
  = \scalarproduct\result\a\b \result
\end{equation}
Matrix-vector product
\begin{equation}
  \usematrix\A \cdot \usevvector\a
  = \matrixtimesvector\result\A\a  \usevvector\result
\end{equation}

% 2) Vector addition: $\a+\b$ returns (10,4,6)
% 3) Vector subtraction: $\a-\b$ returns (0,2,-6)
% 4) Vector matrix multiplication: $\A*\a$ returns (5,6,0)
\end{document}

verwandte Informationen