Ask Your Question
1

how to write an expression in latex without it being transformed by sage/sagetex

asked 2022-07-19 20:53:44 +0200

ryss gravatar image

For my lesson that I am trying to write in latex/sagetex, I need to write formulas without them being transformed by sage.

Here's an example :

sage: f(x) = -2*x^2+x+3
....: g(x) = -2*(x-1/4)^2+25/8
....: g(x)
-1/8*(4*x - 1)^2 + 25/8
sage:

but I want to keep the form -2*(x-1/4)^2+25/8 to write it in latex.

I tried hold and with hold: and also some code with .mul( or .add( but I have a problem with the power.

My purpose is to do random exercises around quadratic equations, and I started writing this :

from random import sample
def signe():
    signe = sample([Integer(i) for i in range(-1, 2, 1) if i != 0],1)
    return(signe[0])

def calcul(amax, bmax, cmax):
    a = randint(1,amax)*signe()
    b = randint(0,bmax)*signe()
    c = randint(0,cmax)*signe()
    f(x) = a*x^2+b*x+c
    alpha = -b/2/a
    beta = f(x=alpha)
    fcanonique(x) = a*(x-alpha)^2+beta
    Delta = b**2-4*a*c
    output = r"Soit $f$ le trinôme défini sur $\R$ par ~${}=0$.".format(latex(f(x)))
    output += r"\medbreak"
    output += r"\begin{enumerate}"
    output += r"\item Déterminer une forme canonique de $f$."
    output += r"\item Résoudre dans $\R$ l'équation $f(x)=0$ par la méthode de votre choix."
    output += r"\item $f$ est-elle factorisable ? Si oui, déterminer en une forme factorisée."
    output += r"\item Résoudre dans $\R$ l'équation $f(x)={}$.".format(c)
    output += r"\item Résoudre dans $\R$ l'équation $f(x)={}$.".format(beta)
    output += r"\end{enumerate}"
    output += r"\medbreak\uline{Réponses} :\medbreak"
    output += r"\begin{enumerate}"
    output +=r"\item On a $f(x)={}$".format(latex(fcanonique(x)))
    if Delta < 0:
        output += r"\item On reconnaît une équation du second degré de discriminant $\Delta={}<0$, et donc cette équation n'a pas de solution réelle :".format(latex(Delta))
        output += "\\bigbreak{}"
        output += r"Ce trinôme admet une forme canonique : "
    elif Delta == 0:
        output += r"\item On reconnaît une équation du second degré de discriminant $\Delta={}$, et donc cette équation admet une unique solution $x_0={}$".format(latex(Delta), latex(alpha))
    else:
        x1 = simplify((-b-Delta^(1/2))/(2*a))
        x2 = simplify((-b+Delta^(1/2))/(2*a))
        ffactorisee(x) = a*(x-x1)*(x-x2)
        output += r"\item On reconnaît une équation du second degré de discriminant $\Delta={}>0$, et donc cette équation admet deux solutions réelles $x_1$ et $x_2$ avec : \quad $\displaystyle x_1={}$ \quad et \quad $\displaystyle x_2={}$.".format(latex(Delta), latex(x1), latex(x2))
        output += "\\bigbreak{}"
    output += r"\end{enumerate}"
    return(output)

and for example, calcul(5, 5, 5) return :

"Soit $f$ le trinôme défini sur $\\R$ par ~$-x^{2} + 4 \\, x - 2=0$.\\medbreak\\begin{enumerate}\\item Déterminer une forme canonique de $f$.\\item Résoudre dans $\\R$ l'équation $f(x)=0$ par la méthode de votre choix.\\item $f$ est-elle factorisable ? Si oui, déterminer en une forme factorisée.\\item Résoudre dans $\\R$ l'équation $f(x)=-2$.\\item Résoudre dans $\\R$ l'équation $f(x)=2$.\\end{enumerate}\\medbreak\\uline{Réponses} :\\medbreak\\begin{enumerate}\\item On a $f(x)=-x + 4$\\item On reconnaît une équation du second degré de discriminant $\\Delta=8>0$, et donc cette équation admet deux solutions réelles $x_1$ et $x_2$ avec : \\quad $\\displaystyle x_1=\\sqrt{2} + 2$ \\quad et \\quad $\\displaystyle x_2=-\\sqrt{2} + 2$.\\bigbreak{}\\end{enumerate}"

Before if Delta < 0: I would like output +=r"\item On a $f(x)={}$".format(latex(fcanonique(x))) to display the formula without transformation.

Thanks.

edit retag flag offensive close merge delete

Comments

First embryo of an idea : work by generating strings representing your "raw" polynomials, format this to LaTeX (possibly with LatexExpr), and convert them to symbolic expressins via eval only when needed.

Our current whether is currently too hot fo me to tackle this one... ;-).

HTH,

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2022-07-19 21:18:53 +0200 )edit

