.. highlightlang:: lua .. us.bug translate .. index:: Lua .. _lua: Lua === Lua is a powerful and fast scripting language that is easy to learn. In UniPlot R2016 Lua can be used parallel with UniScript. UniPlot uses LuaJIT (http://www.luajit.org) from Mike Pall. More Informationen ------------------ The first edition of "Programming in Lua" by Roberto Ierusalimschy, Lua.org, December 2003, ISBN 8590379817 is available online: http://www.lua.org/pil/contents.html * Here is the link for the reference manual 5.1: http://www.lua.org/manual/5.1/ * Good tutorials can be found here: http://lua-users.org/wiki/TutorialDirectory * :ref:`lua-functions` * :ref:`lua-licenses` .. sidebar:: Lua .. image:: S:/uniplot-obj/images/powered-by-lua.* Lua is a powerful, fast, lightweight, embeddable scripting language -- http://www.lua.org/about.html. Short comparison of Lua and UniScript -------------------------------------- Here is an example in UniScipt. The function finds the index of the maximum element in a vector: .. code-block:: us :linenos: // Maximum and index of a vector def maximum(a) { mi = 1; m = a[mi]; for (i in 1:len(a)) { if (a[i] > m) { mi = i; m = a[i]; } } return [m, mi]; } To create the function, we use a UniPlot-Editor. The file must be saved with the extension ``.ic``. The **UniScript=>Save/Execute** command or the function key **F4** translates the function. To invoke the function, open the command window (**View=>Command Window**). First we create a vector with 1,000,000 random numbers in the range 0 to 1. .. code-block:: us * r = rand(1,1e6) .. code-block:: us * tic(); maximum(r); toc() 56.1462 ``tic()`` starts a timer and ``toc()`` returns the time since the timer has been started in milliseconds. Here is the same function in Lua. .. code-block:: lua :linenos: -- Maximum and index of a vector function maximum(a) local mi = 1 local m = a[mi] for i = 1, #a do if a[i] > m then mi = i m = a[i] end end return m, mi end The function must be saved in a file with the extension ``.lua``. The first line is a comment. In Lua, comments start with a doublehyphen ``--`` and run until the end of the line. Instead of ``def`` the Lua function is created with the ``function`` keyword. In UniScript statements are enclosed in braces ``{ ... }``. Lua uses the end keyword. .. code-block:: lua function ... end for ... do ... end if ... then ... end The first statement in UniScript is ``mi = 1;`` and in Lua ``local mi = 1``. In UniScript all variables inside a function are local variables. To create a global variable, it must be declared at the beginning of the function using the ``global`` keyword. In Lua a local variable must be declared before using it with the keyword ``local``. Otherwise the variable is global. See also http://lua-users.org/wiki/LocalByDefault. To compile the Lua function press **F4** in the editor. To execute the function open the the command window. To switch into the Lua mode type in ``.lua``. .. image:: S:/uniplot-obj/images/lua-cmd-wnd-maxi.* Now you can execute the following statements: .. code-block:: lua :linenos: > a = {}; for i=1,1e6 do a[i] = math.random() end > up = require"uniplot" > up.tic(); maximum(a); print(up.toc()) 0.95537533378229 The first command creates a Lua table with 1 million elements. The ``random()`` function from the Lua ``math`` library will create a random number. The second statement loads the ``uniplot`` library for the functions ``tic()`` and ``toc()``. They use the Windows ``QueryPerformanceCounter`` function to measure the execution time. The Lua function takes approx. one millisecond. The UniScript function takes approx. 50 milliseconds. The reasons are: 1.) LuaJIT is a Just-In-Time compiler, 2.) UniScript is an interpreter. In practice, UniScript will call a C function to calculate the maximum. Exit the Lua command window with the ``exit`` command. In the UniScript command window the :ref:`maxi` function can be invoked. This function is even a bit faster than the Lua function. .. code-block:: us * a = rand(1e6,1); * tic(); maxi(a); toc() 0.7638 UniScript Interface ------------------- The ``r = us.call(us_func_name, p1, ...)`` function is used to call an UniScript function. The interface is loaded from the ``lua_uniscript.dll`` dll. Example: .. code-block:: lua us = require "lua-uniscript" -- load lua-uniscript.dll m = us.call("sin", 1) print(m) 0.8414709848079 If a UniScript function returns a scalar number, it will be converted to a Lua number. In all other cases the UniScript value will be converted to a Lua ``userdata`` element. .. code-block:: lua x = us.call("linspace", 0, 2*math.pi, 1e5) print(x) matrix: 0x22e70660 print(type(x)) userdata ``x`` is a UniScript vector with 100,000 points. .. code-block:: lua y = us.call("sin", x) us.call("plot", x, y) Normally ``us.call()`` will not be invoked directly. A wrapper function is used instead. Here are some examples of the ``uniplot`` module: .. code-block:: lua -- uniplot.lua local us = require "lua-uniscript" local mat = require "uniplot.matrix" local u = {} u.abs = function(a1) return mat:new(us.call("abs", a1)) end u.acos = function(a1) return mat:new(us.call("acos", a1)) end u.acosh = function(a1) return mat:new(us.call("acosh", a1)) end return u With the following two packages .. code-block:: lua up = require"uniplot" mat = require"uniplot.matrix" the following UniScript operators can be executed: .. list-table:: :header-rows: 1 * - UniScript - Lua - Comment * - ``a + b`` - ``a + b`` or ``mat.add(a, b)`` - The matrices must have the same size or must be scalars. * - ``a - b`` - ``a - b`` or ``mat.sub(a, b)`` - Subtraction. * - ``a * b`` - ``a * b`` or ``mat.mul(a, b)`` - Matrix multiplication * - ``a .* b`` - ``mat.emul(a, b)`` - Multiplication element wise * - ``a / b`` - ``a / b`` or ``mat.div(a, b)`` - * - ``a ./ b`` - ``mat.ediv(a, b)`` - Disision element wise * - ``a \ b`` - - * - ``a'`` - ``a:trans()`` - Transponse. * - ``a.'`` - ``a:etrans()`` - * - ``nr(a)`` - ``a:nr()`` or ``mat.nr(a)`` - Number of rows. * - ``nc(a)`` - ``a:nc()`` or ``mat.nc(a)`` - Number of columns. * - ``len(a)`` - ``#a`` or ``a:len()`` or ``mat.len(a)`` - Number of elements of a vector. * - ``a^-1`` or ``inv(a)`` - ``a^-1`` or ``a:inv()`` or ``mat.inv(a)`` - Inverse of a matrix. * - ``[1,2,3]`` - ``mat.matrix{1,2,3}`` - Row vector * - ``[1;2;3]`` - ``mat.matrix({1,2,3}):trans()`` - Column vector. * - ``[1,2;3,4]`` - ``up.reshape(mat.matrix{1,2,3,4}, 2, 2):trans()`` - Matrix * - ``[a, b]`` - ``mat.hcat(a,b)`` - Concatenate matrices horizontally * - ``[a; b]`` - ``mat.vcat(a,b)`` - Concatenate matrices vertical * - ``a < b``, ``<= == != > >=`` - ``mat.lt(a, b)``, ``le, eq, ne, gt, ge`` - Compare operators for matrices and vectors. * - ``a & b, a | b, a@b, ~a, a << b, a >> b`` - ``mat.band(a, b)``, ``bor, xor, not, shl, shr`` - Bit wise and, or, exclusiv or, not, shift left, shift right * - ``1:10``, ``1:0.5:3``, ``3:1`` - ``mat.range(1, 10)``, ``mat.range(1,0.5,3)``, ``mat.range(3, 1)`` - Sequence ``[1, 2, .. 10]``, ``[1, 1.5, 2, 2.5, 3]``, ``[3, 2, 1]`` * - ``b = a[i;j]`` - ``b = a:rowcol(i, j)`` - * - ``a[i;]``, ``a[;j]`` - ``a:row(i)``, ``a:col(j)`` - * - ``a[:]`` - reshape(a, 1, #a) - * - ``c = 1+3i`` - ``c = complex(1, 3)`` - Create complex numbers and matrices. Lua Debugger ------------ A Lua-Debugger will be available in one of the next releases. Remarks ------- * The LuaJIT version is 2.1-beta, 2016-01-18 with ``-DLUAJIT_ENABLE_LUA52COMPAT`` enabled. The DLL ``luajit.dll`` is compiled using the Microsoft Visual Studio 2015 kompiliert with the C-Runtime-Library ``msvcr120.dll``. The LuaJIT DLL can be replaced by an owner build DLL. :sub:`id-1010283`