---++!! !commonlib.mathlib %TOC{title="Contents:"}% %STARTINCLUDE% ---++ math lib funcions | *Title* | math lib funcions | | *Author(s)* | LiXizhi | | *Date* | 2007/10/18 | | *File* | script/ide/mathlib.lua | ---+++ Description %T% __Sample Code__ <verbatim> NPL.load("(gl)script/ide/mathlib.lua"); local q1 = mathlib.QuatFromAxisAngle(0,1,0,3.14) local q2 = mathlib.QuatFromAxisAngle(0,1,0,-3.14) commonlib.echo(mathlib.QuaternionMultiply(q1,q2)) </verbatim> ---+++ Member Functions ---++++ !mathlib.QuatToEuler Conversion Quaternion to Euler * _param_ __q1__ : {x,y,z,w} * _returns_ ____ : heading, attitude, bank * _note_ ____ : code converted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm __syntax__ <verbatim>function mathlib.QuatToEuler(q1) </verbatim> __parameters__ | *q1* | {x,y,z,w} | ---++++ !mathlib.EulerToQuat Conversion Euler to Quaternion * _param_ __heading__ :, attitude, bank * _returns_ ____ : x,y,z,w __syntax__ <verbatim>function mathlib.EulerToQuat(heading, attitude, bank) </verbatim> __parameters__ | *heading* | , attitude, bank | | *attitude* | | | *bank* | | ---++++ !mathlib.QuatFromAxisAngle assumes axis is already normalised * _param_ __x__ :,y,z: is a normalized axis vector * _param_ __angle__ : is the angle to rotate __syntax__ <verbatim>function mathlib.QuatFromAxisAngle(x,y,z, angle) </verbatim> __parameters__ | *x* | ,y,z: is a normalized axis vector | | *y* | | | *z* | | | *angle* | | ---++++ !mathlib.QuaternionMultiply Since a unit quaternion represents an orientation in 3D space, the multiplication of two unit quaternions will result in another unit quaternion that represents the combined rotation. Amazing, but it's true. see: http://www.cprogramming.com/tutorial/3d/quaternions.html * _param_ __q1__ :,q2: q1 and q2 are two quaternion{x,y,z,w} __syntax__ <verbatim>function mathlib.QuaternionMultiply(q1,q2)</verbatim> __parameters__ | *q1* | ,q2: q1 and q2 are two quaternion{x,y,z,w} | | *q2* | | ---++ math lib funcions | *Title* | math lib funcions | | *Author(s)* | http://www.dialectronics.com/Lua/, see below, ported to NPL by LXZ | | *Date* | 2008/4/22 | | *File* | script/ide/math/bit.lua | ---+++ Description %T% __Sample Code__ <verbatim> NPL.load("(gl)script/ide/math/bit.lua"); The following is fast and implemented in C++ </verbatim> ---++ math lib funcions | *Title* | math lib funcions | | *Author(s)* | http://luaforge.net/projects/LuaMatrix, see below, ported to NPL by LXZ | | *Date* | 2008/4/22 | | *File* | script/ide/math/complex.lua | ---+++ Description provides common tasks with complex numbers %T% __Sample Code__ <verbatim> NPL.load("(gl)script/ide/math/complex.lua"); mathlib.complex </verbatim> ---+++ Member Functions ---++++ !complex.to complex 0.3.0 Lua 5.1 'complex' provides common tasks with complex numbers function complex.to( arg ); complex( arg ) returns a complex number on success, nil on failure 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" note: 'i' is always in the numerator, spaces are not allowed a complex number is defined as carthesic complex number complex number := { real_part, imaginary_part } this gives fast access to both parts of the number for calculation 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 http://luaforge.net/projects/LuaMatrix http://lua-users.org/wiki/ComplexNumbers Licensed under the same terms as Lua itself. /////////////-- // complex //-- /////////////-- link to complex table if(not mathlib) then mathlib={}; end if(not mathlib.complex) then mathlib.complex = {} end local complex = mathlib.complex; link to complex metatable local complex_meta = {} complex.to( arg ) return a complex number on success return nil on failure local _retone = function() return 1 end local _retminusone = function() return -1 end __syntax__ <verbatim>function complex.to( num )</verbatim> __parameters__ | *num* | | ---++++ !complex.new complex( arg ) same as complex.to( arg ) set __call behaviour of complex setmetatable( complex, { __call = function( _,num ) return complex.to( num ) end } ) complex.new( real, complex ) fast function to get a complex number, not invoking any checks __syntax__ <verbatim>function complex.new( ... )</verbatim> ---++++ !complex.type complex.type( arg ) is argument of type complex __syntax__ <verbatim>function complex.type( arg )</verbatim> __parameters__ | *arg* | | ---++++ !complex.convpolar complex.convpolar( r, phi ) convert polar coordinates ( r*e^(i*phi) ) to carthesic complex number r (radius) is a number phi (angle) must be in radians; e.g. [0 - 2pi] __syntax__ <verbatim>function complex.convpolar( radius, phi )</verbatim> __parameters__ | *radius* | | | *phi* | | ---++++ !complex.tostring complex.convpolardeg( r, phi ) convert polar coordinates ( r*e^(i*phi) ) to carthesic complex number r (radius) is a number phi must be in degrees; e.g. [0?- 360鐧? function complex.convpolardeg( radius, phi ) phi = phi/180 * math.pi return setmetatable( { radius * math.cos( phi ), radius * math.sin( phi ) }, complex_meta ) end // complex number functions only complex.tostring( cx [, formatstr] ) to string or real number takes a complex number and returns its string value or real number value __syntax__ <verbatim>function complex.tostring( cx,formatstr )</verbatim> __parameters__ | *cx* | | | *formatstr* | | ---++++ !complex.print complex.print( cx [, formatstr] ) print a complex number __syntax__ <verbatim>function complex.print( ... )</verbatim> ---++++ !complex.polar complex.polar( cx ) from complex number to polar coordinates output in radians; [-pi,+pi] returns r (radius), phi (angle) __syntax__ <verbatim>function complex.polar( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.polardeg complex.polardeg( cx ) from complex number to polar coordinates output in degrees; [-180?180鐧? -- returns r (radius), phi (angle) __syntax__ <verbatim>function complex.polardeg( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.mulconjugate complex.mulconjugate( cx ) multiply with conjugate, function returning a number __syntax__ <verbatim>function complex.mulconjugate( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.abs complex.abs( cx ) get the absolute value of a complex number __syntax__ <verbatim>function complex.abs( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.get complex.get( cx ) returns real_part, imaginary_part __syntax__ <verbatim>function complex.get( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.set complex.set( cx, real, imag ) sets real_part = real and imaginary_part = imag __syntax__ <verbatim>function complex.set( cx,real,imag )</verbatim> __parameters__ | *cx* | | | *real* | | | *imag* | | ---++++ !complex.is complex.is( cx, real, imag ) returns true if, real_part = real and imaginary_part = imag else returns false __syntax__ <verbatim>function complex.is( cx,real,imag )</verbatim> __parameters__ | *cx* | | | *real* | | | *imag* | | ---++++ !complex.copy // functions returning a new complex number complex.copy( cx ) copy complex number __syntax__ <verbatim>function complex.copy( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.add complex.add( cx1, cx2 ) add two numbers; cx1 + cx2 __syntax__ <verbatim>function complex.add( cx1,cx2 )</verbatim> __parameters__ | *cx1* | | | *cx2* | | ---++++ !complex.sub complex.sub( cx1, cx2 ) subtract two numbers; cx1 - cx2 __syntax__ <verbatim>function complex.sub( cx1,cx2 )</verbatim> __parameters__ | *cx1* | | | *cx2* | | ---++++ !complex.mul complex.mul( cx1, cx2 ) multiply two numbers; cx1 * cx2 __syntax__ <verbatim>function complex.mul( cx1,cx2 )</verbatim> __parameters__ | *cx1* | | | *cx2* | | ---++++ !complex.mulnum complex.mulnum( cx, num ) multiply complex with number; cx1 * num __syntax__ <verbatim>function complex.mulnum( cx,num )</verbatim> __parameters__ | *cx* | | | *num* | | ---++++ !complex.div complex.div( cx1, cx2 ) divide 2 numbers; cx1 / cx2 __syntax__ <verbatim>function complex.div( cx1,cx2 )</verbatim> __parameters__ | *cx1* | | | *cx2* | | ---++++ !complex.divnum complex.divnum( cx, num ) divide through a number __syntax__ <verbatim>function complex.divnum( cx,num )</verbatim> __parameters__ | *cx* | | | *num* | | ---++++ !complex.pow complex.pow( cx, num ) get the power of a complex number __syntax__ <verbatim>function complex.pow( cx,num )</verbatim> __parameters__ | *cx* | | | *num* | | ---++++ !complex.sqrt complex.sqrt( cx ) get the first squareroot of a complex number, more accurate than cx^.5 __syntax__ <verbatim>function complex.sqrt( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.ln complex.ln( cx ) natural logarithm of cx __syntax__ <verbatim>function complex.ln( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.exp complex.exp( cx ) exponent of cx (e^cx) __syntax__ <verbatim>function complex.exp( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.conjugate complex.conjugate( cx ) get conjugate complex of number __syntax__ <verbatim>function complex.conjugate( cx )</verbatim> __parameters__ | *cx* | | ---++++ !complex.round complex.round( cx [,idp] ) round complex numbers, by default to 0 decimal points __syntax__ <verbatim>function complex.round( cx,idp )</verbatim> __parameters__ | *cx* | | | *idp* | | ---++ 3d math funcions | *Title* | 3d math funcions | | *Author(s)* | LiXizhi | | *Date* | 2008/12/20 | | *File* | script/ide/math/math3d.lua | ---+++ Description a collection of standalone and frequently used 3d math functions, such as vector rotation, etc. %T% __Sample Code__ <verbatim> NPL.load("(gl)script/ide/math/math3d.lua"); print(mathlib.math3d.vec3Rotate(1,0,0, 0,1.57,0)) print(mathlib.math3d.vec3RotateByPoint(1000,0,0, 1001,0,0, 0,3.14,0)) </verbatim> ---+++ Member Functions ---++++ !math3d.vec3Rotate rotation a vector, around the X, then Y, then Z axis by the given radian. e.g. print(mathlib.math3d.vec3Rotate(1,0,0, 0,1.57,0)) * _param_ __X__ :, Y, Z: a point in 3D * _param_ __a__ :,b,c: radian around the X, Y, Z axis, such as 0, 1.57, 0 * _return_ __x__ :,y,z: the rotated vector __syntax__ <verbatim>function math3d.vec3Rotate(X, Y, Z, a, b, c)</verbatim> __parameters__ | *X* | , Y, Z: a point in 3D | | *Y* | | | *Z* | | | *a* | | | *b* | | | *c* | | | *return* | ,y,z: the rotated vector | ---++++ !math3d.vec3RotateByPoint rotate input vector3 around a given point. * _param_ __ox__ :, oy, oz: around which point to rotate the input. * _param_ __X__ :, Y, Z: the input point in 3D * _param_ __a__ :,b,c: radian around the X, Y, Z axis, such as 0, 1.57, 0 * _return_ __x__ :,y,z: the rotated vector __syntax__ <verbatim>function math3d.vec3RotateByPoint(ox, oy, oz, X, Y, Z, a, b, c)</verbatim> __parameters__ | *ox* | , oy, oz: around which point to rotate the input. | | *oy* | | | *oz* | | | *X* | | | *Y* | | | *Z* | | | *a* | ,b,c: radian around the X, Y, Z axis, such as 0, 1.57, 0 | | *b* | | | *c* | | ---++ math lib funcions | *Title* | math lib funcions | | *Author(s)* | http://luaforge.net/projects/LuaMatrix, see below, ported to NPL by LXZ | | *Date* | 2008/4/22 | | *File* | script/ide/math/fit.lua | ---+++ Description %T% __Sample Code__ <verbatim> NPL.load("(gl)script/ide/math/fit.lua"); mathlib.fit </verbatim> ---+++ Member Functions ---++++ !fit.linear v 0.2 Lua 5.1 compatible little add-on to the matrix module, to show some curve fitting http://luaforge.net/projects/LuaMatrix http://lua-users.org/wiki/SimpleFit Licensed under the same terms as Lua itself. The Fit Table requires matrix module NPL.load("(gl)script/ide/math/matrix.lua"); if(not mathlib) then mathlib={}; end if(not mathlib.matrix) then mathlib.matrix = {} end if(not mathlib.complex) then mathlib.complex = {} end if(not mathlib.fit) then mathlib.fit = {} end local matrix = mathlib.matrix; local fit = mathlib.fit; Note all these Algos use the Gauss-Jordan Method to caculate equation systems function to get the results local function getresults( mtx ) assert( #mtx+1 == #mtx[1], "Cannot calculate Results" ) mtx:dogauss() -- tresults local cols = #mtx[1] local tres = {} for i = 1,#mtx do tres[i] = mtx[i][cols] end return unpack( tres ) end fit.linear ( x_values, y_values ) fit a straight line model ( y = a + b * x ) returns a, b __syntax__ <verbatim>function fit.linear( x_values,y_values )</verbatim> __parameters__ | *x* | | | *values* | | | *y* | | | *values* | | ---++++ !fit.parabola fit.parabola ( x_values, y_values ) Fit a parabola model ( y = a + b * x + c * x?) returns a, b, c __syntax__ <verbatim>function fit.parabola( x_values,y_values )</verbatim> __parameters__ | *x* | | | *values* | | | *y* | | | *values* | | ---++++ !fit.exponential fit.exponential ( x_values, y_values ) Fit exponential model ( y = a * x^b ) returns a, b __syntax__ <verbatim>function fit.exponential( x_values,y_values )</verbatim> __parameters__ | *x* | | | *values* | | | *y* | | | *values* | | ---++ math lib funcions | *Title* | math lib funcions | | *Author(s)* | http://luaforge.net/projects/LuaMatrix, see below, ported to NPL by LXZ | | *Date* | 2008/4/22 | | *File* | script/ide/math/matrix.lua | ---+++ Description %T% __Sample Code__ <verbatim> NPL.load("(gl)script/ide/math/matrix.lua"); mathlib.matrix </verbatim> ---+++ Member Functions ---++++ !matrix:new [[ matrix v 0.2.8 Lua 5.1 compatible 'matrix' provides a good selection of matrix functions. With simple matrices this script is quite useful, though for more exact calculations, one would probably use a program like Matlab instead. Matrices of size 100x100 can still be handled very well. The error for the determinant and the inverted matrix is around 10^-9 with a 100x100 matrix and an element range from -100 to 100. Characteristics: - functions called via matrix.<function> should be able to handle any table matrix of structure t[i][j] = value - can handle a type of complex matrix - can handle symbolic matrices. (Symbolic matrices cannot be used with complex matrices.) - arithmetic functions do not change the matrix itself but build and return a new matrix - functions are intended to be light on checks since one gets a Lua error on incorrect use anyways - uses mainly Gauss-Jordan elimination - for Lua tables optimised determinant calculation (fast) but not invoking any checks for special types of matrices - vectors can be set up via vec1 = matrix{{ 1,2,3 }}^'T' or matrix{1,2,3} - vectors can be multiplied scalar via num = vec1^'T' * vec2 where num will be a matrix with the result in mtx[1][1], or use num = vec1:scalar( vec2 ), where num is a number Sites: http://luaforge.net/projects/LuaMatrix http://lua-users.org/wiki/SimpleMatrix Licensed under the same terms as Lua itself. Developers: Michael Lutz (chillcode) David Manura http://lua-users.org/wiki/DavidManura ]]-- for speed and clearer code load the complex function table in there we define the complex number //////////// // matrix // //////////// NPL.load("(gl)script/ide/math/complex.lua"); if(not mathlib) then mathlib={}; end if(not mathlib.matrix) then mathlib.matrix = {} end if(not mathlib.complex) then mathlib.complex = {} end if(not mathlib.fit) then mathlib.fit = {} end local matrix = mathlib.matrix; local complex = mathlib.complex; access to the metatable we set at the end of the file local matrix_meta = {} access to the symbolic metatable local symbol_meta = {}; symbol_meta.__index = symbol_meta set up a symbol type local function newsymbol(o) return setmetatable({tostring(o)}, symbol_meta) end ///////////////////////////// // Get 'new' matrix object // ///////////////////////////// // matrix:new ( rows [, comlumns [, value]] ) if rows is a table then sets rows as matrix if rows is a table of structure {1,2,3} then it sets it as a vector matrix if rows and columns are given and are numbers, returns a matrix with size rowsxcolumns if num is given then returns a matrix with given size and all values set to num if rows is given as number and columns is "I", will return an identity matrix of size rowsxrows __syntax__ <verbatim>function matrix:new( rows, columns, value )</verbatim> __parameters__ | *rows* | | | *columns* | | | *value* | | ---++++ !matrix.add // matrix ( rows [, comlumns [, value]] ) set __call behaviour of matrix for matrix( ... ) as matrix.new( ... ) setmetatable( matrix, { __call = function(...) return matrix.new(...) end } ) functions are designed to be light on checks so we get Lua errors instead on wrong input matrix.<functions> should handle any table of structure t[i][j] = value we always return a matrix with scripts metatable cause its faster than setmetatable( mtx, getmetatable( input matrix ) ) /////////////////////////////// // matrix 'matrix' functions // /////////////////////////////// // for real, complx and symbolic matrices //-- note: real and complex matrices may be added, subtracted, etc. real and symbolic matrices may also be added, subtracted, etc. but one should avoid using symbolic matrices with complex ones since it is not clear which metatable then is used // matrix.add ( m1, m2 ) Add 2 matrices; m2 may be of bigger size than m1 __syntax__ <verbatim>function matrix.add( m1, m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.sub // matrix.sub ( m1 ,m2 ) Subtract 2 matrices; m2 may be of bigger size than m1 __syntax__ <verbatim>function matrix.sub( m1, m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.mul // matrix.mul ( m1, m2 ) Multiply 2 matrices; m1 columns must be equal to m2 rows e.g. #m1[1] == #m2 __syntax__ <verbatim>function matrix.mul( m1, m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.div // matrix.div ( m1, m2 ) Divide 2 matrices; m1 columns must be equal to m2 rows m2 must be square, to be inverted, if that fails returns the rank of m2 as second argument e.g. #m1[1] == #m2; #m2 == #m2[1] __syntax__ <verbatim>function matrix.div( m1, m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.mulnum // matrix.mulnum ( m1, num ) Multiply matrix with a number num may be of type 'number','complex number' or 'string' strings get converted to complex number, if that fails then to symbol __syntax__ <verbatim>function matrix.mulnum( m1, num )</verbatim> __parameters__ | *m1* | | | *num* | | ---++++ !matrix.divnum // matrix.divnum ( m1, num ) Divide matrix by a number num may be of type 'number','complex number' or 'string' strings get converted to complex number, if that fails then to symbol __syntax__ <verbatim>function matrix.divnum( m1, num )</verbatim> __parameters__ | *m1* | | | *num* | | ---++++ !matrix.pow // for real and complex matrices only //-- // matrix.pow ( m1, num ) Power of matrix; mtx^(num) num is an integer and may be negative m1 has to be square if num is negative and inverting m1 fails returns the rank of matrix m1 as second argument __syntax__ <verbatim>function matrix.pow( m1, num )</verbatim> __parameters__ | *m1* | | | *num* | | ---++++ !matrix.det // matrix.det ( m1 ) Calculate the determinant of a matrix m1 needs to be square Can calc the det for symbolic matrices up to 3x3 too The function to calculate matrices bigger 3x3 is quite fast and for matrices of medium size ~(100x100) and average values quite accurate here we try to get the nearest element to |1|, (smallest pivot element) os that usually we have |mtx[i][j]/subdet| > 1 or mtx[i][j]; with complex matrices we use the complex.abs function to check if it is bigger or smaller local fiszerocomplex = function( cx ) return complex.is(cx,0,0) end local fiszeronumber = function( num ) return num == 0 end __syntax__ <verbatim>function matrix.det( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.dogauss // matrix.dogauss ( mtx ) Gauss elimination, Gauss-Jordan Method this function changes the matrix itself returns on success: true, returns on failure: false,'rank of matrix' locals checking here for the nearest element to 1 or -1; (smallest pivot element) this way the factor of the evolving number division should be > 1 or the divided number itself, what gives better results local setelementtosmallest = function( mtx,i,j,fiszero,fisone,abs ) -- check if element is one if fisone(mtx[i][j]) then return true end -- check for lowest value local _ilow for _i = i,#mtx do local e = mtx[_i][j] if fisone(e) then break end if not _ilow then if not fiszero(e) then _ilow = _i end elseif (not fiszero(e)) and math.abs(abs(e)-1) < math.abs(abs(mtx[_ilow][j])-1) then _ilow = _i end end if _ilow then -- switch lines if not input line -- legal operation if _ilow ~= i then mtx[i],mtx[_ilow] = mtx[_ilow],mtx[i] end return true end end local cxfiszero = function( cx ) return complex.is(cx,0,0) end local cxfsetzero = function( mtx,i,j ) complex.set(mtx[i][j],0,0) end local cxfisone = function( cx ) return complex.abs(cx) == 1 end local cxfsetone = function( mtx,i,j ) complex.set(mtx[i][j],1,0) end local numfiszero = function( num ) return num == 0 end local numfsetzero = function( mtx,i,j ) mtx[i][j] = 0 end local numfisone = function( num ) return math.abs(num) == 1 end local numfsetone = function( mtx,i,j ) mtx[i][j] = 1 end note: in --// ... //-- we have a way that does no divison, however with big number and matrices we get problems since we do no reducing __syntax__ <verbatim>function matrix.dogauss( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.invert // matrix.invert ( m1 ) Get the inverted matrix or m1 matrix must be square and not singular on success: returns inverted matrix on failure: returns nil,'rank of matrix' __syntax__ <verbatim>function matrix.invert( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.sqrt // matrix.sqrt ( m1 [,iters] ) calculate the square root of a matrix using "Denman鏈唀avers square root iteration" condition: matrix rows == matrix columns; must have a invers matrix and a square root if called without additional arguments, the function finds the first nearest square root to input matrix, there are others but the error between them is very small if called with agument iters, the function will return the matrix by number of iterations the script returns: as first argument, matrix^.5 as second argument, matrix^-.5 as third argument, the average error between (matrix^.5)^2-inputmatrix you have to determin for yourself if the result is sufficent enough for you local average error local function get_abs_avg( m1, m2 ) local dist = 0 local abs = matrix.type(m1) == "complex" and complex.abs or math.abs for i=1,#m1 do for j=1,#m1[1] do dist = dist + abs(m1[i][j]-m2[i][j]) end end -- norm by numbers of entries return dist/(#m1*2) end square root function __syntax__ <verbatim>function matrix.sqrt( m1, iters )</verbatim> __parameters__ | *m1* | | | *iters* | | ---++++ !matrix.root // matrix.root ( m1, root [,iters] ) calculate any root of a matrix source: http://www.dm.unipi.it/~cortona04/slides/bruno.pdf m1 and root have to be given;(m1 = matrix, root = number) conditions same as matrix.sqrt returns same values as matrix.sqrt __syntax__ <verbatim>function matrix.root( m1, root, iters )</verbatim> __parameters__ | *m1* | | | *root* | | | *iters* | | ---++++ !matrix.normf // Norm functions //-- // matrix.normf ( mtx ) calculates the Frobenius norm of the matrix. ||mtx||_F = sqrt(SUM_{i,j} |a_{i,j}|^2) http://en.wikipedia.org/wiki/Frobenius_norm#Frobenius_norm __syntax__ <verbatim>function matrix.normf(mtx)</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.normmax // matrix.normmax ( mtx ) calculates the max norm of the matrix. ||mtx||_{max} = max{|a_{i,j}|} Does not work with symbolic matrices http://en.wikipedia.org/wiki/Frobenius_norm#Max_norm __syntax__ <verbatim>function matrix.normmax(mtx)</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.round // only for number and complex type //-- Functions changing the matrix itself // matrix.round ( mtx [, idp] ) perform round on elements local numround = function( num,mult ) return math.floor( num * mult + 0.5 ) / mult end local tround = function( t,mult ) for i,v in ipairs(t) do t[i] = math.floor( v * mult + 0.5 ) / mult end return t end __syntax__ <verbatim>function matrix.round( mtx, idp )</verbatim> __parameters__ | *mtx* | | | *idp* | | ---++++ !matrix.random // matrix.random( mtx [,start] [, stop] [, idip] ) fillmatrix with random values local numfill = function( _,start,stop,idp ) return math.random( start,stop ) / idp end local tfill = function( t,start,stop,idp ) for i in ipairs(t) do t[i] = math.random( start,stop ) / idp end return t end __syntax__ <verbatim>function matrix.random( mtx,start,stop,idp )</verbatim> __parameters__ | *mtx* | | | *start* | | | *stop* | | | *idp* | | ---++++ !matrix.type ////////////////////////////// // Object Utility Functions // ////////////////////////////// // for all types and matrices //-- // matrix.type ( mtx ) get type of matrix, normal/complex/symbol or tensor __syntax__ <verbatim>function matrix.type( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.copy // matrix.copy ( m1 ) Copy a matrix simple copy, one can write other functions oneself __syntax__ <verbatim>function matrix.copy( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.transpose // matrix.transpose ( m1 ) Transpose a matrix switch rows and columns __syntax__ <verbatim>function matrix.transpose( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.subm // matrix.subm ( m1, i1, j1, i2, j2 ) Submatrix out of a matrix input: i1,j1,i2,j2 i1,j1 are the start element i2,j2 are the end element condition: i1,j1,i2,j2 are elements of the matrix __syntax__ <verbatim>function matrix.subm( m1,i1,j1,i2,j2 )</verbatim> __parameters__ | *m1* | | | *i1* | | | *j1* | | | *i2* | | | *j2* | | ---++++ !matrix.concath // matrix.concath( m1, m2 ) Concatenate 2 matrices, horizontal will return m1m2; rows have to be the same e.g.: #m1 == #m2 __syntax__ <verbatim>function matrix.concath( m1,m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.concatv // matrix.concatv ( m1, m2 ) Concatenate 2 matrices, vertical will return m1 m2 columns have to be the same; e.g.: #m1[1] == #m2[1] __syntax__ <verbatim>function matrix.concatv( m1,m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.rotl // matrix.rotl ( m1 ) Rotate Left, 90 degrees __syntax__ <verbatim>function matrix.rotl( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.rotr // matrix.rotr ( m1 ) Rotate Right, 90 degrees __syntax__ <verbatim>function matrix.rotr( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.tostring local get_elemnts in string local get_tstr = function( t ) return "["..table.concat(t,",").."]" end local get_str = function( e ) return tostring(e) end local get_elemnts in string and formated local getf_tstr = function( t,fstr ) local tval = {} for i,v in ipairs( t ) do tval[i] = string.format( fstr,v ) end return "["..table.concat(tval,",").."]" end local getf_cxstr = function( e,fstr ) return complex.tostring( e,fstr ) end local getf_symstr = function( e,fstr ) return string.format( fstr,e[1] ) end local getf_str = function( e,fstr ) return string.format( fstr,e ) end // matrix.tostring ( mtx, formatstr ) tostring function __syntax__ <verbatim>function matrix.tostring( mtx, formatstr )</verbatim> __parameters__ | *mtx* | | | *formatstr* | | ---++++ !matrix.print // matrix.print ( mtx [, formatstr] ) print out the matrix, just calls tostring __syntax__ <verbatim>function matrix.print( ... )</verbatim> ---++++ !matrix.latex // matrix.latex ( mtx [, align] ) LaTeX output __syntax__ <verbatim>function matrix.latex( mtx, align )</verbatim> __parameters__ | *mtx* | | | *align* | | ---++++ !matrix.rows // Functions not changing the matrix // matrix.rows ( mtx ) return number of rows __syntax__ <verbatim>function matrix.rows( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.columns // matrix.columns ( mtx ) return number of columns __syntax__ <verbatim>function matrix.columns( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.size // matrix.size ( mtx ) get matrix size as string rows,columns __syntax__ <verbatim>function matrix.size( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.getelement // matrix.getelement ( mtx, i, j ) return specific element ( row,column ) returns element on success and nil on failure __syntax__ <verbatim>function matrix.getelement( mtx,i,j )</verbatim> __parameters__ | *mtx* | | | *i* | | | *j* | | ---++++ !matrix.setelement // matrix.setelement( mtx, i, j, value ) set an element ( i, j, value ) returns 1 on success and nil on failure __syntax__ <verbatim>function matrix.setelement( mtx,i,j,value )</verbatim> __parameters__ | *mtx* | | | *i* | | | *j* | | | *value* | | ---++++ !matrix.ipairs // matrix.ipairs ( mtx ) iteration, same for complex __syntax__ <verbatim>function matrix.ipairs( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.scalar /////////////////////////////// // matrix 'vector' functions // /////////////////////////////// a vector is defined as a 3x1 matrix get a vector; vec = matrix{{ 1,2,3 }}^'T' // matrix.scalar ( m1, m2 ) returns the Scalar Product of two 3x1 matrices (vectors) __syntax__ <verbatim>function matrix.scalar( m1, m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.cross // matrix.cross ( m1, m2 ) returns the Cross Product of two 3x1 matrices (vectors) __syntax__ <verbatim>function matrix.cross( m1, m2 )</verbatim> __parameters__ | *m1* | | | *m2* | | ---++++ !matrix.len // matrix.len ( m1 ) returns the Length of a 3x1 matrix (vector) __syntax__ <verbatim>function matrix.len( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.tocomplex //////////////////////////////// // matrix 'complex' functions // //////////////////////////////// // matrix.tocomplex ( mtx ) we set now all elements to a complex number also set the metatable __syntax__ <verbatim>function matrix.tocomplex( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.remcomplex // matrix.remcomplex ( mtx ) set the matrix elements to a number or complex number string __syntax__ <verbatim>function matrix.remcomplex( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.conjugate // matrix.conjugate ( m1 ) get the conjugate complex matrix __syntax__ <verbatim>function matrix.conjugate( m1 )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.tosymbol ///////////////////////////////// // matrix 'symbol' functions // ///////////////////////////////// // matrix.tosymbol ( mtx ) set the matrix elements to symbolic values __syntax__ <verbatim>function matrix.tosymbol( mtx )</verbatim> __parameters__ | *mtx* | | ---++++ !matrix.gsub // matrix.gsub( m1, from, to ) perform gsub on all elements __syntax__ <verbatim>function matrix.gsub( m1,from,to )</verbatim> __parameters__ | *m1* | | | *from* | | | *to* | | ---++++ !matrix.replace // matrix.replace ( m1, ... ) replace one letter by something else replace( "a",4,"b",7, ... ) will replace a with 4 and b with 7 __syntax__ <verbatim>function matrix.replace( m1,... )</verbatim> __parameters__ | *m1* | | ---++++ !matrix.solve // matrix.solve ( m1 ) solve; tries to solve a symbolic matrix to a number __syntax__ <verbatim>function matrix.solve( m1 )</verbatim> __parameters__ | *m1* | | ---++ TEA-1.0 | *Title* | TEA-1.0 | | *Author(s)* | LiXizhi, code is based on http://www.wowace.com/wiki/TEA-1.0 | | *Date* | | | *File* | script/ide/math/TEA.lua | ---+++ Description Tiny Encryption Algorythm implementation %T% __Sample Code__ <verbatim> NPL.load("(gl)script/ide/math/TEA.lua"); local TEA = commonlib.LibStub("TEA") local s0 = 'message digest' local s3 = '12345678901234567890123456789012345678901234567890123456789012345678901234567890' local k3 = TEA:GenerateKey(s3) assert(TEA:Decrypt(TEA:Encrypt(s0, k3), k3) == s0) </verbatim> ---+++ Member Functions ---++++ !lib:GenerateKey ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- local function StringToIntArray(text) local a, l = {}, string.len(text) for i = 1, l, 4 do local acc = 0 if l >= i + 3 then acc = acc + string.byte(text, i + 3) + string.byte(text, i + 2) * 256 + string.byte(text, i + 1) * 65536 + string.byte(text, i + 0) * 16777216 elseif l >= i + 2 then acc = acc + string.byte(text, i + 2) * 256 + string.byte(text, i + 1) * 65536 + string.byte(text, i + 0) * 16777216 elseif l >= i + 1 then acc = acc + string.byte(text, i + 1) * 65536 + string.byte(text, i + 0) * 16777216 elseif l >= i + 0 then acc = acc + string.byte(text, i + 0) * 16777216 end table.insert(a, acc) end if (math.fmod(#(a), 2) == 1) then table.insert(a, 0) end return a end local function IntArrayToString(array) local a = {} for i = 1, #(array) do for j = 3, 0, -1 do local b = bit.band(bit.rshift(array[i], j * 8), 255) table.insert(a, string.char(b)) end end while true do local n = #(a) if n > 0 and string.byte(a[n]) == 0 then table.remove(a, n) else break end end return table.concat(a) end __syntax__ <verbatim>function lib:GenerateKey(key)</verbatim> __parameters__ | *key* | | %STOPINCLUDE%
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r1
|
B
acklinks
|
V
iew topic
|
Ra
w
edit
|
M
ore topic actions
Topic revision: r1 - 2008-02-29
-
LiXizhi
Home
Site map
CCWeb web
HaqiTeen web
Main web
ParaEngine web
TWiki web
Main Web
Users
Groups
Index
Search
Changes
Notifications
RSS Feed
Statistics
导航页WebTopMenu
Preferences
开发指南
Getting Started
ParacraftSDK
NPL
MCML
NPL Reference Manual
美术Mod
Account
Log In
English
简体中文
簡體中文
E
dit
A
ttach
Copyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback