¿Cómo crear macros para operadores de matrices vectoriales?

¿Cómo crear macros para operadores de matrices vectoriales?

¿Alguien puede crear macros para realizar las siguientes operaciones vectoriales? ¿O ya existen tales macros? Por ejemplo,

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)

Gracias al código de David, amplié lo siguiente para 1) suma de vectores, 2) resta de vectores, 3) multiplicación de vectores, 4) división de vectores. Lo que voy a hacer es expandir el código a 5) \car y \cdr para el procesamiento de la lista. El siguiente es el primer paso.

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

Respuesta1

Ahora no hay tiempo para hacer multiplicaciones, pero aquí son las sumas y restas de vectores más fáciles.

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

Respuesta2

Cambié un poco la sintaxis, omitiendo los paréntesis que tenías en tus vectores y matrices. Con el siguiente código, puedes hacer

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

para mostrar la matriz \A, el vector \a(verticalmente), calcule el \resultde multiplicar \Apor \ay muestre el \resultcomo un vector vertical.

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

información relacionada