0

I have another question in regards to using expl3. I am trying to generate a random parabola and then print a rewritten form of that generated equation. I have a \NewDocumentCommand named \parabola. I have a few global variables declared that correspond to different coefficients in standard form of a quadratic. Namely, for the standard form of a quadratic given by: (A/D)(x-h)^2+k. Where A is and integer in [-2,2]\{0}, D is an integer in [1,5], and h and k are an integers in [-2,2]. On top of this, I'd like a section that takes the standard form I use for plotting and writes it in expanded form (i.e. ax^2+bx+c). This part I am certainly lost in accomplishing. My preamble is given and document are given below:

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=0.75in]{geometry}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{amsmath,amssymb,enumitem}
\usepackage[first=-20, last=20]{lcg}
\usepackage{tikz}
\usepackage{tkz-euclide}
\usepackage{calculator}
\usepackage{calculus}
\usepackage{ifthen}
\usepackage{xfp}
\usepackage{pgffor}
\usepackage{pgfplots}

\newcommand{\randi}{\rand\arabic{rand}}

\ExplSyntaxOn\newcommand{\intR}[2]{\chgrand[first=#1, last=#2] \randi}\ExplSyntaxOff

\ExplSyntaxOn\newcommand{\firstpower}{\chgrand[first=2, last=5] \randi}\ExplSyntaxOff

\ExplSyntaxOn\def\isneg#1{ \expandafter\ifnum#1>0 ~+\else ~-\fi }\ExplSyntaxOff

\ExplSyntaxOn\def\isopp#1{ \expandafter\ifnum#1>0 ~-\else ~+\fi }\ExplSyntaxOff

\ExplSyntaxOn\def\isone#1{ \expandafter\ifnum#1=1 ~1\else ~2\fi }\ExplSyntaxOff

\newcommand{\addsub}{\pgfmathrandomitem{\choice}{choices1}\choice} \pgfmathdeclarerandomlist{choices1}{{+}{-}}

\newcommand{\subnone}{\pgfmathrandomitem{\choice}{choices3}\choice} \pgfmathdeclarerandomlist{choices3}{{}{-}}

\pgfplotsset{ every non boxed x axis/.append style={x axis line style=-}, every non boxed y axis/.append style={y axis line style=-}}

\NewDocumentCommand{\parabola}{}{ \int_gset:Nn \g_point_num_int { \int_rand:nn { -2 } { 2 } } \int_gset:Nn \g_point_denom_int { \int_rand:nn { 1 } { 5 } } \int_gset:Nn \g_point_xv_int { \int_rand:nn { -2 } { 2 } } \int_gset:Nn \g_point_yv_int { \int_rand:nn { -2 } { 2 } } \begin{tikzpicture} \begin{axis}[ width=0.7\textwidth, height=0.7\textwidth, grid=major, xmin=-5, xmax=5, ymin=-5, ymax=5, axis~lines=center % axis lines = left ] \addplot[smooth, red, thick] {(\g_point_num_int / \g_point_denom_int)*(x-\g_point_xv_int)^2+\g_point_yv_int}; \end{axis} \end{tikzpicture} } \int_new:N \l_val_An_int \int_new:N \l_val_Bn_int \int_new:N \l_val_Cn_int \int_new:N \l_val_Ad_int \int_new:N \l_val_Bd_int \int_new:N \l_val_Cd_int \NewDocumentCommand{\paraexpand}{}{ % Writing expression for the A coefficient \MULTIPLY{ \int_gset:N \g_point_num_int }{ 1 }{\tempNum}~ \MULTIPLY{ \int_gset:N \g_point_denom_int }{ 1 }{\tempDenom}~ \FRACTIONSIMPLIFY{ \tempNum }{ \tempDenom }{\An}{\Ad} \ABSVALUE{ \An }\absAn~ \int_if_odd:nTF \isone{\Ad} { \int_if_odd:nTF \isone{\absAn} {} {\int_set:Nn \l_val_A_int {\absAn} } } { \FRACTIONSIMPLIFY{\absAn}{\Ab}{}{} }

% Writing expression for numerator of B coefficient \MULTIPLY{ \int_gset:N \g_point_xv_int }{ 2 }{\tempB}~ \MULTIPLY{ \tempB }{ \tempNum }{\solBn}~ \FRACTIONSIMPLIFY{ \solBn }{ \tempDenom }{\Bn}{\Bd}~ \ABSVALUE{ \Bn }\absBn~

% Writing expression for numerator of C coefficient \SQUARE{ \g_point_xv_int }{ \hsq }~ \MULTIPLY{ \tempNum }{ \hsq }{\tempCl}~ \MULTIPLY{ \tempDenom }{ \int_gset:N \g_point_yv_int }{\tempCr}~ \ADD{ \tempCl }{ \tempCr }{\solCn}~ \FRACTIONSIMPLIFY{ \solCn }{ \tempDenom }{\Cn}{\Cd}~ \ABSVALUE{ \Cn }\absCn~

\if_odd:nTF \isone{} $ \solA x^2 \isopp{\solB} \absB x \isneg{\solC} \absC $ }

\ExplSyntaxOff

\begin{document} \newpage \section*{Problem 7} \begin{center} \parabola \end{center} \paraexpand \end{document}

There is a lot of unnecessary lines in there as it's part of a larger document, and I can't be 100% certain which parts in there are required for my section. I cut out most of the document so if it looks like I'm missing something please comment and tell me. Again, I'm trying to generate a random quadric equation in standard form, given constraints, plot that equation, then list the expanded form of the equation below the plot.

David G.
  • 205

2 Answers2

1

If you're not insistent on expl3 then this is the sort of problem that the sagetex package makes easy. Consider the following code:

\documentclass{article}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
A = 0 
while A == 0:
    A = randint(-2,3)
D =  randint(-1,5)
h = randint(-2,2)
k = randint(-2,2)

f = (A/D)*(x-h)^2+k parab = plot(f,-4,4,color='red') g = expand(f) \end{sagesilent} If $A=\sage{A}$, $D=\sage{D}$, $h=\sage{h}$, and $k=\sage{k}$ then the function $f(x)=\frac{A}{D}(x-h)^2+k$ can be written as $f(x)= \frac{\sage{A}}{\sage{D}}(x-(\sage{h}))^2+(\sage{k})$ or $f(x)=\sage{f}$. Its graph is a parabola: \begin{center} \sageplot[width=3.5in]{parab} \end{center} The standard form of the parabola is $\sage{g}$. \end{document}

The output in Cocalc is: enter image description here

The code (Python) will be easier to read than expl3 and you can see there isn't much of it. I've given a plot using SAGE but you can force the output through to tikz/pgfplots. There are numerous examples on this website to show how. My answers here and here being just two of many examples. The sagetex package uses a computer algebra system to work its magic so expanding from vertex form to standard form is accomplished by g = expand(f). The documentation for sagetex is here on CTAN. The CAS is SAGE, its website is here. It doesn't come with LaTeX so you would need to install it on your computer. As that can be problematic depending on your platform, a free Cocalc account is the best way to get started. Then you don't need SAGE on your computer because you get access through the cloud.

DJP
  • 12,451
  • I use Overleaf, you wouldn't happen to know how to get sagetex to work on there, would you? It's not a package it seems to be automatically found by Overleaf. – David G. Nov 12 '20 at 18:01
  • I don't use Overleaf. I did a search of their website and can't find any mention of sagetex. I suspect they don't support it but you should try the Contact Us page and check to be sure. – DJP Nov 12 '20 at 22:16
0

If you want to know more about LaTeX3, you can refer to the tutorial that I wrote.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{expl3}

\ExplSyntaxOn

% https://tex.stackexchange.com/questions/253693/reducing-fractions-automatically-using-latex-3 \cs_set:Npn \svend_gcd:nn #1#2 { \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_set:Npn \svend_reduced:nnNN #1#2#3#4 { \int_set:Nn \l__svend_tmp_int { \svend_gcd:nn {#1} {#2} } \int_set:Nn #3 { \int_eval:n { #1 / \l__svend_tmp_int } } \int_set:Nn #4 { \int_eval:n { #2 / \l__svend_tmp_int } } }

\int_new:N \g_pb_a_int \int_new:N \g_pb_d_int \int_new:N \g_pb_h_int \int_new:N \g_pb_k_int

\newcommand{\newparabola}{ \int_gset:Nn \g_pb_a_int {(2 * \int_rand:nn {0}{1} - 1) * \int_rand:nn {1}{2}} \int_gset:Nn \g_pb_d_int {\int_rand:nn {1}{5}} \int_gset:Nn \g_pb_h_int {\int_rand:nn {-2}{2}} \int_gset:Nn \g_pb_k_int {\int_rand:nn {-2}{2}} }

\cs_set:Npn \doc_int_safe_use:N #1 { \int_compare:nNnT {#1} < {0} { \int_use:N #1 } \int_compare:nNnT {#1} > {0} { + \int_use:N #1 } }

\int_new:N \l_tmpc_int \int_new:N \l_tmpd_int \int_new:N \l_tmpe_int

\cs_set:Npn \doc_frac_safe_output:nnnn #1#2#3#4 { % extract sign \int_set:Nn \l_tmpe_int {(#1) * (#2)} \int_set:Nn \l_tmpa_int {\int_abs:n {#1}} \int_set:Nn \l_tmpb_int {\int_abs:n {#2}}

\svend_reduced:nnNN {\l_tmpa_int} {\l_tmpb_int} \l_tmpc_int \l_tmpd_int

\str_case:nn {#3} {
    {f} {
        \int_compare:nNnT {\l_tmpe_int} &lt; {0} {-}
        \int_compare:nNnT {\l_tmpe_int} &gt; {0} {+}
    }
    {n} {
        \int_compare:nNnT {\l_tmpe_int} &lt; {0} {-}
    }
}

\int_compare:nNnT {\l_tmpc_int} = {0} {
    \int_set:Nn \l_tmpd_int {1}
}

\int_compare:nNnTF {\l_tmpd_int} = {1} {
    \str_case:nn {#4} {
        {a} {
            \int_use:N \l_tmpc_int
        }
        {z} {
            \int_compare:nNnF {\l_tmpc_int} = {0} {
                \int_use:N \l_tmpc_int
            }
        }
        {n} {
            \int_compare:nNnF {\l_tmpc_int} = {1} {
                \int_use:N \l_tmpc_int
            }
        }
    }

} {
    \frac{\int_use:N \l_tmpc_int}{\int_use:N \l_tmpd_int}
}

}

% original parabola \newcommand{\parabolao}{ \int_compare:nNnTF {\g_pb_h_int} = {0} { $ \doc_frac_safe_output:nnnn {\g_pb_a_int} {\g_pb_d_int} {n} {n} x^2 \doc_int_safe_use:N \g_pb_k_int $

} {
    $
      \doc_frac_safe_output:nnnn {\g_pb_a_int} {\g_pb_d_int} {n} {n}
        (x \doc_int_safe_use:N \g_pb_h_int )^2 \doc_int_safe_use:N \g_pb_k_int
    $
}

}

% expanded parabola \newcommand{\parabolae}{ \int_compare:nNnTF {\g_pb_h_int} = {0} { $ \doc_frac_safe_output:nnnn {\g_pb_a_int} {\g_pb_d_int} {n} {n} x^2 \exp_args:Nx \doc_frac_safe_output:nnnn {\int_eval:n { \g_pb_h_int * \g_pb_h_int * \g_pb_a_int + \g_pb_d_int * \g_pb_k_int} } {\g_pb_d_int} {f} {a} $ } { $ \doc_frac_safe_output:nnnn {\g_pb_a_int} {\g_pb_d_int} {n} {n} x^2 \exp_args:Nx \doc_frac_safe_output:nnnn {\int_eval:n {2 * \g_pb_h_int * \g_pb_a_int}} {\g_pb_d_int} {f} {n} x \exp_args:Nx \doc_frac_safe_output:nnnn {\int_eval:n { \g_pb_h_int * \g_pb_h_int * \g_pb_a_int + \g_pb_d_int * \g_pb_k_int} } {\g_pb_d_int} {f} {z} $ }

}

% plot parabola \newcommand{\parabolap}{ \begin{tikzpicture} \begin{axis}[ width=0.7\textwidth, height=0.7\textwidth, grid=major, xmin=-5, xmax=5, ymin=-5, ymax=5, axis~lines=center ] \addplot[smooth, red, thick] {(\g_pb_a_int / \g_pb_d_int)*(x-\g_pb_h_int)^2+x-\g_pb_k_int}; \end{axis} \end{tikzpicture} }

\ExplSyntaxOff

\begin{document}

\newparabola \par\parabolao \par\parabolae \begin{center} \parabolap \end{center}

\end{document}

Alan Xiang
  • 5,227