用 expl3 分解二次方程

用 expl3 分解二次方程

我的目标是说明分解二次方程的“完全平方”技术。我希望代码能够处理各种系数,包括整数、对有理数的一些支持以及数值。我对语法非常陌生,expl3并尝试调整找到的代码这里这里。但我缺少一些基本的东西。

在此处输入图片描述

在下面的实验代码中,有理数 -3/2 的情况处理不当,分母中有符号。我还想抑制 1x 这样的单位系数。最后,我想将根和替换$(x+1)(x+1)$$(x+1)^2$。也欢迎任何一般的编码技巧!谢谢。

\documentclass[10pt,t]{beamer}
\geometry{paperwidth=160mm,paperheight=96mm}% aspectratio=169: 160mm x 90mm
\usefonttheme{professionalfonts}%
\setbeamertemplate{navigation symbols}{}% nobody likes you
\usepackage{xfp}% math calculations
\usepackage{xparse}

% https://tex.stackexchange.com/questions/480444

\ExplSyntaxOn

% reduce reducible fractions
% https://tex.stackexchange.com/questions/253693
\cs_new:Nn \svend_gcd:nn
  {
    \int_compare:nNnTF {#2} = { 0 } {#1}
      { \svend_gcd:ff {#2} { \int_mod:nn {#1} {#2} } }
  }
\cs_generate_variant:Nn \svend_gcd:nn { ff }
\int_new:N \l__svend_tmp_int
\cs_new:Nn \svend_reduced:nn
 {
    \int_set:Nn \l__svend_tmp_int { \svend_gcd:nn {#1} {#2} }

    \fp_compare:nT 
      { #2 = \l__svend_tmp_int } 
      { \int_eval:n { #1 / \l__svend_tmp_int } }

    \fp_compare:nF 
      { #2 = \l__svend_tmp_int } 
      { { \int_eval:n { #1 / \l__svend_tmp_int } }
        \over
        { \int_eval:n { #2 / \l__svend_tmp_int } }
      }
 }

% Quadratic form
\NewDocumentCommand{\QuadraticForm}{O{x}mmm}
 {
  \ensuremath{
    \str_case:nnF { #2 }
     {
      {1}{}
      {-1}{-}
     }
     {#2}
     #1^{2}
    \str_case:nnF { #3 }
     {
      {0}{}
      {1}{+#1}
      {-1}{-#1}
     }
     { 
      \fp_compare:nT { #3 > 0 } { + } #3#1 
     }
    \fp_compare:nF { #4 = 0 }
     {
      \fp_compare:nT { #4 > 0 } { + }
     }
    #4
  }
}


% Quadratic roots
\cs_new:Nn \sandu_solve:nnnn
   {
    \fp_eval:n { round( ( -(#3) #1 sqrt((#3)^2-4*(#2)*(#4)) )/(2*(#2)), 4) }
   }
\NewDocumentCommand{\QuadraticRoots}{O{x}mmm}
 {
  \ensuremath{
    #1=\sandu_solve:nnnn{+}{#2}{#3}{#4},
    #1=\sandu_solve:nnnn{-}{#2}{#3}{#4}
  }
}

% Leading coefficient
\NewDocumentCommand{\LeadingCoeff}{O{x}mmm}
 {
  \ensuremath{#2}
}

% Linear coefficient
\NewDocumentCommand{\LinearCoeff}{O{x}mmm}
 {
  \ensuremath{#3}
}

% Constant coefficient
\NewDocumentCommand{\ConstantCoeff}{O{x}mmm}
 {
  \ensuremath{#4}
}

% Variable name
\NewDocumentCommand{\VariableName}{O{x}mmm}
 {
  \ensuremath{#1}
}


% Monic form
\NewDocumentCommand{\MonicForm}{O{x}mmm}
 {
  \ensuremath{
     #1^{2}
    \str_case:nnF { #3/#2 }
     {
      {0}{}
      {1}{+#1}
      {-1}{-#1}
     }
     { 
      \fp_compare:nT { #3/#2 > 0 } { + } { \svend_reduced:nn {#3} {#2} } #1 
     }
    \fp_compare:nF { #4 = 0 }
     { 
      \fp_compare:nT { #4/#2 > 0 } { + } { \svend_reduced:nn {#4} {#2} }
     }
  }
}


% Leading coefficient factored out
\NewDocumentCommand{\FactorLeadingCoeff}{O{x}mmm}
 { 
  \ensuremath{
    \fp_compare:nTF { #2 = 1 } { \MonicForm[#1]{#2}{#3}{#4} }{ #2 \left(\MonicForm[#1]{#2}{#3}{#4}\right) }
  }
}

% Product form
\NewDocumentCommand{\ProductForm}{O{x}mmm}
 { 
  \ensuremath{

  \fp_compare:nF { \sandu_solve:nnnn{+}{#2}{#3}{#4} < 0 }
  { \left(#1 \fpeval{-\sandu_solve:nnnn{+}{#2}{#3}{#4}}\right) }

  \fp_compare:nF { \sandu_solve:nnnn{-}{#2}{#3}{#4} < 0 }
  { \left(#1 \fpeval{-\sandu_solve:nnnn{-}{#2}{#3}{#4}}\right) }

  \fp_compare:nF { \sandu_solve:nnnn{+}{#2}{#3}{#4} > 0 }
  { \left(#1+\fpeval{-\sandu_solve:nnnn{+}{#2}{#3}{#4}}\right) }

  \fp_compare:nF { \sandu_solve:nnnn{-}{#2}{#3}{#4} > 0 }
  { \left(#1+\fpeval{-\sandu_solve:nnnn{-}{#2}{#3}{#4}}\right) }

  }
}

% Factored form
\NewDocumentCommand{\FactoredForm}{O{x}mmm}
 { 
  \ensuremath{
    \fp_compare:nTF { #2 = 1 } { \ProductForm[#1]{#2}{#3}{#4} }{ #2 \ProductForm[#1]{#2}{#3}{#4} }
  }
}

\ExplSyntaxOff


\setbeamercovered{transparent=0}% remove transparency of overlays

\begin{document}

\begin{frame}[allowframebreaks]

\frametitle{Factoring Quadratic Equations}

Quadratic equation: $\QuadraticForm{-3}{3}{18}=0 \quad\checkmark$

Quadratic roots: $\QuadraticForm{-3}{3}{18} \to \QuadraticRoots{-3}{3}{18} \quad\checkmark$

Quadratic roots: $\QuadraticForm{1}{-1}{-1} \to \QuadraticRoots{1}{-1}{-1} \to$ order from smaller to larger root

Leading coefficient: $\QuadraticForm{-3}{3}{18} \to \LeadingCoeff{-3}{3}{18} \quad\checkmark$

Monic form: $\QuadraticForm{-3}{3}{18} \to \MonicForm{-3}{3}{18} \to$ remove unit linear coefficient $1x$

Monic form: $\QuadraticForm{2}{-3}{18} \to \MonicForm{2}{-3}{18} \to$ fix the sign in the denominator

Monic form: $\QuadraticForm{2}{3}{18} \to \MonicForm{2}{3}{18} \quad\checkmark$ 

Factor leading coefficient: $\QuadraticForm{-3}{3}{18} \to \FactorLeadingCoeff{-3}{3}{18} \quad\checkmark$

Factored form: $\QuadraticForm{-3}{3}{18} \to \FactoredForm{-3}{3}{18} \quad\checkmark$

Factored form: $\QuadraticForm{1}{2}{1} \to \FactoredForm{1}{2}{1} \to$ repeated roots to be squared


\end{frame}


\end{document}

答案1

下面是一个示例,说明如何sagetex帮助您解决问题,后面是一些解释。首先,代码:

\documentclass{article}
\usepackage{sagetex,amsmath}
\linespread{1.2}
\begin{document}
\noindent\textbf{\Large Factoring Quadratics Equations I}\\
\begin{sagesilent}
f=-3*x^2+3*x+18
L= f.roots()
L.sort()
\end{sagesilent}

\noindent \textbf{Quadratic Equation:} $\sage{f}=0$

\noindent \textbf{Quadratic Roots:} $\sage{f} \rightarrow x=\sage{L[0][0]}, x=\sage{L[1][0]}$

\begin{sagesilent}
g=x^2-x-1
L2= g.roots()
L2.sort()
\end{sagesilent}
\noindent \textbf{Quadratic Roots:} $\sage{g} \rightarrow x=\sage{L2[0][0]} \approx \sage{(L2[0][0]).n(digits=3)}, x=\sage{L2[1][0]} \approx \sage{(L2[1][0]).n(digits=4)}$

\noindent \textbf{Leading Coefficients:} $\sage{f} \rightarrow \sage{f.coefficients()[2][0]}$

\noindent \textbf{Monic Form:} $\sage{f} \rightarrow \sage{f/f.coefficients()[2][0]}$
\begin{sagesilent}
h=2*x^2-3*x+18
L3= h.roots()
L3.sort()
\end{sagesilent}

\noindent \textbf{Monic Form:} $\sage{h} \rightarrow \sage{h/h.coefficients()[2][0]}$
\begin{sagesilent}
i=2*x^2+3*x+18
L3= i.roots()
L3.sort()
\end{sagesilent}

\noindent \textbf{Monic Form:} $\sage{i} \rightarrow \sage{i/i.coefficients()[2][0]}$

\noindent \textbf{Factor Leading Coefficient:} $\sage{f} \rightarrow \sage{f.coefficients()[2][0]}(\sage{f/f.coefficients()[2][0]})$

\noindent \textbf{Factored Form:} $\sage{f} \rightarrow \sage{factor(f)}$

\begin{sagesilent}
j=x^2+2*x+1
\end{sagesilent}
\noindent \textbf{Factored Form:} $\sage{j} \rightarrow \sage{factor(j)}$
\end{document}

Cocalc 中运行的输出: 在此处输入图片描述

说明:信息和计算由 Sage 在块中完成sagesilent。这些信息就像草稿:它不是由 LaTeX 排版的,我们使用适当的sagetex宏获取所需的信息。对于数字数据,\sage{}从草稿中取出并将其插入到 LaTeX 中。因此,例如在LaTeX 代码f=-3*x^2+3*x+18中将多项式定义为后,将得到方程。创建一个 2 元组列表(根及其重数),同时将根从小到大排序。该命令取最小根(Python 将其视为列表中的第零位置),我们想要根(而不是重数),所以。如果我们想要第一个根的重数,我们可以使用来获得它。sagesilent$\sage{f}=0$-3*x^2+3*x+18=0L= f.roots()L.sort()x=\sage{L[0][0]}L[0][0]L[0][1]

您可以通过以下方式更好地了解这一点:Sage 单元服务器在第 1 行输入f=-3*x^2+3*x+18,然后f.roots()在第 2 行输入,然后按 Enter 键。学习 Sage 的文档非常多。关于多项式的 700 多页文档是这里。为了更好地了解 Sage,又不至于沉溺于细节,免费书籍很有帮助。在本指南中,第 131 页有一些用于多项式的基本 Sage 命令。请注意获取多项式系数的命令。如果我转到我的 Sage 单元服务器并输入以下内容

在此处输入图片描述

输出为,[[18, 0], [3, 1], [-3, 2]]它告诉我 18 是 x^0 的系数,3 是 x^1 的系数,-3 是 x^2 的系数。这是因为如果f=-3*x^2+18我们得到[[18, 0], [-3, 2]]。强制打印所有系数f.coefficients(sparse=False)将起作用。如果您转到 LaTeX 代码:\sage{i/i.coefficients()[2][0]i=2*x^2+3*x+18我们将输出[[18, 0], [3, 1], [2, 2]]其中指 i.coefficients()[2]的是 2 元组[2, 2]i.coefficients()[2][0]指的是的前 2(在第零位置),[2,2]因此\sage{i/i.coefficients()[2][0]只需2*x^2+3*x+18除以 2。

在您的评论中,您说"I'd be open to other solutions. Any reason not to use expl?"。首先,通过使用 Sage 的内置功能,您可以更快地解决问题。需要分解多项式(或数字):很容易,因为因子已经定义。如果 Sage 缺少某些内容,定义 Python 函数会有所帮助。其次,Sage 解决方案通常更短,因为 CAS 已经介入以提供帮助,例如处理+-问题。第三,阅读和记住 Python 也更容易。例如,我无法弄清楚您的expl代码中发生了什么。同样,与从头开始编码相比,使用 Sage 进行工作,结果更有可能是正确的——这只是一个选择编写解决方案所需的文档的问题。最后,Sage 随时准备帮助解决更难的问题,例如高阶多项式和积分、微分、矩阵、图论等。作为 CAS,Sage 可以轻松简化平方根。主要缺点是 Sage 不是 LaTeX 的一部分。访问它的最简单方法是使用免费的 Cocalc 帐户。如果您更懂电脑,您可以下载它并让它与您的 LaTeX 发行版进行通信。

相关内容