2

This is my first attempt to create macro with luatex. the macro \solveq to solve quadratic equation ax^2+bx+c=0 here my code

\documentclass[12pt]{article}
\usepackage{amssymb}
\usepackage{luacode}


\begin{luacode*}
function solve_equa(equa)
local a_here= string.find (equa,"x^2")
local b_here= string.find (equa,"x[^^]")
local c_here= string.find (equa,"x[-+](.-)=")

local a = string.match(equa,"%$(.-)x^2") or 0
local b = (b_here ~=nil) and  ((a_here ~=nil) and  string.match(equa,"x^2(.-)x") or string.match(equa,"%$(.-)x")) or 0
local c = (c_here ~=nil) and  ((a_here ~=nil) and  ((b_here ~=nil) and string.match(equa,"%b^x(.-)=") or string.match(equa,"%x^2(.-)="))  or
string.match(equa,"x(.-)=")) or 0

if a=="" or a=="+" then
 a=1
elseif a=="-" then
 a=-1
end

if b=="" or b=="+" then
 b=1
elseif b=="-" then
 b=-1
end

if a==0 then
local  temp =  (-c/b == -0) and 0 or -c/b
       solution = "x = " .. temp
else

D = b*b-4*a*c

if D==0 then
       solution = "$x = " ..  -b/2/a .. "$"
else if D>0 then
       solution  = "$x1 = " .. (-b+math.sqrt(D))/2/a .. "\\quad  x2 =" .. (-b-math.sqrt(D))/2/a ..  "$"
     else
       solution  =[[no solution in $\mathbb{R}$]]
     end
end
end
return solution
end

\end{luacode*}

\def\solveq#1{solution of equation $#1$:\par
{\centering \directlua{solve_equa("$#1$") tex.print(solution)}\par}}

\begin{document}

\solveq{-x^2+5x+4=0}

\end{document}

My hope is to symplify collect of numbers a,b,c with the lpeg functions

  • 1
    Are you familiar with the sagetex package? It gives you access to a computer algebra system with a lot of built in commands for mathematics. Want to collect a,b,c? Use coefficient(sparse=False) with your polynomial as shown here. You would, however, need Sage installed locally on your computer or use Cocalc. No need to reinvent the wheel! – DJP Oct 14 '18 at 1:17
2

Below I present an LPEG grammar which can do what you asked for, but focusing on simplicity. For more complicated parsing you need a more complicated parser. You might want to have a look at, and perhaps adapt the parser from my project here: https://github.com/hmenke/boost_matheval/blob/master/include/matheval.lua

\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{luacode}

\begin{luacode*}
local lpeg = require"lpeg"
local C, P, S = lpeg.C, lpeg.P, lpeg.S

local sgn = { [""] = 1, ["+"] = 1, ["-"] = -1 }

local w     = S" \t"^0
local eq    = P"="
local var   = P"x"
local pm    = C(S"+-"^0) / sgn
local num   = C((1 - var - eq)^0) / function(c) return c == "" and 1 or tonumber(c) end
local coeff = pm * w * num / function(a,b) return a * b end

local grammar = (
    w * coeff * w * var * P"^2" *
    w * coeff * w * var *
    w * coeff *
    w * eq *
    w * coeff
)

local parse = function(exp)
    return grammar:match(exp)
end

solve = function(exp)
    local a, b, c, d = parse(exp)
    c = c - d

    local D = b^2 - 4*a*c

    if D < 0 then
        tex.sprint("\\[\\text{no solution in $\\mathbb{R}$}\\]")
        return
    end

    if D == 0 then
        tex.sprint("\\[x_1 = " .. -b/(2*a) .."\\]")
        return
    end

    local x1 = (-b + math.sqrt(D))/(2*a)
    local x2 = (-b - math.sqrt(D))/(2*a)
    tex.sprint("\\[x_1 = " .. x1 .. " \\quad x_2 = " .. x2 .. "\\]")
end
\end{luacode*}

\def\solveq#1{\[ #1 \] has the following solutions: \directlua{solve("\luaescapestring{#1}")}}

\begin{document}

\solveq{-x^2+5x+4=0}

\solveq{- x^2 + 3 x + 2 = 2}

\solveq{x^2+ x +1=0}

\solveq{-13x^2+0x+1=0}

\end{document}

enter image description here

  • Thank's, the role of /sgn after local pm = C(S"+-"^0) ? – Salim Bou Oct 16 '18 at 9:41
  • 2
    @SalimBou / sgn is a semantic action which uses the table sgn to map the capture ("" or "+" or "-") to a number (-1 or +1). – Henri Menke Oct 16 '18 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.