The problem with strings are signs : I can retrieve a, b, c, alpha and beta values to make a string, but I have to manage signs with if then else conditions to prevent things like (x+-1)^2+-2. If I understand your solution correctly, I think I'm going to have this problem I once had while making a python program that does elementary operations on fractions.

ryss gravatar imageryss ( 2022-07-19 22:35:39 +0200 )edit

3 Answers

Sort by » oldest newest most voted
2

answered 2022-07-20 03:24:38 +0200

Juanjo gravatar image

updated 2022-07-20 13:38:09 +0200

Instead of defining fcanonique , I would directly write a*(x-alpha)^2+beta once replaced the constants. As a proof of concept, the code

a, b, c = -2, 3, 4
f(x) = a*x^2+b*x+c
alpha = -b/2/a
beta = f(alpha)
fcanonique(x) = a*(x-alpha)^2+beta

texte = (r"Je ne veux pas que mon polynôme soit écrit comme ça : "
         fr"${latex(fcanonique(x))}$."
         r"Plutôt, il faut qu'il soit écrit comme ça : "
         fr"${a}(x-{alpha})^2+{beta}$.")

print(texte)

yields

Je ne veux pas que mon polynôme soit écrit comme ça : $-\frac{1}{8} \, {\left(4 \, x - 3\right)}^{2} + \frac{41}{8}$. Plutôt, il faut qu'il soit écrit comme ça : $-2(x-3/4)^2+41/8$.

Please note that you can simplify your code with the help of f-strings instead of the format method and concatenate strings as shown above. Likewise, I think you can use randrange(-1,2,2) instead of your own function signe.

Edit. Use the pol function below to fine print the binomial a(x-alpha)^2+beta:

def pol(a, alpha, beta):
    if a==1:
        fc = "$"
    elif a==-1:
        fc = "$-"
    else:
        fc = f"${a}"
    if alpha==0:
        fc += "x^2"
    elif alpha>0:
        fc += f"(x-{alpha})^2"
    else:
        fc += f"(x+{abs(alpha)})^2"
    if beta==0:
        fc += "$"
    elif beta>0:
        fc += f"+{beta}$"
    else:
        fc += f"-{abs(beta)}$"
    return fc

For example, this code

a, b, c = -1, -3, -4
f(x) = a*x^2+b*x+c
alpha = -b/2/a
beta = f(alpha)

texte = "La forme canonique est "
texte += pol(a,alpha,beta)
texte += ". C'est bien comme ça."
print(texte)

now yields

La forme canonique est $-(x+3/2)^2-7/4$. C'est bien comme ça.
edit flag offensive delete link more

Comments

I agree. If you need such a fine level of control, you will have to code it yourself.

John Palmieri gravatar imageJohn Palmieri ( 2022-07-20 07:25:48 +0200 )edit

Yes I think I have to code it with Python. The problem with this answer is that with a, b, c = -2, 3, -4 (I changed the value of c which is now negative), the result is $-2(x-3/4)^2+-23/8$. As you can see, there is a +- that I would like to avoid. I've been using sage for a little less than two weeks, I don't yet know all the possibilities like f-strings (I hadn't used this with python before, and it's really helpfull). You're right with randrange(-1,2,2), I don't know why I didn't think about it :) Thanks for these informations which improves my code, however the problem remains.

ryss gravatar imageryss ( 2022-07-20 09:49:23 +0200 )edit

See the edit of my answer which copes with your objection.

Juanjo gravatar imageJuanjo ( 2022-07-20 13:39:54 +0200 )edit

Thanks a lot. I had started to write something (with if then else), but longer and less elegant. I didn't think to build the expression "little by little" with +=. That's a good idea. I'm going to use this to rewrite my python program that does operations with fractions (and returns latex code).

ryss gravatar imageryss ( 2022-07-20 14:51:34 +0200 )edit
1

answered 2022-07-19 23:53:31 +0200

If you have actual numbers a, b, and c and you define Delta = b**2-4*a*c, there is nothing to hold: Python immediately evaluates Delta as a number. You could instead define Delta as a symbolic expression in terms of variables a, b, and c, and then evaluate it. Something like this:

sage: var('a,b,c')
(a, b, c)
sage: D = b**2 - 4*a*c
sage: D
b^2 - 4*a*c
sage: D.subs({a: 2, b: 1, c: 5})
-39

In terms of your code:

from random import sample
def signe():
    signe = sample([Integer(i) for i in range(-1, 2, 1) if i != 0],1)
    return(signe[0])

