需要定义一个列表并将其传递给函数

需要定义一个列表并将其传递给函数

我需要将一个定义为 clist 的向量传递给一个函数,该函数将其解析为多个后续计算的组件。如果将向量 clist 作为参数直接传递给解析器,解析器似乎可以完美运行,但当将其定义为命令(例如)时则不行\vectora

从长远来看,我想在中进行向量计算,LaTeX3但首先,我需要一种将向量定义为命令的方法,其组件表示为 clist。我设想了类似的东西,\DefineVector[b]{1,2,3}其中[b]是具有默认值的可选标签a{1,2,3}是包含向量数值组件的 clist。标签可以简单到一个字母,也可以是类似的东西vectorb。得到的向量,例如,在传递给解析器时\vectora,将扩展为例如{1,2,3}。解析器将是一个编程层函数,用户实际上不会与之交互,但会用于执行实际向量计算(如幅度、点积或交叉积)的其他函数。解析器将获取向量分量,例如,并将{1,2,3}它们逐一分配给变量,如vectoraxvectorayvectoraz,然后随后用于浮点计算。在这个例子中,\vectorax将扩展为1\vectoray将扩展为2,并将\vectoraz扩展为3。所以如果我要定义一个新函数来计算,比如说,交叉积,我会解析两个向量,vectoravectorb,并最终得到两组组件,我可以用它们来计算交叉积。我遇到的问题是创建一个正确传递给解析器的向量。

在下面的代码中,这是我花了至少两三个小时修改的结果,\ParseVector当我传递带有向量组件的 clist 时,命令可以工作,但当我传递我认为是作为另一个命令的一部分定义的 clist 时,命令不起作用。这是我需要解决的直接问题,而且我显然遗漏了一些重要概念。我在做这件事的同时,也试图遵守LaTeX3编码标准。

\documentclass[10pt]{article}
\usepackage{expl3}
\usepackage{xparse}

\ExplSyntaxOn
\cs_new_protected:Nn \joe_parsevector:n {%
  % Create sets temporary clist to #1
  \clist_set:Nn \l_tmpa_clist { #1 }
  % Applies { ... } to each element in the temporary clist.
  %\clist_map_inline:Nn \l_tmpa_clist { [##1] }
  \begin{enumerate}
    \clist_map_inline:Nn \l_tmpa_clist { \item ##1 }
  \end{enumerate}
}%
\NewDocumentCommand{\ParseVector}{ m }{%
  \joe_parsevector:n { #1 }
}%

\NewDocumentCommand{\DefineVector}{ m m }{%
  [#1][#2]
  %\exp_args:Nc \newcommand{#1}[1]{#2}
  \cs_new:cpn {#1} ##1 { #2 }
}%
\ExplSyntaxOff

\begin{document}
Hello.

Parsing the vector \verb!{5,-3,4}! gives \ParseVector{5,-3,4}

\DefineVector{vectora}{3,-5,7}

\vectora

\end{document}

答案1

如果我理解正确的话,您想用符号名称存储向量并使用它们执行操作。

我将展示如何定义存储函数(在序列中,而不是在列表中)和一些运算:幅度、标量积、向量(交叉)积。

符号名称可以是任意字母和数字的序列。

前两个是可扩展的,最后一个则不可扩展,因为我们需要存储结果。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\DefineVector}{O{a}m}
 {
  \joe_vector_define:nn { #1 } { #2 }
 }
\NewExpandableDocumentCommand{\PrintVector}{m}
 {
  (\seq_use:cn { l_joe_vector_#1_seq } { , })
 }
\NewExpandableDocumentCommand{\VectorMagnitude}{O{15}m}
 {
  \joe_vector_magnitude:nn { #1 } { #2 }
 }
\NewExpandableDocumentCommand{\ScalarProduct}{O{15}mm}
 {
  \joe_vector_scalarproduct:nnn { #1 } { #2 } { #3 }
 }
\NewDocumentCommand{\VectorProduct}{mmm}
 {% #1 = first vector, #2 = second vector, #3 = result
  \joe_vector_vectorproduct:nnn { #1 } { #2 } { #3 }
 }

\cs_new_protected:Nn \joe_vector_define:nn
 {
  \seq_clear_new:c { l_joe_vector_#1_seq }
  \seq_set_from_clist:cn { l_joe_vector_#1_seq } { #2 }
 }

\cs_new:Nn \joe_vector_magnitude:nn
 {
  \fp_eval:n
   {
    round
     (
      sqrt( \seq_map_function:cN { l_joe_vector_#2_seq } \__joe_vector_square:n )
      ,
      #1
     )
   }
 }
\cs_new:Nn \__joe_vector_square:n { + (#1)^2 }

\cs_new:Nn \joe_vector_scalarproduct:nnn
 {
  \fp_eval:n
   {
    round
     (
      \seq_mapthread_function:ccN { l_joe_vector_#2_seq } { l_joe_vector_#3_seq } \__joe_vector_product:nn
      ,
      #1
     )
   }
 }
\cs_new:Nn \__joe_vector_product:nn
 {
  +(#1)*(#2)
 }

\cs_new_protected:Nn \joe_vector_vectorproduct:nnn
 {
  \seq_clear_new:c { l_joe_vector_#3_seq }
  \seq_put_right:cx { l_joe_vector_#3_seq }
   {
    \fp_eval:n
     {
      (\seq_item:cn { l_joe_vector_#1_seq } { 2 }) * (\seq_item:cn { l_joe_vector_#2_seq } { 3 })
      -
      (\seq_item:cn { l_joe_vector_#1_seq } { 3 }) * (\seq_item:cn { l_joe_vector_#2_seq } { 2 })
     }
   }
  \seq_put_right:cx { l_joe_vector_#3_seq }
   {
    \fp_eval:n
     {
      (\seq_item:cn { l_joe_vector_#1_seq } { 3 }) * (\seq_item:cn { l_joe_vector_#2_seq } { 1 })
      -
      (\seq_item:cn { l_joe_vector_#1_seq } { 1 }) * (\seq_item:cn { l_joe_vector_#2_seq } { 3 })
     }
   }
  \seq_put_right:cx { l_joe_vector_#3_seq }
   {
    \fp_eval:n
     {
      (\seq_item:cn { l_joe_vector_#1_seq } { 1 }) * (\seq_item:cn { l_joe_vector_#2_seq } { 2 })
      -
      (\seq_item:cn { l_joe_vector_#1_seq } { 2 }) * (\seq_item:cn { l_joe_vector_#2_seq } { 1 })
     }
   }
 }
\ExplSyntaxOff

\begin{document}

\DefineVector[a]{0,-4,0}
\DefineVector[b]{1,1,1}
\DefineVector[x4]{1,2,3,4}
\DefineVector[y4]{-1,1,0,2}

$\VectorMagnitude{a}$
$\VectorMagnitude{b}$
$\VectorMagnitude[2]{b}$

$\ScalarProduct{a}{b}$

$\ScalarProduct{x4}{y4}$

\VectorProduct{a}{b}{c}
$\PrintVector{c}$

\end{document}

在此处输入图片描述

叉积的实现比较困难,因为它实际上并不是向量运算。

相关内容