• Subject: Complex library for LuaJIT
• From: Luis Carvalho <lexcarvalho@...>
• Date: Sun, 28 Aug 2011 11:32:31 -0400

```Hi,

I have implemented a complex library for Numlua using LuaJIT. Since it might
be of more general use on its own, I'm sharing it here. All feedback is
welcome (especially because I'm not proficient in LuaJIT...)

Cheers,
Luis

--
Computers are useless. They can only give you answers.
-- Pablo Picasso

--
Luis Carvalho (Kozure)
lua -e 'print((("lexcarvalho@NO.gmail.SPAM.com"):gsub("(%u+%.)","")))'
```
```--[[
-- ljcomplex.lua
-- Complex library for Numeric Lua, LuaJIT version
-- Luis Carvalho (lexcarvalho@gmail.com)
-- See Copyright Notice in numlua.h
--]]

local ffi = require "ffi"
local C, istype = ffi.C, ffi.istype

local T0 = "double c%s (double complex z);"
local F0 = {"abs", "arg", "imag", "real"}
local T1 = "double complex c%s (double complex z);"
local F1 = {"acos", "acosh", "asin", "asinh", "atan", "atanh", "cos",
"cosh", "exp", "log", "proj", "sin", "sinh", "sqrt", "tan", "tanh"}
local T2 = "double complex c%s (double complex x, double complex z);"
local F2 = {"add", "sub", "mul", "div", "pow"} -- metamethods

local cdefs = {}
for _, f in ipairs(F0) do cdefs[#cdefs + 1] = T0:format(f) end
for _, f in ipairs(F1) do cdefs[#cdefs + 1] = T1:format(f) end
cdefs[#cdefs + 1] = "double complex conj (double complex z);"
for _, f in ipairs(F2) do cdefs[#cdefs + 1] = T2:format(f) end
ffi.cdef(table.concat(cdefs))

local cpxlib = {}
for _, f in ipairs(F0) do cpxlib[f] = C["c" .. f] end
for _, f in ipairs(F1) do cpxlib[f] = C["c" .. f] end
cpxlib.conj = C.conj
cpxlib.logabs = function (z)
local r, i = math.abs(z.re), math.abs(z.im)
if i > r then r, i = i, r end
local t = i / r
return math.log(r) + 0.5 * C.log1p(t * t)
end

local complex
local tocomplex = function (a, b)
if not istype(complex, a) then
assert(type(a) == "number", "number or complex expected")
return complex(a), b
elseif not istype(complex, b) then
assert(type(b) == "number", "number or complex expected")
return a, complex(b)
end
return a, b
end

a, b = tocomplex(a, b)
return complex(a.re + b.re, a.im + b.im)
end
function cpxlib.sub (a, b)
a, b = tocomplex(a, b)
return complex(a.re - b.re, a.im - b.im)
end
function cpxlib.mul (a, b)
a, b = tocomplex(a, b)
return complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re)
end
function cpxlib.div (a, b)
a, b = tocomplex(a, b)
local r, d
if math.abs(b.re) < math.abs(b.im) then
r = b.re / b.im
d = b.re * r + b.im
return complex((a.re * r + a.im) / d, (a.im * r - a.re) / d)
end
r = b.im / b.re
d = b.im * r + b.re
return complex((a.im * r + a.re) / d, (a.im - a.re * r) / d)
end

local mt = { -- while LuaJIT doesn't support them natively
__len = function (a, b) return C.cabs(a) end,
__unm = function (a) return complex (-a.re, -a.im) end,