My goal is to illustrate the "completing the square" technique for factorizing quadratic equations. I'd like code that could handle a wide range of coefficients, including integers, some support for rationals, and numeric values. I'm very new to the expl3 syntax and have attempted to adapt code found here and here. But I'm missing some basic things.
In the experimental code below, the case of the rational -3/2 is not handled properly, with the sign in the denominator. I'd also like to suppress unit coefficients like 1x. Ultimately, I would like to order the roots and to replace $(x+1)(x+1)$ with $(x+1)^2$. Any general coding tip welcome too! Thanks.
\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}



explthen the sagetex package, which gives you access to a computer algebra system, Sage, similar to Mathematica but free can handle everything without you having to reinvent the wheel. It even gives you access to Python programming. – DJP Mar 27 '23 at 03:28expl3, I'd be open to other solutions. Any reason not to useexpl? Thanks! – PatrickT Mar 27 '23 at 05:01expl3. I just happen to find Lua's ways of doing math intuitive and natural. – Mico Mar 27 '23 at 05:06