I am hoping to be able to create a macro to multiply matrices using a lua module. The module is here:
https://raw.github.com/davidm/lua-matrix/master/lua/matrix.lua
As suggested to me in a previous question I put my lua code in a separate lua file and dofiled
it as below:
\documentclass{article}
\usepackage{xparse}
\usepackage{luacode}
\usepackage{fontspec}
\directlua{dofile("matrix.lua")}
\directlua{dofile("lua2.lua")}
\ExplSyntaxOn
\NewDocumentCommand{\matrixop}{ m m }
{
\luaexec{
matrop(#1,#2)
}
}
\ExplSyntaxOff
\begin{document}
\matrixop{{1,2,3},{4,5,6}}{{7,8,9},{10,11,12}}
\end{document}
Where the file lua2.lua
contained the following:
function matrop (mat1, mat2)
local matrix = require 'matrix'
m1 = matrix {mat1}
m2 = matrix {mat2}
m3 = matrix.add(m1,m2)
a = matrix.latex(m3,c)
tex.print(a)
end
The issue that arose with this is that in matrix.lua
a matrix is defined as e.g.
m = matrix{{1,2,3},{4,5,6}}
Thus, I have to pass as mat1
something that looks like {1,2,3},{4,5,6}
. However, as it stands, in the code above matrop(#1,#2)
is equivalent to
matrop({1,2,3},{4,5,6},{7,8,9},{10,11,12})
Where the comma separating the rows in mat1
is visible to the macro and so matrop
sees 4 comma separated arguments rather than 2 arguments that are comma separated. Lua understands me to have passed a pair of single row matrices after dropping the "extra" two arguments (this took forever to figure out). Adding extra braces around each argument to hide the commas doesn't work because it screws up the table that matrix
is expecting. My idea was to replace the row separating comma by a *
, pass that to matrop
, revert the *
to a comma in lua using strings, convert the strings back into tables and then pass that to the matrix command (this took much reading and fiddling, I don't know lua at all). The result is below:
\documentclass{article}
\usepackage{xparse}
\usepackage{luacode}
\usepackage{fontspec}
\directlua{dofile("matrix.lua")}
\directlua{dofile("lua2.lua")}
\ExplSyntaxOn
\NewDocumentCommand{\matrixop}{ m m }
{
% quotes are so that matrop sees args as strings
\luaexec{
matrop("{#1}","{#2}")
}
}
\ExplSyntaxOff
\begin{document}
% row separator now a *
\matrixop{{1,2,3}*{4,5,6}}{{7,8,9}*{10,11,12}}
\end{document}
Where lua2.lua
is as follows:
function matrop (mat1, mat2)
-- replace *'s with ,'s
s1 = string.gsub(mat1,"*",",")
s2 = string.gsub(mat2,"*",",")
-- functions that load resulting strings
f1 = assert(loadstring("return"..s1))
f2 = assert(loadstring("return"..s2))
-- t1 and t2 are now tables (as I understand it)
t1 = f1()
t2 = f2()
local matrix = require 'matrix'
-- pass table entries (rows) to matrix definers
m1 = matrix {t1[1],t1[2]}
m2 = matrix {t2[1],t2[2]}
m3 = matrix.add(m1,m2)
a = matrix.latex(m3,c)
tex.print(a)
end
I am sure that I have done many bad/improper/horrible things above. My question is: how in the world should I actually be doing this? Is there an easy way to pass the information needed to define the matrices to lua? Any and all suggestions, comments, tips, solutions etc. are welcome.
Best Answer
If you use (IMHO) a more user-friendly input similar to (a, b, c)(d, e, f) than it is easy to create the matrices with basic lua commands without the need to know the sizes of the matrices.
Edit Matlab style: If you want to use a matrix-input similar to Matlab you can use the following functions. Here it is not necessary to use the
xparse
package and it is not needed to know how many matrices (and there dimensions) the user give to the function.