![用 expl3 分解二次方程](https://linux22.com/image/462864/%E7%94%A8%20expl3%20%E5%88%86%E8%A7%A3%E4%BA%8C%E6%AC%A1%E6%96%B9%E7%A8%8B.png)
我的目标是说明分解二次方程的“完全平方”技术。我希望代码能够处理各种系数,包括整数、对有理数的一些支持以及数值。我对语法非常陌生,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}
说明:信息和计算由 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=0
L= 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 发行版进行通信。