3

I wrote my first Lua code and it works as expected when running through lua.exe. But when I try to include the lua file or its complete source code I always get the error ! LuaTeX error mr.lua:11: unexpected symbol near '>' stack traceback: [C]: in function 'dofile' [\directlua]:1: in main chunk.

This is my tex code:

\documentclass{article}
\usepackage{luacode}
\begin{document}
\directlua{dofile("mr.lua")}
Is $1000003$ a prime number? \texttt{\directlua{tex.sprint(is_prime(1000003))}}
\end{document}

Here is my mr.lua:

-- This file provides the deterministic Miller-Rabin Algorithm.

-- http://en.wikipedia.org/wiki/Modular_exponentiation
function modular_pow(base, exponent, modulus)
    result = 1
    base = base % modulus
    while exponent > 0 do
        if (exponent % 2 == 1) then
            result = (result * base) % modulus
        end
        exponent = exponent >> 1
        base = (base * base) % modulus
    end
    return result
end

function is_composite(a, d, n, s)
    if modular_pow(a, d, n) == 1 then
        return false
    end
    for i = 0, s - 1 do
        if modular_pow(a, math.pow(2,i) * d, n) == n-1 then
            return false
        end
    end
    return true -- n  is definitely composite
end

-- Although Lua cannot handle big numbers without third party libs
-- this is proven to work correct for all numbers up to 100000000
-- bigger numbers not tested.
global function is_prime(n)
    if n < 5 then
        if n == 2 or n == 3 then
            return true
        end
        return false
    end
    p = n % 6 if p ~= 1 and p ~= 5 then return false end
    d, s = n - 1, 0
    while d % 2 == 0 do
        d, s = d >> 1, s + 1
    end
    -- Returns exact according to http://primes.utm.edu/prove/prove2_3.html
    if n < 2047 then
        if is_composite(2, d, n, s) then
            return false
        end
        return true
    end
    if n < 1373653 then
        for i,a in ipairs({2,3}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 9080191 then
        for i,a in ipairs({31,73}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 25326001 then
        for i,a in ipairs({2,3,5}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 118670087467 then
        if n == 3215031751 then
            return false
        end
        for i,a in ipairs({2,3,5,7}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 2152302898747 then
        for i,a in ipairs({2,3,5,7,11}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 3474749660383 then
        for i,a in ipairs({2,3,5,7,11,13}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 341550071728321 then
        for i,a in ipairs({2,3,5,7,11,13,17}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 3825123056546413051 then
        for i,a in ipairs({2,3,5,7,11,13,17,19,23}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    -- otherwise
    for i,a in ipairs({2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}) do
        if is_composite(a, d, n, s) then
            return false
        end
    end
    return true
end
2
  • Which version of Lua (not LuaTeX) do you use?
    – Mico
    Feb 25, 2015 at 11:16
  • I used 5.3.0 because I didn't know that LuaTeX uses just 5.2.0 and that there is such an enormous difference between these versions. Now I now.
    – user49121
    Feb 25, 2015 at 12:09

1 Answer 1

4

It turns out the Lua version shipped with LuaTeX doesn't support shifting operator >> from the line exponent = exponent >> 1.

For those who are interested here the complete working code for the old Lua 5.2 (hopefully they'll update soon):

TeX:

\documentclass{article}
\usepackage{luacode}
\begin{document}
\directlua{dofile("mr.lua")}
Is $1000003$ a prime number? \texttt{\directlua{
if is_prime(1000003) then tex.sprint("true") else tex.sprint("false") end}}
\end{document}

mr.lua

-- This file provides the deterministic Miller-Rabin Algorithm.

-- http://en.wikipedia.org/wiki/Modular_exponentiation
function modular_pow(base, exponent, modulus)
    result = 1
    base = base % modulus
    while exponent > 0 do
        if (exponent % 2 == 1) then
            result = (result * base) % modulus
        end
        exponent = math.floor(exponent/2)
        base = (base * base) % modulus
    end
    return result
end

function is_composite(a, d, n, s)
    if modular_pow(a, d, n) == 1 then
        return false
    end
    for i = 0, s - 1 do
        if modular_pow(a, math.pow(2,i) * d, n) == n-1 then
            return false
        end
    end
    return true -- n  is definitely composite
end

-- Although Lua cannot handle big numbers without third party libs
-- this is proven to work correct for all numbers up to 100000000
-- bigger numbers not tested.
function is_prime(n)
    if n < 5 then
        if n == 2 or n == 3 then
            return true
        end
        return false
    end
    p = n % 6 if p ~= 1 and p ~= 5 then return false end
    d, s = n - 1, 0
    while d % 2 == 0 do
        d, s = math.floor(d/2), s + 1
    end
    -- Returns exact according to http://primes.utm.edu/prove/prove2_3.html
    if n < 2047 then
        if is_composite(2, d, n, s) then
            return false
        end
        return true
    end
    if n < 1373653 then
        for i,a in ipairs({2,3}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 9080191 then
        for i,a in ipairs({31,73}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 25326001 then
        for i,a in ipairs({2,3,5}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 118670087467 then
        if n == 3215031751 then
            return false
        end
        for i,a in ipairs({2,3,5,7}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 2152302898747 then
        for i,a in ipairs({2,3,5,7,11}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 3474749660383 then
        for i,a in ipairs({2,3,5,7,11,13}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 341550071728321 then
        for i,a in ipairs({2,3,5,7,11,13,17}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    if n < 3825123056546413051 then
        for i,a in ipairs({2,3,5,7,11,13,17,19,23}) do
            if is_composite(a, d, n, s) then
                return false
            end
        end
        return true
    end
    -- otherwise
    for i,a in ipairs({2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}) do
        if is_composite(a, d, n, s) then
            return false
        end
    end
    return true
end
3
  • 1
    I would not expect an update to Lua 5.3 this decade.
    – topskip
    Feb 25, 2015 at 12:04
  • Read this, too. The 5.3.0 Syntax is in my opinion much easier and natural to code. Also it has other huge advantages over 5.2.0 but it's not my decision.
    – user49121
    Feb 25, 2015 at 12:14
  • 1
    The luajit version is still 5.1....
    – topskip
    Feb 25, 2015 at 12:26

You must log in to answer this question.