def calcul(amax, bmax, cmax):
    # first change:
    var('a, b, c')

    # these are all symbolic now:
    f(x) = a*x^2+b*x+c
    alpha = -b/2/a
    beta = f(x=alpha)
    fcanonique(x) = a*(x-alpha)^2+beta
    Delta = b**2-4*a*c

    #  a_rand etc.: numbers to plug into these expressions.
    a_rand = randint(1,amax)*signe()
    b_rand = randint(0,bmax)*signe()
    c_rand = randint(0,cmax)*signe()
    subs_dict = {a: a_rand, b: b_rand, c: c_rand}

    output = r"Soit $f$ le trinôme défini sur $\R$ par ~${}=0$.".format(latex(f(x)))
    output += r"\medbreak"
    output += r"\begin{enumerate}"
    output += r"\item Déterminer une forme canonique de $f$."
    output += r"\item Résoudre dans $\R$ l'équation $f(x)=0$ par la méthode de votre choix."
    output += r"\item $f$ est-elle factorisable ? Si oui, déterminer en une forme factorisée."

    # print c or c_rand?
    output += r"\item Résoudre dans $\R$ l'équation $f(x)={}$.".format(c_rand)

    # print beta or beta.subs(subs_dict)?
    output += r"\item Résoudre dans $\R$ l'équation $f(x)={}$.".format(beta)

    output += r"\end{enumerate}"
    output += r"\medbreak\uline{Réponses} :\medbreak"
    output += r"\begin{enumerate}"
    output +=r"\item On a $f(x)={}$".format(latex(fcanonique(x)))

    # D is Delta with numbers plugged in
    D = Delta.subs(subs_dict)
    if D < 0:
        output += r"\item On reconnaît une équation du second degré de discriminant $\Delta={}<0$, et donc cette équation n'a pas de solution réelle :".format(latex(Delta))
        output += "\\bigbreak{}"
        output += r"Ce trinôme admet une forme canonique : "
    elif D == 0:
        output += r"\item On reconnaît une équation du second degré de discriminant $\Delta={}$, et donc cette équation admet une unique solution $x_0={}$".format(latex(Delta), latex(alpha))
    else:
        x1 = simplify((-b-Delta^(1/2))/(2*a))
        x2 = simplify((-b+Delta^(1/2))/(2*a))
        ffactorisee(x) = a*(x-x1)*(x-x2)
        output += r"\item On reconnaît une équation du second degré de discriminant $\Delta={}>0$, et donc cette équation admet deux solutions réelles $x_1$ et $x_2$ avec : \quad $\displaystyle x_1={}$ \quad et \quad $\displaystyle x_2={}$.".format(latex(Delta), latex(x1), latex(x2))
        output += "\\bigbreak{}"
    output += r"\end{enumerate}"
    return(output)
edit flag offensive delete link more

Comments

I changed format(latex(fcanonique(x)) to format(latex(fcanonique(x).subs(subs_dict))), but, the problem still remain : I tried one calcul(5,5,5) for example, and it returned :

"Soit $f$ le trinôme défini sur $\\R$ par ~$-4 \\, x^{2} + 3 \\, x=0$. ... blablabla ... \\uline{Réponses} :\\medbreak\\begin{enumerate}\\item On a $f(x)=-\\frac{1}{16} \\, {\\left(8 \\, x - 3\\right)}^{2} + \\frac{9}{16}$

And I would like to have $f(x)=-4 \left(x-\frac{3}{8}\right)^{2}+\frac{9}{16}$

ryss gravatar imageryss ( 2022-07-20 00:28:39 +0200 )edit
0

answered 2022-07-20 21:00:18 +0200

ryss gravatar image

With all the answers I received before, I was able to build this code, with a small improvement.

def signe(valeur):
    if valeur < 0:
        return(fr"-{latex(-valeur)}")
    else:
        return(fr"+{latex(valeur)}")

def cform(a, alpha, beta):  # cform means canonical form a (x - alpha)^2 + beta
    if a == 1:
        fc_str = fr"\displaystyle \left(~{latex(x-alpha)}~\right)^2 {signe(beta)}"
    elif a == -1:
        fc_str = fr"\displaystyle -\left(~{latex(x-alpha)}~\right)^2 {signe(beta)}"
    else:
        fc_str = fr"\displaystyle {latex(a)}\left(~{latex(x-alpha)}~\right)^2 {signe(beta)}"
    return fc_str

def fform(a, x1, x2): # fform means factored form a (x - x1) (x - x2)
    if a==1:
        ff_str = fr"\displaystyle \left(~{latex(x-x1)}~\right)\left(~{latex(x-x2)}~\right)"
    elif a==-1:
        ff_str = fr"\displaystyle -\left(~{latex(x-x1)}~\right)\left(~{latex(x-x2)}~\right)"
    else:
        ff_str = fr"\displaystyle {latex(a)}\left(~{latex(x-x1)}~\right)\left(~{latex(x-x2)}~\right)"
    return ff_str

The improvment is to write \left(~{latex(x-alpha)}~\right)^2 instead of \left(~{latex((x-alpha)^2)}~\right) which involves a calculation. Placing x-alpha in latex{ } prevents this calculation and we remove the sign problem for alpha (I noticed this when I built the fform function and I applied it for function cform).

For the sign of beta, I imagined the function signe that it is possible to use in other places.

I'm sure this can be improved.

Thanks for all the answers that were very helpfull, I've learnd a lot.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2022-07-19 20:53:44 +0200

Seen: 118 times

Last updated: Jul 20