convert from dos to unix-style line endings

This commit is contained in:
David Manura 2010-09-22 21:00:52 -04:00
parent 5b3e7b19c5
commit 67f724300f
9 changed files with 2448 additions and 2448 deletions

View File

@ -1,385 +1,385 @@
-- complex 0.3.0 -- complex 0.3.0
-- Lua 5.1 -- Lua 5.1
-- 'complex' provides common tasks with complex numbers -- 'complex' provides common tasks with complex numbers
-- function complex.to( arg ); complex( arg ) -- function complex.to( arg ); complex( arg )
-- returns a complex number on success, nil on failure -- returns a complex number on success, nil on failure
-- arg := number or { number,number } or ( "(-)<number>" and/or "(+/-)<number>i" ) -- arg := number or { number,number } or ( "(-)<number>" and/or "(+/-)<number>i" )
-- e.g. 5; {2,3}; "2", "2+i", "-2i", "2^2*3+1/3i" -- e.g. 5; {2,3}; "2", "2+i", "-2i", "2^2*3+1/3i"
-- note: 'i' is always in the numerator, spaces are not allowed -- note: 'i' is always in the numerator, spaces are not allowed
-- a complex number is defined as carthesic complex number -- a complex number is defined as carthesic complex number
-- complex number := { real_part, imaginary_part } -- complex number := { real_part, imaginary_part }
-- this gives fast access to both parts of the number for calculation -- this gives fast access to both parts of the number for calculation
-- the access is faster than in a hash table -- the access is faster than in a hash table
-- the metatable is just a add on, when it comes to speed, one is faster using a direct function call -- the metatable is just a add on, when it comes to speed, one is faster using a direct function call
-- http://luaforge.net/projects/LuaMatrix -- http://luaforge.net/projects/LuaMatrix
-- http://lua-users.org/wiki/ComplexNumbers -- http://lua-users.org/wiki/ComplexNumbers
-- Licensed under the same terms as Lua itself. -- Licensed under the same terms as Lua itself.
--/////////////-- --/////////////--
--// complex //-- --// complex //--
--/////////////-- --/////////////--
-- link to complex table -- link to complex table
local complex = {} local complex = {}
-- link to complex metatable -- link to complex metatable
local complex_meta = {} local complex_meta = {}
-- complex.to( arg ) -- complex.to( arg )
-- return a complex number on success -- return a complex number on success
-- return nil on failure -- return nil on failure
local _retone = function() return 1 end local _retone = function() return 1 end
local _retminusone = function() return -1 end local _retminusone = function() return -1 end
function complex.to( num ) function complex.to( num )
-- check for table type -- check for table type
if type( num ) == "table" then if type( num ) == "table" then
-- check for a complex number -- check for a complex number
if getmetatable( num ) == complex_meta then if getmetatable( num ) == complex_meta then
return num return num
end end
local real,imag = tonumber( num[1] ),tonumber( num[2] ) local real,imag = tonumber( num[1] ),tonumber( num[2] )
if real and imag then if real and imag then
return setmetatable( { real,imag }, complex_meta ) return setmetatable( { real,imag }, complex_meta )
end end
return return
end end
-- check for number -- check for number
local isnum = tonumber( num ) local isnum = tonumber( num )
if isnum then if isnum then
return setmetatable( { isnum,0 }, complex_meta ) return setmetatable( { isnum,0 }, complex_meta )
end end
if type( num ) == "string" then if type( num ) == "string" then
-- check for real and complex -- check for real and complex
-- number chars [%-%+%*%^%d%./Ee] -- number chars [%-%+%*%^%d%./Ee]
local real,sign,imag = string.match( num, "^([%-%+%*%^%d%./Ee]*%d)([%+%-])([%-%+%*%^%d%./Ee]*)i$" ) local real,sign,imag = string.match( num, "^([%-%+%*%^%d%./Ee]*%d)([%+%-])([%-%+%*%^%d%./Ee]*)i$" )
if real then if real then
if string.lower(string.sub(real,1,1)) == "e" if string.lower(string.sub(real,1,1)) == "e"
or string.lower(string.sub(imag,1,1)) == "e" then or string.lower(string.sub(imag,1,1)) == "e" then
return return
end end
if imag == "" then if imag == "" then
if sign == "+" then if sign == "+" then
imag = _retone imag = _retone
else else
imag = _retminusone imag = _retminusone
end end
elseif sign == "+" then elseif sign == "+" then
imag = loadstring("return tonumber("..imag..")") imag = loadstring("return tonumber("..imag..")")
else else
imag = loadstring("return tonumber("..sign..imag..")") imag = loadstring("return tonumber("..sign..imag..")")
end end
real = loadstring("return tonumber("..real..")") real = loadstring("return tonumber("..real..")")
if real and imag then if real and imag then
return setmetatable( { real(),imag() }, complex_meta ) return setmetatable( { real(),imag() }, complex_meta )
end end
return return
end end
-- check for complex -- check for complex
local imag = string.match( num,"^([%-%+%*%^%d%./Ee]*)i$" ) local imag = string.match( num,"^([%-%+%*%^%d%./Ee]*)i$" )
if imag then if imag then
if imag == "" then if imag == "" then
return setmetatable( { 0,1 }, complex_meta ) return setmetatable( { 0,1 }, complex_meta )
elseif imag == "-" then elseif imag == "-" then
return setmetatable( { 0,-1 }, complex_meta ) return setmetatable( { 0,-1 }, complex_meta )
end end
if string.lower(string.sub(imag,1,1)) ~= "e" then if string.lower(string.sub(imag,1,1)) ~= "e" then
imag = loadstring("return tonumber("..imag..")") imag = loadstring("return tonumber("..imag..")")
if imag then if imag then
return setmetatable( { 0,imag() }, complex_meta ) return setmetatable( { 0,imag() }, complex_meta )
end end
end end
return return
end end
-- should be real -- should be real
local real = string.match( num,"^(%-*[%d%.][%-%+%*%^%d%./Ee]*)$" ) local real = string.match( num,"^(%-*[%d%.][%-%+%*%^%d%./Ee]*)$" )
if real then if real then
real = loadstring( "return tonumber("..real..")" ) real = loadstring( "return tonumber("..real..")" )
if real then if real then
return setmetatable( { real(),0 }, complex_meta ) return setmetatable( { real(),0 }, complex_meta )
end end
end end
end end
end end
-- complex( arg ) -- complex( arg )
-- same as complex.to( arg ) -- same as complex.to( arg )
-- set __call behaviour of complex -- set __call behaviour of complex
setmetatable( complex, { __call = function( _,num ) return complex.to( num ) end } ) setmetatable( complex, { __call = function( _,num ) return complex.to( num ) end } )
-- complex.new( real, complex ) -- complex.new( real, complex )
-- fast function to get a complex number, not invoking any checks -- fast function to get a complex number, not invoking any checks
function complex.new( ... ) function complex.new( ... )
return setmetatable( { ... }, complex_meta ) return setmetatable( { ... }, complex_meta )
end end
-- complex.type( arg ) -- complex.type( arg )
-- is argument of type complex -- is argument of type complex
function complex.type( arg ) function complex.type( arg )
if getmetatable( arg ) == complex_meta then if getmetatable( arg ) == complex_meta then
return "complex" return "complex"
end end
end end
-- complex.convpolar( r, phi ) -- complex.convpolar( r, phi )
-- convert polar coordinates ( r*e^(i*phi) ) to carthesic complex number -- convert polar coordinates ( r*e^(i*phi) ) to carthesic complex number
-- r (radius) is a number -- r (radius) is a number
-- phi (angle) must be in radians; e.g. [0 - 2pi] -- phi (angle) must be in radians; e.g. [0 - 2pi]
function complex.convpolar( radius, phi ) function complex.convpolar( radius, phi )
return setmetatable( { radius * math.cos( phi ), radius * math.sin( phi ) }, complex_meta ) return setmetatable( { radius * math.cos( phi ), radius * math.sin( phi ) }, complex_meta )
end end
-- complex.convpolardeg( r, phi ) -- complex.convpolardeg( r, phi )
-- convert polar coordinates ( r*e^(i*phi) ) to carthesic complex number -- convert polar coordinates ( r*e^(i*phi) ) to carthesic complex number
-- r (radius) is a number -- r (radius) is a number
-- phi must be in degrees; e.g. [0° - 360°] -- phi must be in degrees; e.g. [0° - 360°]
function complex.convpolardeg( radius, phi ) function complex.convpolardeg( radius, phi )
phi = phi/180 * math.pi phi = phi/180 * math.pi
return setmetatable( { radius * math.cos( phi ), radius * math.sin( phi ) }, complex_meta ) return setmetatable( { radius * math.cos( phi ), radius * math.sin( phi ) }, complex_meta )
end end
--// complex number functions only --// complex number functions only
-- complex.tostring( cx [, formatstr] ) -- complex.tostring( cx [, formatstr] )
-- to string or real number -- to string or real number
-- takes a complex number and returns its string value or real number value -- takes a complex number and returns its string value or real number value
function complex.tostring( cx,formatstr ) function complex.tostring( cx,formatstr )
local real,imag = cx[1],cx[2] local real,imag = cx[1],cx[2]
if formatstr then if formatstr then
if imag == 0 then if imag == 0 then
return string.format( formatstr, real ) return string.format( formatstr, real )
elseif real == 0 then elseif real == 0 then
return string.format( formatstr, imag ).."i" return string.format( formatstr, imag ).."i"
elseif imag > 0 then elseif imag > 0 then
return string.format( formatstr, real ).."+"..string.format( formatstr, imag ).."i" return string.format( formatstr, real ).."+"..string.format( formatstr, imag ).."i"
end end
return string.format( formatstr, real )..string.format( formatstr, imag ).."i" return string.format( formatstr, real )..string.format( formatstr, imag ).."i"
end end
if imag == 0 then if imag == 0 then
return real return real
elseif real == 0 then elseif real == 0 then
return ((imag==1 and "") or (imag==-1 and "-") or imag).."i" return ((imag==1 and "") or (imag==-1 and "-") or imag).."i"
elseif imag > 0 then elseif imag > 0 then
return real.."+"..(imag==1 and "" or imag).."i" return real.."+"..(imag==1 and "" or imag).."i"
end end
return real..(imag==-1 and "-" or imag).."i" return real..(imag==-1 and "-" or imag).."i"
end end
-- complex.print( cx [, formatstr] ) -- complex.print( cx [, formatstr] )
-- print a complex number -- print a complex number
function complex.print( ... ) function complex.print( ... )
print( complex.tostring( ... ) ) print( complex.tostring( ... ) )
end end
-- complex.polar( cx ) -- complex.polar( cx )
-- from complex number to polar coordinates -- from complex number to polar coordinates
-- output in radians; [-pi,+pi] -- output in radians; [-pi,+pi]
-- returns r (radius), phi (angle) -- returns r (radius), phi (angle)
function complex.polar( cx ) function complex.polar( cx )
return math.sqrt( cx[1]^2 + cx[2]^2 ), math.atan2( cx[2], cx[1] ) return math.sqrt( cx[1]^2 + cx[2]^2 ), math.atan2( cx[2], cx[1] )
end end
-- complex.polardeg( cx ) -- complex.polardeg( cx )
-- from complex number to polar coordinates -- from complex number to polar coordinates
-- output in degrees; [-180°,180°] -- output in degrees; [-180°,180°]
-- returns r (radius), phi (angle) -- returns r (radius), phi (angle)
function complex.polardeg( cx ) function complex.polardeg( cx )
return math.sqrt( cx[1]^2 + cx[2]^2 ), math.atan2( cx[2], cx[1] ) / math.pi * 180 return math.sqrt( cx[1]^2 + cx[2]^2 ), math.atan2( cx[2], cx[1] ) / math.pi * 180
end end
-- complex.mulconjugate( cx ) -- complex.mulconjugate( cx )
-- multiply with conjugate, function returning a number -- multiply with conjugate, function returning a number
function complex.mulconjugate( cx ) function complex.mulconjugate( cx )
return cx[1]^2 + cx[2]^2 return cx[1]^2 + cx[2]^2
end end
-- complex.abs( cx ) -- complex.abs( cx )
-- get the absolute value of a complex number -- get the absolute value of a complex number
function complex.abs( cx ) function complex.abs( cx )
return math.sqrt( cx[1]^2 + cx[2]^2 ) return math.sqrt( cx[1]^2 + cx[2]^2 )
end end
-- complex.get( cx ) -- complex.get( cx )
-- returns real_part, imaginary_part -- returns real_part, imaginary_part
function complex.get( cx ) function complex.get( cx )
return cx[1],cx[2] return cx[1],cx[2]
end end
-- complex.set( cx, real, imag ) -- complex.set( cx, real, imag )
-- sets real_part = real and imaginary_part = imag -- sets real_part = real and imaginary_part = imag
function complex.set( cx,real,imag ) function complex.set( cx,real,imag )
cx[1],cx[2] = real,imag cx[1],cx[2] = real,imag
end end
-- complex.is( cx, real, imag ) -- complex.is( cx, real, imag )
-- returns true if, real_part = real and imaginary_part = imag -- returns true if, real_part = real and imaginary_part = imag
-- else returns false -- else returns false
function complex.is( cx,real,imag ) function complex.is( cx,real,imag )
if cx[1] == real and cx[2] == imag then if cx[1] == real and cx[2] == imag then
return true return true
end end
return false return false
end end
--// functions returning a new complex number --// functions returning a new complex number
-- complex.copy( cx ) -- complex.copy( cx )
-- copy complex number -- copy complex number
function complex.copy( cx ) function complex.copy( cx )
return setmetatable( { cx[1],cx[2] }, complex_meta ) return setmetatable( { cx[1],cx[2] }, complex_meta )
end end
-- complex.add( cx1, cx2 ) -- complex.add( cx1, cx2 )
-- add two numbers; cx1 + cx2 -- add two numbers; cx1 + cx2
function complex.add( cx1,cx2 ) function complex.add( cx1,cx2 )
return setmetatable( { cx1[1]+cx2[1], cx1[2]+cx2[2] }, complex_meta ) return setmetatable( { cx1[1]+cx2[1], cx1[2]+cx2[2] }, complex_meta )
end end
-- complex.sub( cx1, cx2 ) -- complex.sub( cx1, cx2 )
-- subtract two numbers; cx1 - cx2 -- subtract two numbers; cx1 - cx2
function complex.sub( cx1,cx2 ) function complex.sub( cx1,cx2 )
return setmetatable( { cx1[1]-cx2[1], cx1[2]-cx2[2] }, complex_meta ) return setmetatable( { cx1[1]-cx2[1], cx1[2]-cx2[2] }, complex_meta )
end end
-- complex.mul( cx1, cx2 ) -- complex.mul( cx1, cx2 )
-- multiply two numbers; cx1 * cx2 -- multiply two numbers; cx1 * cx2
function complex.mul( cx1,cx2 ) function complex.mul( cx1,cx2 )
return setmetatable( { cx1[1]*cx2[1] - cx1[2]*cx2[2],cx1[1]*cx2[2] + cx1[2]*cx2[1] }, complex_meta ) return setmetatable( { cx1[1]*cx2[1] - cx1[2]*cx2[2],cx1[1]*cx2[2] + cx1[2]*cx2[1] }, complex_meta )
end end
-- complex.mulnum( cx, num ) -- complex.mulnum( cx, num )
-- multiply complex with number; cx1 * num -- multiply complex with number; cx1 * num
function complex.mulnum( cx,num ) function complex.mulnum( cx,num )
return setmetatable( { cx[1]*num,cx[2]*num }, complex_meta ) return setmetatable( { cx[1]*num,cx[2]*num }, complex_meta )
end end
-- complex.div( cx1, cx2 ) -- complex.div( cx1, cx2 )
-- divide 2 numbers; cx1 / cx2 -- divide 2 numbers; cx1 / cx2
function complex.div( cx1,cx2 ) function complex.div( cx1,cx2 )
-- get complex value -- get complex value
local val = cx2[1]^2 + cx2[2]^2 local val = cx2[1]^2 + cx2[2]^2
-- multiply cx1 with conjugate complex of cx2 and divide through val -- multiply cx1 with conjugate complex of cx2 and divide through val
return setmetatable( { (cx1[1]*cx2[1]+cx1[2]*cx2[2])/val,(cx1[2]*cx2[1]-cx1[1]*cx2[2])/val }, complex_meta ) return setmetatable( { (cx1[1]*cx2[1]+cx1[2]*cx2[2])/val,(cx1[2]*cx2[1]-cx1[1]*cx2[2])/val }, complex_meta )
end end
-- complex.divnum( cx, num ) -- complex.divnum( cx, num )
-- divide through a number -- divide through a number
function complex.divnum( cx,num ) function complex.divnum( cx,num )
return setmetatable( { cx[1]/num,cx[2]/num }, complex_meta ) return setmetatable( { cx[1]/num,cx[2]/num }, complex_meta )
end end
-- complex.pow( cx, num ) -- complex.pow( cx, num )
-- get the power of a complex number -- get the power of a complex number
function complex.pow( cx,num ) function complex.pow( cx,num )
if math.floor( num ) == num then if math.floor( num ) == num then
if num < 0 then if num < 0 then
local val = cx[1]^2 + cx[2]^2 local val = cx[1]^2 + cx[2]^2
cx = { cx[1]/val,-cx[2]/val } cx = { cx[1]/val,-cx[2]/val }
num = -num num = -num
end end
local real,imag = cx[1],cx[2] local real,imag = cx[1],cx[2]
for i = 2,num do for i = 2,num do
real,imag = real*cx[1] - imag*cx[2],real*cx[2] + imag*cx[1] real,imag = real*cx[1] - imag*cx[2],real*cx[2] + imag*cx[1]
end end
return setmetatable( { real,imag }, complex_meta ) return setmetatable( { real,imag }, complex_meta )
end end
-- we calculate the polar complex number now -- we calculate the polar complex number now
-- since then we have the versatility to calc any potenz of the complex number -- since then we have the versatility to calc any potenz of the complex number
-- then we convert it back to a carthesic complex number, we loose precision here -- then we convert it back to a carthesic complex number, we loose precision here
local length,phi = math.sqrt( cx[1]^2 + cx[2]^2 )^num, math.atan2( cx[2], cx[1] )*num local length,phi = math.sqrt( cx[1]^2 + cx[2]^2 )^num, math.atan2( cx[2], cx[1] )*num
return setmetatable( { length * math.cos( phi ), length * math.sin( phi ) }, complex_meta ) return setmetatable( { length * math.cos( phi ), length * math.sin( phi ) }, complex_meta )
end end
-- complex.sqrt( cx ) -- complex.sqrt( cx )
-- get the first squareroot of a complex number, more accurate than cx^.5 -- get the first squareroot of a complex number, more accurate than cx^.5
function complex.sqrt( cx ) function complex.sqrt( cx )
local len = math.sqrt( cx[1]^2+cx[2]^2 ) local len = math.sqrt( cx[1]^2+cx[2]^2 )
local sign = (cx[2]<0 and -1) or 1 local sign = (cx[2]<0 and -1) or 1
return setmetatable( { math.sqrt((cx[1]+len)/2), sign*math.sqrt((len-cx[1])/2) }, complex_meta ) return setmetatable( { math.sqrt((cx[1]+len)/2), sign*math.sqrt((len-cx[1])/2) }, complex_meta )
end end
-- complex.ln( cx ) -- complex.ln( cx )
-- natural logarithm of cx -- natural logarithm of cx
function complex.ln( cx ) function complex.ln( cx )
return setmetatable( { math.log(math.sqrt( cx[1]^2 + cx[2]^2 )), return setmetatable( { math.log(math.sqrt( cx[1]^2 + cx[2]^2 )),
math.atan2( cx[2], cx[1] ) }, complex_meta ) math.atan2( cx[2], cx[1] ) }, complex_meta )
end end
-- complex.exp( cx ) -- complex.exp( cx )
-- exponent of cx (e^cx) -- exponent of cx (e^cx)
function complex.exp( cx ) function complex.exp( cx )
local expreal = math.exp(cx[1]) local expreal = math.exp(cx[1])
return setmetatable( { expreal*math.cos(cx[2]), expreal*math.sin(cx[2]) }, complex_meta ) return setmetatable( { expreal*math.cos(cx[2]), expreal*math.sin(cx[2]) }, complex_meta )
end end
-- complex.conjugate( cx ) -- complex.conjugate( cx )
-- get conjugate complex of number -- get conjugate complex of number
function complex.conjugate( cx ) function complex.conjugate( cx )
return setmetatable( { cx[1], -cx[2] }, complex_meta ) return setmetatable( { cx[1], -cx[2] }, complex_meta )
end end
-- complex.round( cx [,idp] ) -- complex.round( cx [,idp] )
-- round complex numbers, by default to 0 decimal points -- round complex numbers, by default to 0 decimal points
function complex.round( cx,idp ) function complex.round( cx,idp )
local mult = 10^( idp or 0 ) local mult = 10^( idp or 0 )
return setmetatable( { math.floor( cx[1] * mult + 0.5 ) / mult, return setmetatable( { math.floor( cx[1] * mult + 0.5 ) / mult,
math.floor( cx[2] * mult + 0.5 ) / mult }, complex_meta ) math.floor( cx[2] * mult + 0.5 ) / mult }, complex_meta )
end end
--// metatable functions --// metatable functions
complex_meta.__add = function( cx1,cx2 ) complex_meta.__add = function( cx1,cx2 )
local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 ) local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 )
return complex.add( cx1,cx2 ) return complex.add( cx1,cx2 )
end end
complex_meta.__sub = function( cx1,cx2 ) complex_meta.__sub = function( cx1,cx2 )
local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 ) local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 )
return complex.sub( cx1,cx2 ) return complex.sub( cx1,cx2 )
end end
complex_meta.__mul = function( cx1,cx2 ) complex_meta.__mul = function( cx1,cx2 )
local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 ) local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 )
return complex.mul( cx1,cx2 ) return complex.mul( cx1,cx2 )
end end
complex_meta.__div = function( cx1,cx2 ) complex_meta.__div = function( cx1,cx2 )
local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 ) local cx1,cx2 = complex.to( cx1 ),complex.to( cx2 )
return complex.div( cx1,cx2 ) return complex.div( cx1,cx2 )
end end
complex_meta.__pow = function( cx,num ) complex_meta.__pow = function( cx,num )
if num == "*" then if num == "*" then
return complex.conjugate( cx ) return complex.conjugate( cx )
end end
return complex.pow( cx,num ) return complex.pow( cx,num )
end end
complex_meta.__unm = function( cx ) complex_meta.__unm = function( cx )
return setmetatable( { -cx[1], -cx[2] }, complex_meta ) return setmetatable( { -cx[1], -cx[2] }, complex_meta )
end end
complex_meta.__eq = function( cx1,cx2 ) complex_meta.__eq = function( cx1,cx2 )
if cx1[1] == cx2[1] and cx1[2] == cx2[2] then if cx1[1] == cx2[1] and cx1[2] == cx2[2] then
return true return true
end end
return false return false
end end
complex_meta.__tostring = function( cx ) complex_meta.__tostring = function( cx )
return tostring( complex.tostring( cx ) ) return tostring( complex.tostring( cx ) )
end end
complex_meta.__concat = function( cx,cx2 ) complex_meta.__concat = function( cx,cx2 )
return tostring(cx)..tostring(cx2) return tostring(cx)..tostring(cx2)
end end
-- cx( cx, formatstr ) -- cx( cx, formatstr )
complex_meta.__call = function( ... ) complex_meta.__call = function( ... )
print( complex.tostring( ... ) ) print( complex.tostring( ... ) )
end end
complex_meta.__index = {} complex_meta.__index = {}
for k,v in pairs( complex ) do for k,v in pairs( complex ) do
complex_meta.__index[k] = v complex_meta.__index[k] = v
end end
return complex return complex
--///////////////-- --///////////////--
--// chillcode //-- --// chillcode //--
--///////////////-- --///////////////--

View File

@ -1,55 +1,55 @@
complex changelog: complex changelog:
v 0.3.0: 2007-08-26 v 0.3.0: 2007-08-26
- fixed print function - fixed print function
- fixed call behaviour of complex number - fixed call behaviour of complex number
- __unm now directly alters the complex number instead of calling a complex function - __unm now directly alters the complex number instead of calling a complex function
- changed cmplx to imag (imaginary), for better understand of what is the real - changed cmplx to imag (imaginary), for better understand of what is the real
and what is the imaginary part and what is the imaginary part
- changed convpolar, to take as first argument the radius and second the angle - changed convpolar, to take as first argument the radius and second the angle
now both have to be given but is more conform to the polar function, now both have to be given but is more conform to the polar function,
that returns radius, phi that returns radius, phi
- updated test_complex.lua - updated test_complex.lua
v 0.2.9: 2007-08-13 v 0.2.9: 2007-08-13
- complex.tonumber is now complex.tostring, it will still return a number - complex.tonumber is now complex.tostring, it will still return a number
if it only has a real part, use tostring( cmplx ) to make sure it if it only has a real part, use tostring( cmplx ) to make sure it
always returns a string always returns a string
v 0.2.8: 2007-08-11 v 0.2.8: 2007-08-11
- metatable functions such as __add;__sub ... didn't return an error if it couldn't be calculated - metatable functions such as __add;__sub ... didn't return an error if it couldn't be calculated
now the complex.add function will return an error now the complex.add function will return an error
- topolar is not polar, and topolardeg is now polardeg - topolar is not polar, and topolardeg is now polardeg
- exp returns now e^(complexnumber) - exp returns now e^(complexnumber)
- convpolar returns polar coordinates as carthesic complex number - convpolar returns polar coordinates as carthesic complex number
- sqrt now calcs the sqrt of a complex number - sqrt now calcs the sqrt of a complex number
- added changelog file and *.zip - added changelog file and *.zip
v 0.2.7: v 0.2.7:
- optimised functions with ... - optimised functions with ...
- complex.len is now complex.abs - complex.len is now complex.abs
v 0.2.6 v 0.2.6
- optimised metatable functions - optimised metatable functions
- added __call behaviour, prints the complex number - added __call behaviour, prints the complex number
v 0.2.5 v 0.2.5
- added option formatstr in complex.tonumber - added option formatstr in complex.tonumber
- added __tostring, is the same as complex.tonumber, but it always returns a string - added __tostring, is the same as complex.tonumber, but it always returns a string
- added __concat so when one does "complex: "..cx, will do the right thing - added __concat so when one does "complex: "..cx, will do the right thing
doesn't work with table.concat unfortunatly doesn't work with table.concat unfortunatly
v 0.2.4 v 0.2.4
- changed to normal module loading via require rather than dofile - changed to normal module loading via require rather than dofile
e.g. "local complex = require "complex", if its on the call folder e.g. "local complex = require "complex", if its on the call folder
very good so one can decide for oneself to have complex global or local very good so one can decide for oneself to have complex global or local
- added license - added license
- changed function name tocomplex to complex.to - changed function name tocomplex to complex.to
v 0.2.3 v 0.2.3
- rewritten tocomplex, clear structure, can be used as 'if tocomplex( arg ) then' - rewritten tocomplex, clear structure, can be used as 'if tocomplex( arg ) then'
- added fast function complex.new( real,cmplx ), not invoking any checks - added fast function complex.new( real,cmplx ), not invoking any checks
v 0.2.2 v 0.2.2
- changed tocomplex, to that it only returns a complex table if the input is - changed tocomplex, to that it only returns a complex table if the input is
either a table holding 2 numbers as first elemenst or a number or a string either a table holding 2 numbers as first elemenst or a number or a string
representing a complex number as defined representing a complex number as defined
else it returns nil, so one can do "if tocomplex( arg ) then" else it returns nil, so one can do "if tocomplex( arg ) then"
v 0.2.1 added cx:set( real,complex ) to set real and complex v 0.2.1 added cx:set( real,complex ) to set real and complex
real,complex = cx:get() and cx:is(real,complex) real,complex = cx:get() and cx:is(real,complex)
built built

234
fit.lua
View File

@ -1,118 +1,118 @@
--///////////////////-- --///////////////////--
--// Curve Fitting //-- --// Curve Fitting //--
--///////////////////-- --///////////////////--
-- v 0.2 -- v 0.2
-- Lua 5.1 compatible -- Lua 5.1 compatible
-- little add-on to the matrix module, to show some curve fitting -- little add-on to the matrix module, to show some curve fitting
-- http://luaforge.net/projects/LuaMatrix -- http://luaforge.net/projects/LuaMatrix
-- http://lua-users.org/wiki/SimpleFit -- http://lua-users.org/wiki/SimpleFit
-- Licensed under the same terms as Lua itself. -- Licensed under the same terms as Lua itself.
-- requires matrix module -- requires matrix module
local matrix = require "matrix" local matrix = require "matrix"
-- The Fit Table -- The Fit Table
local fit = {} local fit = {}
-- Note all these Algos use the Gauss-Jordan Method to caculate equation systems -- Note all these Algos use the Gauss-Jordan Method to caculate equation systems
-- function to get the results -- function to get the results
local function getresults( mtx ) local function getresults( mtx )
assert( #mtx+1 == #mtx[1], "Cannot calculate Results" ) assert( #mtx+1 == #mtx[1], "Cannot calculate Results" )
mtx:dogauss() mtx:dogauss()
-- tresults -- tresults
local cols = #mtx[1] local cols = #mtx[1]
local tres = {} local tres = {}
for i = 1,#mtx do for i = 1,#mtx do
tres[i] = mtx[i][cols] tres[i] = mtx[i][cols]
end end
return unpack( tres ) return unpack( tres )
end end
-- fit.linear ( x_values, y_values ) -- fit.linear ( x_values, y_values )
-- fit a straight line -- fit a straight line
-- model ( y = a + b * x ) -- model ( y = a + b * x )
-- returns a, b -- returns a, b
function fit.linear( x_values,y_values ) function fit.linear( x_values,y_values )
-- x_values = { x1,x2,x3,...,xn } -- x_values = { x1,x2,x3,...,xn }
-- y_values = { y1,y2,y3,...,yn } -- y_values = { y1,y2,y3,...,yn }
-- values for A matrix -- values for A matrix
local a_vals = {} local a_vals = {}
-- values for Y vector -- values for Y vector
local y_vals = {} local y_vals = {}
for i,v in ipairs( x_values ) do for i,v in ipairs( x_values ) do
a_vals[i] = { 1, v } a_vals[i] = { 1, v }
y_vals[i] = { y_values[i] } y_vals[i] = { y_values[i] }
end end
-- create both Matrixes -- create both Matrixes
local A = matrix:new( a_vals ) local A = matrix:new( a_vals )
local Y = matrix:new( y_vals ) local Y = matrix:new( y_vals )
local ATA = matrix.mul( matrix.transpose(A), A ) local ATA = matrix.mul( matrix.transpose(A), A )
local ATY = matrix.mul( matrix.transpose(A), Y ) local ATY = matrix.mul( matrix.transpose(A), Y )
local ATAATY = matrix.concath(ATA,ATY) local ATAATY = matrix.concath(ATA,ATY)
return getresults( ATAATY ) return getresults( ATAATY )
end end
-- fit.parabola ( x_values, y_values ) -- fit.parabola ( x_values, y_values )
-- Fit a parabola -- Fit a parabola
-- model ( y = a + b * x + c * x² ) -- model ( y = a + b * x + c * x² )
-- returns a, b, c -- returns a, b, c
function fit.parabola( x_values,y_values ) function fit.parabola( x_values,y_values )
-- x_values = { x1,x2,x3,...,xn } -- x_values = { x1,x2,x3,...,xn }
-- y_values = { y1,y2,y3,...,yn } -- y_values = { y1,y2,y3,...,yn }
-- values for A matrix -- values for A matrix
local a_vals = {} local a_vals = {}
-- values for Y vector -- values for Y vector
local y_vals = {} local y_vals = {}
for i,v in ipairs( x_values ) do for i,v in ipairs( x_values ) do
a_vals[i] = { 1, v, v*v } a_vals[i] = { 1, v, v*v }
y_vals[i] = { y_values[i] } y_vals[i] = { y_values[i] }
end end
-- create both Matrixes -- create both Matrixes
local A = matrix:new( a_vals ) local A = matrix:new( a_vals )
local Y = matrix:new( y_vals ) local Y = matrix:new( y_vals )
local ATA = matrix.mul( matrix.transpose(A), A ) local ATA = matrix.mul( matrix.transpose(A), A )
local ATY = matrix.mul( matrix.transpose(A), Y ) local ATY = matrix.mul( matrix.transpose(A), Y )
local ATAATY = matrix.concath(ATA,ATY) local ATAATY = matrix.concath(ATA,ATY)
return getresults( ATAATY ) return getresults( ATAATY )
end end
-- fit.exponential ( x_values, y_values ) -- fit.exponential ( x_values, y_values )
-- Fit exponential -- Fit exponential
-- model ( y = a * x^b ) -- model ( y = a * x^b )
-- returns a, b -- returns a, b
function fit.exponential( x_values,y_values ) function fit.exponential( x_values,y_values )
-- convert to linear problem -- convert to linear problem
-- ln(y) = ln(a) + b * ln(x) -- ln(y) = ln(a) + b * ln(x)
for i,v in ipairs( x_values ) do for i,v in ipairs( x_values ) do
x_values[i] = math.log( v ) x_values[i] = math.log( v )
y_values[i] = math.log( y_values[i] ) y_values[i] = math.log( y_values[i] )
end end
local a,b = fit.linear( x_values,y_values ) local a,b = fit.linear( x_values,y_values )
return math.exp(a), b return math.exp(a), b
end end
return fit return fit
--///////////////-- --///////////////--
--// chillcode //-- --// chillcode //--
--///////////////-- --///////////////--

View File

@ -1,7 +1,7 @@
fit changelog: fit changelog:
v 0.2: 2007-08-26 v 0.2: 2007-08-26
- some optimising, for the input - some optimising, for the input
v 0.1: 2007-08-11 v 0.1: 2007-08-11
- built from former fit - built from former fit

2532
matrix.lua

File diff suppressed because it is too large Load Diff

View File

@ -1,160 +1,160 @@
matrix function list: matrix function list:
matrix.add matrix.add
matrix.columns matrix.columns
matrix.concath matrix.concath
matrix.concatv matrix.concatv
matrix.conjugate matrix.conjugate
matrix.copy matrix.copy
matrix.cross matrix.cross
matrix.det matrix.det
matrix.div matrix.div
matrix.divnum matrix.divnum
matrix.dogauss matrix.dogauss
matrix.getelement matrix.getelement
matrix.gsub matrix.gsub
matrix.invert matrix.invert
matrix.ipairs matrix.ipairs
matrix.latex matrix.latex
matrix.len matrix.len
matrix.mul matrix.mul
matrix.mulnum matrix.mulnum
matrix:new matrix:new
matrix.normf matrix.normf
matrix.normmax matrix.normmax
matrix.pow matrix.pow
matrix.print matrix.print
matrix.random matrix.random
matrix.remcomplex matrix.remcomplex
matrix.replace matrix.replace
matrix.root matrix.root
matrix.rotl matrix.rotl
matrix.rotr matrix.rotr
matrix.round matrix.round
matrix.rows matrix.rows
matrix.scalar matrix.scalar
matrix.setelement matrix.setelement
matrix.size matrix.size
matrix.solve matrix.solve
matrix.sqrt matrix.sqrt
matrix.sub matrix.sub
matrix.subm matrix.subm
matrix.tocomplex matrix.tocomplex
matrix.tostring matrix.tostring
matrix.tosymbol matrix.tosymbol
matrix.transpose matrix.transpose
matrix.type matrix.type
v 0.2.8: 2007-08-26 v 0.2.8: 2007-08-26
[ Michael Lutz ] [ Michael Lutz ]
- fixed rotr and rotl for rotating type 'complex','symbol' and 'tensor' - fixed rotr and rotl for rotating type 'complex','symbol' and 'tensor'
- mulscalar is now mulnum, divscalar is now divnum, mul/div a complex number or a string, - mulscalar is now mulnum, divscalar is now divnum, mul/div a complex number or a string,
strings first get checked if they can be converted to a complex number (what returns a strings first get checked if they can be converted to a complex number (what returns a
complex matrix) and if that fails they get converted to a symbol (what returns a symbol matrix) complex matrix) and if that fails they get converted to a symbol (what returns a symbol matrix)
- require "matrix" will return 'matrix, complex' just for convinience - require "matrix" will return 'matrix, complex' just for convinience
- matrix.size will now returns the correct size of tensors - matrix.size will now returns the correct size of tensors
- function matrix.div returns rank on failed invertion of m2 - function matrix.div returns rank on failed invertion of m2
- function matrix.det, was adjusted to better combine complex and number matrices - function matrix.det, was adjusted to better combine complex and number matrices
and made sure it finds the element nearest to 1 or -1 and made sure it finds the element nearest to 1 or -1
- function dogauss, was updated to handle complex and number matrices in one - function dogauss, was updated to handle complex and number matrices in one
- tweaked some utility functions, should speed up number matrices at least - tweaked some utility functions, should speed up number matrices at least
- updated matrix.latex to support all types of matrices - updated matrix.latex to support all types of matrices
- matrix.tostring can now also format the output, and was updated to handle all types better - matrix.tostring can now also format the output, and was updated to handle all types better
- matrix.print now just calls matrix.tostring - matrix.print now just calls matrix.tostring
- updated test_matrix.lua - updated test_matrix.lua
- added fit (curve fitting to LuaMatrix package) - added fit (curve fitting to LuaMatrix package)
[ David Manura ] [ David Manura ]
- tweaked matrix.sqrt and matrix.root function; - tweaked matrix.sqrt and matrix.root function;
replaced "dist1 > dist or dist1 == dist" with "dist1 >= dist" replaced "dist1 > dist or dist1 == dist" with "dist1 >= dist"
- tweaked get_abs_avg function - tweaked get_abs_avg function
- added function matrix.normf ( mtx ), returns the norm abs of a matrix - added function matrix.normf ( mtx ), returns the norm abs of a matrix
- added function matrix.normmax ( mtx ), returns the biggest abs(element) - added function matrix.normmax ( mtx ), returns the biggest abs(element)
- added __pow to symbol - added __pow to symbol
- added abs() and sqrt() to symbol - added abs() and sqrt() to symbol
- fixed some global variables, that were allocated - fixed some global variables, that were allocated
v 0.2.7: 2007-08-19 v 0.2.7: 2007-08-19
- added __div to metatable and the corresponding matrix functions( matrix.div(m1,m2); matrix.divscalar(m1,num) ) - added __div to metatable and the corresponding matrix functions( matrix.div(m1,m2); matrix.divscalar(m1,num) )
- updated square root function, now returns to the matrix the average error of the calculated to the original matrix - updated square root function, now returns to the matrix the average error of the calculated to the original matrix
- added matrix.root function (from David Manura/http://www.dm.unipi.it/~cortona04/slides/bruno.pdf) - added matrix.root function (from David Manura/http://www.dm.unipi.it/~cortona04/slides/bruno.pdf)
to calculate any root of a matrix, returns same values as matrix.sqrt to calculate any root of a matrix, returns same values as matrix.sqrt
- added function matrix.rotl and matrix.rotr, for rotate left and rotate right - added function matrix.rotl and matrix.rotr, for rotate left and rotate right
v 0.2.6: 2007-08-12 v 0.2.6: 2007-08-12
- added patch#5 from DavidManura, fixes symbolic matrices handling - added patch#5 from DavidManura, fixes symbolic matrices handling
- added sqrt function to function list, thx David for the hint, that some matrices don't convergent - added sqrt function to function list, thx David for the hint, that some matrices don't convergent
- added print function for rank3 tensors - added print function for rank3 tensors
- added solve function, for symbolic matrices, tries to solve a symbolic matrix so that is numeric again - added solve function, for symbolic matrices, tries to solve a symbolic matrix so that is numeric again
- tocomplex converts to a complex matrix, remcomplex removes the complex metatable and returns its - tocomplex converts to a complex matrix, remcomplex removes the complex metatable and returns its
string/number value string/number value
v 0.2.5: 2007-08-11 v 0.2.5: 2007-08-11
- added path#4 from DavidManura - added path#4 from DavidManura
It contains some doc updates, fixed handling mtx^-1 for singular matrices, It contains some doc updates, fixed handling mtx^-1 for singular matrices,
and a few checks that can be useful. and a few checks that can be useful.
- added setting up of a vector as matrix{1,2,3} - added setting up of a vector as matrix{1,2,3}
v 0.2.4 v 0.2.4
- added patch#3 from DavidManura, fixes negative exponent - added patch#3 from DavidManura, fixes negative exponent
- removed concat, added concath (concat horizontal) and concatv (concat vertical) - removed concat, added concath (concat horizontal) and concatv (concat vertical)
- removed get from all commands, all commands return a matrix even those only changing - removed get from all commands, all commands return a matrix even those only changing
the input matrix itself, except getelement and setelement the input matrix itself, except getelement and setelement
- submatrix is now subm, and dogaussjordan is now dogauss - submatrix is now subm, and dogaussjordan is now dogauss
- __tostring returns matrix.tostring, matrix.tostring returns a simple string with the matrix elements - __tostring returns matrix.tostring, matrix.tostring returns a simple string with the matrix elements
- __call; e.g. mtx(arg), will return matrix.print(mtx,arg) - __call; e.g. mtx(arg), will return matrix.print(mtx,arg)
- added function matrix.cross( v1,v2 ) to get the cross product of 2 matrices e.g. m1[3][1], m2[3][1] - added function matrix.cross( v1,v2 ) to get the cross product of 2 matrices e.g. m1[3][1], m2[3][1]
to get the scalar product of these you have to do m1:scalar( m2 ); to get the scalar product of these you have to do m1:scalar( m2 );
to create a vector do matrix{{ 1,2,3 }}^'T' to create a vector do matrix{{ 1,2,3 }}^'T'
v 0.2.3 v 0.2.3
- some optimising, in parts where complex and normal matrix are separate anyways - some optimising, in parts where complex and normal matrix are separate anyways
- added patch from DavidManura; matrix^0 returning the identitiy matrix, makes a lot sense - added patch from DavidManura; matrix^0 returning the identitiy matrix, makes a lot sense
print and printf merged, scalar multiply fixed, and __unm and __tostring added, 'good to know' print and printf merged, scalar multiply fixed, and __unm and __tostring added, 'good to know'
v 0.2.2 v 0.2.2
updated matrix function to suit new complex functions, function names updated matrix function to suit new complex functions, function names
should become more stable now should become more stable now
matrix can now be loaded via local matrix = require "matrix" matrix can now be loaded via local matrix = require "matrix"
or local matrix = dofile( "matrixfile" ), but require is better and faster or local matrix = dofile( "matrixfile" ), but require is better and faster
when loading multiple times when loading multiple times
v 0.2.1 v 0.2.1
updated matrix functions to suit new complex functions updated matrix functions to suit new complex functions
v 0.2.0 v 0.2.0
changed matrix functions to use the updated changed matrix functions to use the updated
complex number functions; makes a lot less code complex number functions; makes a lot less code
now complex and normal matrices share the same functions now complex and normal matrices share the same functions
one can add/sub/mul complex and normal matrices, returning a complex matrix one can add/sub/mul complex and normal matrices, returning a complex matrix
v 0.1.6 v 0.1.6
optimised functions a bit optimised functions a bit
changed matrix.getinv to matrix.invert changed matrix.getinv to matrix.invert
matrix:new is now matrix.new, 'matrix' should only provide functions matrix:new is now matrix.new, 'matrix' should only provide functions
added mtx = matrix( ... ); as matrix.new( ... ) added mtx = matrix( ... ); as matrix.new( ... )
matrix functions only return tables with metatable of first argument matrix matrix functions only return tables with metatable of first argument matrix
changed complex functions to changed complex functions to
matrix.c<func_name>; e.g. matirx.cadd; matrix.csub matrix.c<func_name>; e.g. matirx.cadd; matrix.csub
added: function matrix.cconjugate, returns the conjuagte complex matrix added: function matrix.cconjugate, returns the conjuagte complex matrix
v 0.1.5 v 0.1.5
written complex functions from normal matrices written complex functions from normal matrices
added metatable handling for overloading operators added metatable handling for overloading operators
v 0.1.4 v 0.1.4
added complex add on, to be able to handle added complex add on, to be able to handle
complex elements in the format declaired in 'complex' complex elements in the format declaired in 'complex'
v 0.1.3 v 0.1.3
added many functions also getdet and dogaussjordan added many functions also getdet and dogaussjordan
only defined one way to get the determinant, so we are only defined one way to get the determinant, so we are
slow here in certain cases where matrices have a triangle shape for exsample slow here in certain cases where matrices have a triangle shape for exsample
v 0.1.2 v 0.1.2
object returns mainly internal errors for lighter code, object returns mainly internal errors for lighter code,
structure should be no checks structure should be no checks
v 0.1.0 v 0.1.0
matrix matrix
structure of matrix m[i][j] structure of matrix m[i][j]
added simple operations +-.. added simple operations +-..

View File

@ -1,185 +1,185 @@
local complex = require "complex" local complex = require "complex"
local cx,cx1,cx2,re,im local cx,cx1,cx2,re,im
-- complex.to / complex call -- complex.to / complex call
cx = complex { 2,3 } cx = complex { 2,3 }
assert( tostring( cx ) == "2+3i" ) assert( tostring( cx ) == "2+3i" )
cx = complex ( 2 ) cx = complex ( 2 )
assert( tostring( cx ) == "2" ) assert( tostring( cx ) == "2" )
assert( cx:tostring() == 2 ) assert( cx:tostring() == 2 )
cx = complex "2^2+3/2i" cx = complex "2^2+3/2i"
assert( tostring( cx ) == "4+1.5i" ) assert( tostring( cx ) == "4+1.5i" )
cx = complex ".5-2E-3i" cx = complex ".5-2E-3i"
assert( tostring( cx ) == "0.5-0.002i" ) assert( tostring( cx ) == "0.5-0.002i" )
cx = complex "3i" cx = complex "3i"
assert( tostring( cx ) == "3i" ) assert( tostring( cx ) == "3i" )
cx = complex "2" cx = complex "2"
assert( tostring( cx ) == "2" ) assert( tostring( cx ) == "2" )
assert( cx:tostring() == 2 ) assert( cx:tostring() == 2 )
assert( complex "2 + 4i" == nil ) assert( complex "2 + 4i" == nil )
-- complex.new -- complex.new
cx = complex.new( 2,3 ) cx = complex.new( 2,3 )
assert( tostring( cx ) == "2+3i" ) assert( tostring( cx ) == "2+3i" )
-- complex.type -- complex.type
assert( complex.type( cx ) == "complex" ) assert( complex.type( cx ) == "complex" )
assert( complex.type( {} ) == nil ) assert( complex.type( {} ) == nil )
-- complex.convpolar( radius, phi ) -- complex.convpolar( radius, phi )
assert( complex.convpolar( 3, 0 ):round(10) == complex "3" ) assert( complex.convpolar( 3, 0 ):round(10) == complex "3" )
assert( complex.convpolar( 3, math.pi/2 ):round(10) == complex "3i" ) assert( complex.convpolar( 3, math.pi/2 ):round(10) == complex "3i" )
assert( complex.convpolar( 3, math.pi ):round(10) == complex "-3" ) assert( complex.convpolar( 3, math.pi ):round(10) == complex "-3" )
assert( complex.convpolar( 3, math.pi*3/2 ):round(10) == complex "-3i" ) assert( complex.convpolar( 3, math.pi*3/2 ):round(10) == complex "-3i" )
assert( complex.convpolar( 3, math.pi*2 ):round(10) == complex "3" ) assert( complex.convpolar( 3, math.pi*2 ):round(10) == complex "3" )
-- complex.convpolardeg( radius, phi ) -- complex.convpolardeg( radius, phi )
assert( complex.convpolardeg( 3, 0 ):round(10) == complex "3" ) assert( complex.convpolardeg( 3, 0 ):round(10) == complex "3" )
assert( complex.convpolardeg( 3, 90 ):round(10) == complex "3i" ) assert( complex.convpolardeg( 3, 90 ):round(10) == complex "3i" )
assert( complex.convpolardeg( 3, 180 ):round(10) == complex "-3" ) assert( complex.convpolardeg( 3, 180 ):round(10) == complex "-3" )
assert( complex.convpolardeg( 3, 270 ):round(10) == complex "-3i" ) assert( complex.convpolardeg( 3, 270 ):round(10) == complex "-3i" )
assert( complex.convpolardeg( 3, 360 ):round(10) == complex "3" ) assert( complex.convpolardeg( 3, 360 ):round(10) == complex "3" )
-- complex.tostring( cx,formatstr ) -- complex.tostring( cx,formatstr )
cx = complex "2+3i" cx = complex "2+3i"
assert( complex.tostring( cx ) == "2+3i" ) assert( complex.tostring( cx ) == "2+3i" )
assert( complex.tostring( cx, "%.2f" ) == "2.00+3.00i" ) assert( complex.tostring( cx, "%.2f" ) == "2.00+3.00i" )
-- does not support a second argument -- does not support a second argument
assert( tostring( cx, "%.2f" ) == "2+3i" ) assert( tostring( cx, "%.2f" ) == "2+3i" )
-- complex.polar( cx ) -- complex.polar( cx )
local r,phi = complex.polar( {3,0} ) local r,phi = complex.polar( {3,0} )
assert( r == 3 ) assert( r == 3 )
assert( phi == 0 ) assert( phi == 0 )
local r,phi = complex.polar( {0,3} ) local r,phi = complex.polar( {0,3} )
assert( r == 3 ) assert( r == 3 )
assert( phi == math.pi/2 ) assert( phi == math.pi/2 )
local r,phi = complex.polar( {-3,0} ) local r,phi = complex.polar( {-3,0} )
assert( r == 3 ) assert( r == 3 )
assert( phi == math.pi ) assert( phi == math.pi )
local r,phi = complex.polar( {0,-3} ) local r,phi = complex.polar( {0,-3} )
assert( r == 3 ) assert( r == 3 )
assert( phi == -math.pi/2 ) assert( phi == -math.pi/2 )
-- complex.polardeg( cx ) -- complex.polardeg( cx )
local r,phi = complex.polardeg( {3,0} ) local r,phi = complex.polardeg( {3,0} )
assert( r == 3 ) assert( r == 3 )
assert( phi == 0 ) assert( phi == 0 )
local r,phi = complex.polardeg( {0,3} ) local r,phi = complex.polardeg( {0,3} )
assert( r == 3 ) assert( r == 3 )
assert( phi == 90 ) assert( phi == 90 )
local r,phi = complex.polardeg( {-3,0} ) local r,phi = complex.polardeg( {-3,0} )
assert( r == 3 ) assert( r == 3 )
assert( phi == 180 ) assert( phi == 180 )
local r,phi = complex.polardeg( {0,-3} ) local r,phi = complex.polardeg( {0,-3} )
assert( r == 3 ) assert( r == 3 )
assert( phi == -90 ) assert( phi == -90 )
-- complex.mulconjugate( cx ) -- complex.mulconjugate( cx )
cx = complex "2+3i" cx = complex "2+3i"
assert( complex.mulconjugate( cx ) == 13 ) assert( complex.mulconjugate( cx ) == 13 )
-- complex.abs( cx ) -- complex.abs( cx )
cx = complex "3+4i" cx = complex "3+4i"
assert( complex.abs( cx ) == 5 ) assert( complex.abs( cx ) == 5 )
-- complex.get( cx ) -- complex.get( cx )
cx = complex "2+3i" cx = complex "2+3i"
re,im = complex.get( cx ) re,im = complex.get( cx )
assert( re == 2 ) assert( re == 2 )
assert( im == 3 ) assert( im == 3 )
-- complex.set( cx, re, im ) -- complex.set( cx, re, im )
cx = complex "2+3i" cx = complex "2+3i"
complex.set( cx, 3, 2 ) complex.set( cx, 3, 2 )
assert( cx == complex "3+2i" ) assert( cx == complex "3+2i" )
-- complex.is( cx, re, im ) -- complex.is( cx, re, im )
cx = complex "2+3i" cx = complex "2+3i"
assert( complex.is( cx, 2, 3 ) == true ) assert( complex.is( cx, 2, 3 ) == true )
assert( complex.is( cx, 3, 2 ) == false ) assert( complex.is( cx, 3, 2 ) == false )
-- complex.copy( cx ) -- complex.copy( cx )
cx = complex "2+3i" cx = complex "2+3i"
cx1 = complex.copy( cx ) cx1 = complex.copy( cx )
complex.set( cx, 1, 1 ) complex.set( cx, 1, 1 )
assert( cx1 == complex "2+3i" ) assert( cx1 == complex "2+3i" )
-- complex.add( cx1, cx2 ) -- complex.add( cx1, cx2 )
cx1 = complex "2+3i" cx1 = complex "2+3i"
cx2 = complex "3+2i" cx2 = complex "3+2i"
assert( complex.add(cx1,cx2) == complex "5+5i" ) assert( complex.add(cx1,cx2) == complex "5+5i" )
-- complex.sub( cx1, cx2 ) -- complex.sub( cx1, cx2 )
cx1 = complex "2+3i" cx1 = complex "2+3i"
cx2 = complex "3+2i" cx2 = complex "3+2i"
assert( complex.sub(cx1,cx2) == complex "-1+1i" ) assert( complex.sub(cx1,cx2) == complex "-1+1i" )
-- complex.mul( cx1, cx2 ) -- complex.mul( cx1, cx2 )
cx1 = complex "2+3i" cx1 = complex "2+3i"
cx2 = complex "3+2i" cx2 = complex "3+2i"
assert( complex.mul(cx1,cx2) == complex "13i" ) assert( complex.mul(cx1,cx2) == complex "13i" )
-- complex.mulnum( cx, num ) -- complex.mulnum( cx, num )
cx = complex "2+3i" cx = complex "2+3i"
assert( complex.mulnum( cx, 2 ) == complex "4+6i" ) assert( complex.mulnum( cx, 2 ) == complex "4+6i" )
-- complex.div( cx1, cx2 ) -- complex.div( cx1, cx2 )
cx1 = complex "2+3i" cx1 = complex "2+3i"
cx2 = complex "3-2i" cx2 = complex "3-2i"
assert( complex.div(cx1,cx2) == complex "i" ) assert( complex.div(cx1,cx2) == complex "i" )
-- complex.divnum( cx, num ) -- complex.divnum( cx, num )
cx = complex "2+3i" cx = complex "2+3i"
assert( complex.divnum( cx, 2 ) == complex "1+1.5i" ) assert( complex.divnum( cx, 2 ) == complex "1+1.5i" )
-- complex.pow( cx, num ) -- complex.pow( cx, num )
cx = complex "2+3i" cx = complex "2+3i"
assert( complex.pow( cx, 3 ) == complex "-46+9i" ) assert( complex.pow( cx, 3 ) == complex "-46+9i" )
cx = complex( -121 ) cx = complex( -121 )
cx = cx^.5 cx = cx^.5
-- we have to round here due to the polar calculation of the squareroot -- we have to round here due to the polar calculation of the squareroot
cx = cx:round( 10 ) cx = cx:round( 10 )
assert( cx == complex "11i" ) assert( cx == complex "11i" )
cx = complex"2+3i" cx = complex"2+3i"
assert( cx^-2 ~= 1/cx^2 ) assert( cx^-2 ~= 1/cx^2 )
assert( cx^-2 == (cx^-1)^2 ) assert( cx^-2 == (cx^-1)^2 )
assert( tostring( cx^-2 ) == tostring( 1/cx^2 ) ) assert( tostring( cx^-2 ) == tostring( 1/cx^2 ) )
-- complex.sqrt( cx ) -- complex.sqrt( cx )
cx = complex( -121 ) cx = complex( -121 )
assert( complex.sqrt( cx ) == complex "11i" ) assert( complex.sqrt( cx ) == complex "11i" )
cx = complex "2-3i" cx = complex "2-3i"
cx = cx^2 cx = cx^2
assert( cx:sqrt() == complex "2-3i" ) assert( cx:sqrt() == complex "2-3i" )
-- complex.ln( cx ) -- complex.ln( cx )
cx = complex "3+4i" cx = complex "3+4i"
assert( cx:ln():round( 4 ) == complex "1.6094+0.9273i" ) assert( cx:ln():round( 4 ) == complex "1.6094+0.9273i" )
-- complex.exp( cx ) -- complex.exp( cx )
cx = complex "2+3i" cx = complex "2+3i"
assert( cx:ln():exp() == complex "2+3i" ) assert( cx:ln():exp() == complex "2+3i" )
-- complex.conjugate( cx ) -- complex.conjugate( cx )
cx = complex "2+3i" cx = complex "2+3i"
assert( cx:conjugate() == complex "2-3i" ) assert( cx:conjugate() == complex "2-3i" )
-- metatable -- metatable
-- __add -- __add
cx = complex "2+3i" cx = complex "2+3i"
assert( cx+2 == complex "4+3i" ) assert( cx+2 == complex "4+3i" )
-- __unm -- __unm
cx = complex "2+3i" cx = complex "2+3i"
assert( -cx == complex "-2-3i" ) assert( -cx == complex "-2-3i" )

View File

@ -1,22 +1,22 @@
-- require fit -- require fit
local fit = require "fit" local fit = require "fit"
print( "Fit a straight line " ) print( "Fit a straight line " )
-- x(i) = 2 | 3 | 4 | 5 -- x(i) = 2 | 3 | 4 | 5
-- y(i) = 5 | 9 | 15 | 21 -- y(i) = 5 | 9 | 15 | 21
-- model = y = a + b * x -- model = y = a + b * x
-- r(i) = y(i) - ( a + b * x(i) ) -- r(i) = y(i) - ( a + b * x(i) )
local a,b = fit.linear( { 2,3, 4, 5 }, local a,b = fit.linear( { 2,3, 4, 5 },
{ 5,9,15,21 } ) { 5,9,15,21 } )
print( "=> y = ( "..a.." ) + ( "..b.." ) * x") print( "=> y = ( "..a.." ) + ( "..b.." ) * x")
print( "Fit a parabola " ) print( "Fit a parabola " )
local a, b, c = fit.parabola( { 0,1,2,4,6 }, local a, b, c = fit.parabola( { 0,1,2,4,6 },
{ 3,1,0,1,4 } ) { 3,1,0,1,4 } )
print( "=> y = ( "..a.." ) + ( "..b.." ) * x + ( "..c.." ) * x²") print( "=> y = ( "..a.." ) + ( "..b.." ) * x + ( "..c.." ) * x²")
print( "Fit exponential" ) print( "Fit exponential" )
local a, b = fit.exponential( {1, 2, 3, 4, 5}, local a, b = fit.exponential( {1, 2, 3, 4, 5},
{1,3.1,5.6,9.1,12.9} ) {1,3.1,5.6,9.1,12.9} )
print( "=> y = ( "..a.." ) * x^( "..b.." )") print( "=> y = ( "..a.." ) * x^( "..b.." )")

View File

@ -1,258 +1,258 @@
local matrix, complex = require "matrix" local matrix, complex = require "matrix"
local mtx, m1,m2,m3,m4,m5, ms,ms1,ms2,ms3,ms4 local mtx, m1,m2,m3,m4,m5, ms,ms1,ms2,ms3,ms4
-- test matrix:new/matrix call function -- test matrix:new/matrix call function
-- normal matrix -- normal matrix
mtx = matrix {{1,2},{3,4}} mtx = matrix {{1,2},{3,4}}
assert( tostring(mtx) == "1\t2\n3\t4" ) assert( tostring(mtx) == "1\t2\n3\t4" )
-- vector -- vector
mtx = matrix {1,2,3} mtx = matrix {1,2,3}
assert( tostring(mtx) == "1\n2\n3" ) assert( tostring(mtx) == "1\n2\n3" )
-- matrix with size 2x2 -- matrix with size 2x2
mtx = matrix (2,2) mtx = matrix (2,2)
assert( tostring(mtx) == "0\t0\n0\t0" ) assert( tostring(mtx) == "0\t0\n0\t0" )
-- matrix with size 2x2 and default value 1/3 -- matrix with size 2x2 and default value 1/3
mtx = matrix (2,2,1/3) mtx = matrix (2,2,1/3)
assert( tostring(mtx) == "0.33333333333333\t0.33333333333333\n0.33333333333333\t0.33333333333333" ) assert( tostring(mtx) == "0.33333333333333\t0.33333333333333\n0.33333333333333\t0.33333333333333" )
-- identity matrix with size 2x2 -- identity matrix with size 2x2
mtx = matrix (2,"I") mtx = matrix (2,"I")
assert( tostring(mtx) == "1\t0\n0\t1" ) assert( tostring(mtx) == "1\t0\n0\t1" )
-- matrix.add; number -- matrix.add; number
m1 = matrix{{8,4,1},{6,8,3}} m1 = matrix{{8,4,1},{6,8,3}}
m2 = matrix{{-8,1,3},{5,2,1}} m2 = matrix{{-8,1,3},{5,2,1}}
assert(m1 + m2 == matrix{{0,5,4},{11,10,4}}) assert(m1 + m2 == matrix{{0,5,4},{11,10,4}})
-- matrix.add; complex -- matrix.add; complex
m1 = matrix{{10,"2+6i",1},{5,1,"4-2i"}}:tocomplex() m1 = matrix{{10,"2+6i",1},{5,1,"4-2i"}}:tocomplex()
m2 = matrix{{3,4,5},{"2+3i",4,"6i"}}:tocomplex() m2 = matrix{{3,4,5},{"2+3i",4,"6i"}}:tocomplex()
assert(m1 + m2 == matrix{{13,"6+6i",6},{"7+3i",5,"4+4i"}}:tocomplex()) assert(m1 + m2 == matrix{{13,"6+6i",6},{"7+3i",5,"4+4i"}}:tocomplex())
-- matrix.add; symbol -- matrix.add; symbol
m1 = matrix{{8,4,1},{6,8,3}}:tosymbol() m1 = matrix{{8,4,1},{6,8,3}}:tosymbol()
m2 = matrix{{-8,1,3},{5,2,1}}:tosymbol() m2 = matrix{{-8,1,3},{5,2,1}}:tosymbol()
assert(m1 + m2 == matrix{{"8+-8","4+1","1+3"},{"6+5","8+2","3+1"}}:tosymbol()) assert(m1 + m2 == matrix{{"8+-8","4+1","1+3"},{"6+5","8+2","3+1"}}:tosymbol())
-- matrix.sub; number -- matrix.sub; number
m1 = matrix{{8,4,1},{6,8,3}} m1 = matrix{{8,4,1},{6,8,3}}
m2 = matrix{{-8,1,3},{5,2,1}} m2 = matrix{{-8,1,3},{5,2,1}}
assert(m1 - m2 == matrix{{16,3,-2},{1,6,2}}) assert(m1 - m2 == matrix{{16,3,-2},{1,6,2}})
-- matrix.sub; complex -- matrix.sub; complex
m1 = matrix{{10,"2+6i",1},{5,1,"4-2i"}}:tocomplex() m1 = matrix{{10,"2+6i",1},{5,1,"4-2i"}}:tocomplex()
m2 = matrix{{3,4,5},{"2+3i",4,"6i"}}:tocomplex() m2 = matrix{{3,4,5},{"2+3i",4,"6i"}}:tocomplex()
assert(m1 - m2 == matrix{{7,"-2+6i",-4},{"3-3i",-3,"4-8i"}}:tocomplex()) assert(m1 - m2 == matrix{{7,"-2+6i",-4},{"3-3i",-3,"4-8i"}}:tocomplex())
-- matrix.sub; symbol -- matrix.sub; symbol
m1 = matrix{{8,4,1},{6,8,3}}:tosymbol() m1 = matrix{{8,4,1},{6,8,3}}:tosymbol()
m2 = matrix{{-8,1,3},{5,2,1}}:tosymbol() m2 = matrix{{-8,1,3},{5,2,1}}:tosymbol()
assert(m1 - m2 == matrix{{"8--8","4-1","1-3"},{"6-5","8-2","3-1"}}:tosymbol()) assert(m1 - m2 == matrix{{"8--8","4-1","1-3"},{"6-5","8-2","3-1"}}:tosymbol())
-- matrix.mul; number -- matrix.mul; number
m1 = matrix{{8,4,1},{6,8,3}} m1 = matrix{{8,4,1},{6,8,3}}
m2 = matrix{{3,1},{2,5},{7,4}} m2 = matrix{{3,1},{2,5},{7,4}}
assert(m1 * m2 == matrix{{39,32},{55,58}}) assert(m1 * m2 == matrix{{39,32},{55,58}})
-- matrix.mul; complex -- matrix.mul; complex
m1 = matrix{{"1+2i","3-i"},{"2-2i","1+i"}}:tocomplex() m1 = matrix{{"1+2i","3-i"},{"2-2i","1+i"}}:tocomplex()
m2 = matrix{{"i","5-i"},{2,"1-i"}}:tocomplex() m2 = matrix{{"i","5-i"},{2,"1-i"}}:tocomplex()
assert( m1*m2 == matrix{{"4-i","9+5i"},{"4+4i","10-12i"}}:tocomplex() ) assert( m1*m2 == matrix{{"4-i","9+5i"},{"4+4i","10-12i"}}:tocomplex() )
-- matrix.mul; symbol -- matrix.mul; symbol
m1 = matrix{{8,4,1},{6,8,3}}:tosymbol() m1 = matrix{{8,4,1},{6,8,3}}:tosymbol()
m2 = matrix{{3,1},{2,5},{7,4}}:tosymbol() m2 = matrix{{3,1},{2,5},{7,4}}:tosymbol()
assert(m1 * m2 == matrix{ assert(m1 * m2 == matrix{
{"(8)*(3)+(4)*(2)+(1)*(7)", "(8)*(1)+(4)*(5)+(1)*(4)"}, {"(8)*(3)+(4)*(2)+(1)*(7)", "(8)*(1)+(4)*(5)+(1)*(4)"},
{"(6)*(3)+(8)*(2)+(3)*(7)", "(6)*(1)+(8)*(5)+(3)*(4)"} {"(6)*(3)+(8)*(2)+(3)*(7)", "(6)*(1)+(8)*(5)+(3)*(4)"}
}:tosymbol()) }:tosymbol())
-- matrix.div; number, same for complex, not for symbol -- matrix.div; number, same for complex, not for symbol
m1 = matrix {{1,2},{3,4}} m1 = matrix {{1,2},{3,4}}
m2 = matrix {{4,5},{6,7}} m2 = matrix {{4,5},{6,7}}
assert( m1*m2^-1 == m1/m2 ) assert( m1*m2^-1 == m1/m2 )
-- matrix.divnum; number, same complex -- matrix.divnum; number, same complex
m2 = matrix {{4,5},{6,7}} m2 = matrix {{4,5},{6,7}}
assert( m2/2 == matrix{{2,2.5},{3,3.5}} ) assert( m2/2 == matrix{{2,2.5},{3,3.5}} )
mtx = matrix {{3,5,1},{2,4,5},{1,2,2}} mtx = matrix {{3,5,1},{2,4,5},{1,2,2}}
assert( 2 / mtx == matrix{{4,16,-42},{-2,-10,26},{0,2,-4}} ) assert( 2 / mtx == matrix{{4,16,-42},{-2,-10,26},{0,2,-4}} )
-- matrix.mulnum; symbol -- matrix.mulnum; symbol
m1 = m1:tosymbol() m1 = m1:tosymbol()
assert( m1*2 == matrix{{"(1)*(2)","(2)*(2)"},{"(3)*(2)","(4)*(2)"}}:tosymbol() ) assert( m1*2 == matrix{{"(1)*(2)","(2)*(2)"},{"(3)*(2)","(4)*(2)"}}:tosymbol() )
assert( m1/2 == matrix{{"(1)/(2)","(2)/(2)"},{"(3)/(2)","(4)/(2)"}}:tosymbol() ) assert( m1/2 == matrix{{"(1)/(2)","(2)/(2)"},{"(3)/(2)","(4)/(2)"}}:tosymbol() )
-- matrix.pow; number, same complex -- matrix.pow; number, same complex
mtx = matrix{{3,5,1},{2,4,5},{1,2,2}} mtx = matrix{{3,5,1},{2,4,5},{1,2,2}}
assert(mtx^3 == matrix{{164,308,265},{161,303,263},{76,143,124}}) assert(mtx^3 == matrix{{164,308,265},{161,303,263},{76,143,124}})
assert(mtx^1 == mtx) assert(mtx^1 == mtx)
assert(mtx^0 == matrix{{1,0,0},{0,1,0},{0,0,1}} ) assert(mtx^0 == matrix{{1,0,0},{0,1,0},{0,0,1}} )
assert(mtx^-1 == mtx:invert()) assert(mtx^-1 == mtx:invert())
assert(mtx^-3 == (mtx^-1)^3) assert(mtx^-3 == (mtx^-1)^3)
mtx = matrix{{1,2,3},{1,2,3},{3,2,1}} -- singular mtx = matrix{{1,2,3},{1,2,3},{3,2,1}} -- singular
assert(mtx^-1 == nil) assert(mtx^-1 == nil)
local m1,rank = mtx:invert(); assert(m1 == nil and rank == 2) local m1,rank = mtx:invert(); assert(m1 == nil and rank == 2)
mtx = matrix{{1,2},{3,4},{5,6}} -- non-square mtx = matrix{{1,2},{3,4},{5,6}} -- non-square
assert(select(2, pcall(function() return mtx^-1 end)) assert(select(2, pcall(function() return mtx^-1 end))
:find("matrix not square")) :find("matrix not square"))
-- matrix.det; number -- matrix.det; number
mtx = matrix {{1,4,3,2},{2,1,-1,-1},{-3,2,2,-2},{-1,-5,-4,1}} mtx = matrix {{1,4,3,2},{2,1,-1,-1},{-3,2,2,-2},{-1,-5,-4,1}}
assert( mtx:det() == 78 ) assert( mtx:det() == 78 )
-- matrix.det; complex -- matrix.det; complex
m1 = matrix{{"1+2i","3-i"},{"2-2i","1+i"}}:tocomplex() m1 = matrix{{"1+2i","3-i"},{"2-2i","1+i"}}:tocomplex()
m2 = matrix{{"i","5-i"},{2,"1-i"}}:tocomplex() m2 = matrix{{"i","5-i"},{2,"1-i"}}:tocomplex()
m3 = m1*m2 m3 = m1*m2
-- (checked in maple) -- (checked in maple)
assert( m3:det() == complex "12-114i" ) assert( m3:det() == complex "12-114i" )
mtx = {{"2+3i","1+4i","-2i",3,2}, mtx = {{"2+3i","1+4i","-2i",3,2},
{"2i",3,"2+3i",0,3}, {"2i",3,"2+3i",0,3},
{3,"-2i",6,"4+5i",0}, {3,"-2i",6,"4+5i",0},
{1,"1+2i",3,5,7}, {1,"1+2i",3,5,7},
{"-3+3i","3+3i",3,-8,2}} {"-3+3i","3+3i",3,-8,2}}
matrix(mtx):tocomplex() matrix(mtx):tocomplex()
-- (checked in maple) -- (checked in maple)
assert( mtx:det():round(10) == complex "5527+2687i" ) assert( mtx:det():round(10) == complex "5527+2687i" )
-- matrix.invert; number -- matrix.invert; number
--1 --1
mtx = matrix{{3,5,1},{2,4,5},{1,2,2}} mtx = matrix{{3,5,1},{2,4,5},{1,2,2}}
local mtxinv = matrix{{2,8,-21},{-1,-5,13},{0,1,-2}} local mtxinv = matrix{{2,8,-21},{-1,-5,13},{0,1,-2}}
assert( mtx^-1 == mtxinv ) assert( mtx^-1 == mtxinv )
--2 --2
mtx = matrix{{1,0,2},{4,1,1},{3,2,-7}} mtx = matrix{{1,0,2},{4,1,1},{3,2,-7}}
local mtxinv = matrix{{-9,4,-2},{31,-13,7},{5,-2,1}} local mtxinv = matrix{{-9,4,-2},{31,-13,7},{5,-2,1}}
assert( mtx^-1 == mtxinv ) assert( mtx^-1 == mtxinv )
-- matrix.invert; complex -- matrix.invert; complex
mtx = { mtx = {
{ 3,"4-3i",1}, { 3,"4-3i",1},
{3,"-1+5i",-3}, {3,"-1+5i",-3},
{4,0,7}, {4,0,7},
} }
matrix.tocomplex( mtx ) matrix.tocomplex( mtx )
local mtxinv = mtx^-1 local mtxinv = mtx^-1
local mtxinvcomp = { local mtxinvcomp = {
{"0.13349-0.07005i","0.14335+0.03609i","0.04237+0.02547i"}, {"0.13349-0.07005i","0.14335+0.03609i","0.04237+0.02547i"},
{"0.08771+0.10832i","-0.04519-0.0558i","-0.0319-0.03939i"}, {"0.08771+0.10832i","-0.04519-0.0558i","-0.0319-0.03939i"},
{"-0.07628+0.04003i","-0.08192-0.02062i","0.11865-0.01456i"},} {"-0.07628+0.04003i","-0.08192-0.02062i","0.11865-0.01456i"},}
mtxinvcomp = matrix( mtxinvcomp ) mtxinvcomp = matrix( mtxinvcomp )
mtxinv:round( 5 ) mtxinv:round( 5 )
mtxinv:remcomplex() mtxinv:remcomplex()
assert( mtxinvcomp == mtxinv ) assert( mtxinvcomp == mtxinv )
-- matrix.sqrt; number -- matrix.sqrt; number
local m1 = matrix{{4,2,1},{1,5,4},{1,5,2}} local m1 = matrix{{4,2,1},{1,5,4},{1,5,2}}
local m2 = m1*m1 local m2 = m1*m1
local msqrt = m2:sqrt() local msqrt = m2:sqrt()
assert((m2 - msqrt^2):normmax() < 1E-12) assert((m2 - msqrt^2):normmax() < 1E-12)
-- matrix.sqrt; complex -- matrix.sqrt; complex
local m1 = matrix{{4,"2+i",1},{1,5,"4-2i"},{1,"5+3i",2}}:tocomplex() local m1 = matrix{{4,"2+i",1},{1,5,"4-2i"},{1,"5+3i",2}}:tocomplex()
local m2 = m1*m1 local m2 = m1*m1
local msqrt = m2:sqrt() local msqrt = m2:sqrt()
assert((m2 - msqrt^2):normmax() < 1E-12) assert((m2 - msqrt^2):normmax() < 1E-12)
-- matrix.root; number -- matrix.root; number
local p = 3 local p = 3
local m1 = matrix {{4,2,3},{1,9,7},{6,5,8}} local m1 = matrix {{4,2,3},{1,9,7},{6,5,8}}
local m2 = m1^p local m2 = m1^p
local mroot = m2:root(p) local mroot = m2:root(p)
assert((m2 - mroot^p):normmax() < 1E-7) assert((m2 - mroot^p):normmax() < 1E-7)
-- matrix.root; complex -- matrix.root; complex
local m1 = matrix{{4,"2+i",1},{1,5,"4-2i"},{1,"5+3i",2}}:tocomplex() local m1 = matrix{{4,"2+i",1},{1,5,"4-2i"},{1,"5+3i",2}}:tocomplex()
local m2 = m1^p local m2 = m1^p
local mroot = m2:root(p) local mroot = m2:root(p)
assert((m2 - mroot^p):normmax() < 1E-7) assert((m2 - mroot^p):normmax() < 1E-7)
-- matrix.normf -- matrix.normf
mtx = matrix{{2,3},{-2,-3}} mtx = matrix{{2,3},{-2,-3}}
assert(mtx:normf() == math.sqrt(2^2+3^2+2^2+3^2)) assert(mtx:normf() == math.sqrt(2^2+3^2+2^2+3^2))
mtx = matrix{{'2i','3'},{'-2i','-3'}}:tocomplex() mtx = matrix{{'2i','3'},{'-2i','-3'}}:tocomplex()
assert(mtx:normf() == math.sqrt(2^2+3^2+2^2+3^2)) assert(mtx:normf() == math.sqrt(2^2+3^2+2^2+3^2))
mtx = matrix{{'a','b'},{'c','d'}}:tosymbol() mtx = matrix{{'a','b'},{'c','d'}}:tosymbol()
assert(tostring(mtx:normf()) == "(0+((a):abs())^(2)+((b):abs())^(2)+((c):abs())^(2)+((d):abs())^(2)):sqrt()") assert(tostring(mtx:normf()) == "(0+((a):abs())^(2)+((b):abs())^(2)+((c):abs())^(2)+((d):abs())^(2)):sqrt()")
-- matrix.normmax -- matrix.normmax
-- note: symbolic matrices not supported -- note: symbolic matrices not supported
mtx = matrix{{2,3},{-2,-4}} mtx = matrix{{2,3},{-2,-4}}
assert(mtx:normmax() == 4) assert(mtx:normmax() == 4)
mtx = matrix{{'2i','3'},{'-2i','-4i'}}:tocomplex() mtx = matrix{{'2i','3'},{'-2i','-4i'}}:tocomplex()
assert(mtx:normmax() == 4) assert(mtx:normmax() == 4)
-- matrix.transpose -- matrix.transpose
-- test transpose; number, same for all others -- test transpose; number, same for all others
mtx = matrix{{3,5,1},{2,4,5},{1,2,2}} mtx = matrix{{3,5,1},{2,4,5},{1,2,2}}
assert(mtx^'T' == matrix{{3,2,1},{5,4,2},{1,5,2}}) assert(mtx^'T' == matrix{{3,2,1},{5,4,2},{1,5,2}})
-- matrix.rotl; number, same for all others -- matrix.rotl; number, same for all others
local m1 = matrix{{2,3},{4,5},{6,7}} local m1 = matrix{{2,3},{4,5},{6,7}}
assert( m1:rotl() == matrix{{3,5,7},{2,4,6}} ) assert( m1:rotl() == matrix{{3,5,7},{2,4,6}} )
-- matris.rotr; number, same for all others -- matris.rotr; number, same for all others
assert( m1:rotr() == matrix{{6,4,2},{7,5,3}} ) assert( m1:rotr() == matrix{{6,4,2},{7,5,3}} )
-- matrix.tostring; number -- matrix.tostring; number
mtx = matrix{{4,2,-3},{3,-5,2}} mtx = matrix{{4,2,-3},{3,-5,2}}
assert(tostring(mtx) == "4\t2\t-3\n3\t-5\t2" ) assert(tostring(mtx) == "4\t2\t-3\n3\t-5\t2" )
-- matrix.tostring; complex -- matrix.tostring; complex
mtx = matrix{{4,"2+i"},{"3-4i",5}}:tocomplex() mtx = matrix{{4,"2+i"},{"3-4i",5}}:tocomplex()
assert(tostring(mtx) == "4\t2+i\n3-4i\t5" ) assert(tostring(mtx) == "4\t2+i\n3-4i\t5" )
-- matrix.tostring; tensor -- matrix.tostring; tensor
local mt = matrix {{{1,2},{3,4}},{{5,6},{7,8}}} local mt = matrix {{{1,2},{3,4}},{{5,6},{7,8}}}
assert( tostring(mt) == "[1,2]\t[3,4]\n[5,6]\t[7,8]" ) assert( tostring(mt) == "[1,2]\t[3,4]\n[5,6]\t[7,8]" )
local i,j,k = mt:size() local i,j,k = mt:size()
assert( i == 2 ); assert( j == 2 );assert( k == 2 ) assert( i == 2 ); assert( j == 2 );assert( k == 2 )
-- matrix.latex; tensor -- matrix.latex; tensor
local mt = matrix {{{1,2},{3,4}},{{5,6},{7,8}}} local mt = matrix {{{1,2},{3,4}},{{5,6},{7,8}}}
assert( mt:latex() == "$\\left( \\begin{array}{cc}\n\t[1,2] & [3,4] \\\\\n\t[5,6] & [7,8]\n\\end{array} \\right)$" ) assert( mt:latex() == "$\\left( \\begin{array}{cc}\n\t[1,2] & [3,4] \\\\\n\t[5,6] & [7,8]\n\\end{array} \\right)$" )
-- matrix.cross -- matrix.cross
local e1 = matrix{ 1,0,0 } local e1 = matrix{ 1,0,0 }
local e2 = matrix{ 0,1,0 } local e2 = matrix{ 0,1,0 }
local e3 = e1:cross( e2 ) local e3 = e1:cross( e2 )
assert( e3 == matrix{ 0,0,1 } ) assert( e3 == matrix{ 0,0,1 } )
-- matrix.scalar -- matrix.scalar
local v1 = matrix{ 2,3,0, } local v1 = matrix{ 2,3,0, }
local v2 = matrix{ 0,3,4 } local v2 = matrix{ 0,3,4 }
local vx = v1:cross( v2 ) local vx = v1:cross( v2 )
assert( v1:scalar( vx ) == 0 ) assert( v1:scalar( vx ) == 0 )
assert( vx:scalar( v2 ) == 0 ) assert( vx:scalar( v2 ) == 0 )
-- matrix.len -- matrix.len
assert( v2:len() == math.sqrt( 3^2+4^2 ) ) assert( v2:len() == math.sqrt( 3^2+4^2 ) )
--// test symbolic --// test symbolic
ms = matrix {{ "a",1 },{2,"b"}}:tosymbol() ms = matrix {{ "a",1 },{2,"b"}}:tosymbol()
ms2 = matrix {{ "a",2 },{"b",3}}:tosymbol() ms2 = matrix {{ "a",2 },{"b",3}}:tosymbol()
ms3 = ms2+ms ms3 = ms2+ms
ms3 = ms3:replace( "a",4,"b",2 ) ms3 = ms3:replace( "a",4,"b",2 )
ms3 = ms3:solve() ms3 = ms3:solve()
assert( ms3 == matrix {{8,3},{4,5}} ) assert( ms3 == matrix {{8,3},{4,5}} )
ms4 = ms2*ms ms4 = ms2*ms
ms4 = ms4:replace( "a",4,"b",2 ) ms4 = ms4:replace( "a",4,"b",2 )
ms4 = ms4:solve() ms4 = ms4:solve()
assert( ms4 == matrix {{20,8},{14,8}} ) assert( ms4 == matrix {{20,8},{14,8}} )
-- __unm -- __unm
mtx = matrix{{4,2},{3,5}} mtx = matrix{{4,2},{3,5}}
assert(-mtx == matrix{{-4,-2},{-3,-5}}) assert(-mtx == matrix{{-4,-2},{-3,-5}})
-- test inverted with big table -- test inverted with big table
--[[mtx = matrix:new( 100,100 ) --[[mtx = matrix:new( 100,100 )
mtx:random( -100,100 ) mtx:random( -100,100 )
--mtx:print() --mtx:print()
t1 = os.clock() t1 = os.clock()
identm = mtx*mtx^-1 identm = mtx*mtx^-1
print("Diff:",os.clock()-t1 ) print("Diff:",os.clock()-t1 )
-- round to 8 decimal points -- round to 8 decimal points
-- this depends on the numbers used, small, big, range -- this depends on the numbers used, small, big, range
-- the average error in this calculation was 10^-9 -- the average error in this calculation was 10^-9
identm:round( 8 ) identm:round( 8 )
--identm:print() --identm:print()
ident = matrix:new( 100, "I" ) ident = matrix:new( 100, "I" )
assert( identm == ident )--]] assert( identm == ident )--]]
local t = {} local t = {}
for i,v in pairs( matrix ) do for i,v in pairs( matrix ) do
table.insert( t, i ) table.insert( t, i )
end end
table.sort( t ) table.sort( t )
for i,v in ipairs( t ) do for i,v in ipairs( t ) do
--print( "matrix."..v ) --print( "matrix."..v )
end end