# newbee question... Classic List Threaded 15 messages Open this post in threaded view
|

## newbee question...

 ```Hi, I'm new to Lua but I think I like it. Here is my question: How can I implement a USER-friendly method to work with 2-dimensional arrays/matrices. (i.e. create, redim, access elements etc.)? I'd like to allow my users to do something like: arrayA = array(NumCols, NumRows) --create array numberB = getval(arrayA, Col, Pos) --access elements redim(arrayA, ColDelta, RowDelta) --realloc arrayC = arrayA -- copy whole array arrayD = arrayA+arrayB --arithmetic operators Do I have to use the USERDATA tag for arrayA, arrayB ..., or can I do all this with tables? Thanks, Chris ```
Open this post in threaded view
|

## Re: newbee question...

 ```> How can I implement a USER-friendly method to work with 2-dimensional > arrays/matrices. (i.e. create, redim, access elements etc.)? > I'd like to allow my users to do something like: > arrayA = array(NumCols, NumRows) --create array > numberB = getval(arrayA, Col, Pos) --access elements > redim(arrayA, ColDelta, RowDelta) --realloc > arrayC = arrayA -- copy whole array > arrayD = arrayA+arrayB --arithmetic operators > > Do I have to use the USERDATA tag for arrayA, arrayB ..., or can I do all > this with tables? > Forget the unflexibility of "legacy programming languages" like maybe C or BASIC (>>yuck<<). You need not to "redimensioning" anything. Just add new elements- or even dimensions. Even don't think about indexes being contigous -A table can contain tables, so one solution for two dimensional matrices can be a table of tables -you don't have to specify a size ever - to cleanup, just assign nil or leave the scope where the table is valid, the garbage collector does the rest ```
Open this post in threaded view
|

## Re: newbee question...

 ```On 19 Oct 2000 [hidden email] wrote: > > How can I implement a USER-friendly method to work with > 2-dimensional > > arrays/matrices. (i.e. create, redim, access elements etc.)? > > I'd like to allow my users to do something like: > > arrayA = array(NumCols, NumRows) --create array > > numberB = getval(arrayA, Col, Pos) --access elements > > redim(arrayA, ColDelta, RowDelta) --realloc > > arrayC = arrayA -- copy whole array > > arrayD = arrayA+arrayB --arithmetic operators > > > > Do I have to use the USERDATA tag for arrayA, arrayB ..., or can I do > all > > this with tables? > > > > Forget the unflexibility of "legacy programming languages" like maybe C > or BASIC (>>yuck<<). > You need not to "redimensioning" anything. Just add new elements- or > even dimensions. Even don't think about indexes being contigous > > -A table can contain tables, so one solution for two dimensional > matrices can be a table of tables > -you don't have to specify a size ever > - to cleanup, just assign nil or leave the scope where the table > is valid, the garbage collector does the rest > Out of curiousity... > c={1,3} > print(c) nil > print(c) 1 > print(c) 3 > Why does table indexing begin at 1 and not zero? I guess this is just a convention, but I've become accustomed to zero based arrays :) Thanks Jonathan. ```
Open this post in threaded view
|

## Re: newbee question...

 ```In message you wrote: > On 19 Oct 2000 [hidden email] wrote: > > > > How can I implement a USER-friendly method to work with > > 2-dimensional > > > arrays/matrices. (i.e. create, redim, access elements etc.)? I'd like > > > to allow my users to do something like: arrayA = array(NumCols, > > > NumRows) --create array numberB = getval(arrayA, Col, Pos) > > > --access elements redim(arrayA, ColDelta, RowDelta) --realloc arrayC > > > = arrayA -- copy whole array arrayD = arrayA+arrayB --arithmetic > > > operators > > > > > > Do I have to use the USERDATA tag for arrayA, arrayB ..., or can I do > > all > > > this with tables? > > > > > > > Forget the unflexibility of "legacy programming languages" like maybe C > > or BASIC (>>yuck<<). You need not to "redimensioning" anything. Just add > > new elements- or even dimensions. Even don't think about indexes being > > contigous > > > > -A table can contain tables, so one solution for two dimensional > > matrices can be a table of tables -you don't have to specify a size ever > > - to cleanup, just assign nil or leave the scope where the table is > > valid, the garbage collector does the rest > > > > Out of curiousity... > > > c={1,3} print(c) > nil > > print(c) > 1 > > print(c) > 3 > > > > Why does table indexing begin at 1 and not zero? I guess this is just a > convention, but I've become accustomed to zero based arrays :) Thats something I found had to get used to, but I did :) Cheers, -- Rob Kendrick, http://www.digital-scurf.org/ Work is the scythe of time. ```
Open this post in threaded view
|

## Re: newbee question...

 ```On Thu, 19 Oct 2000, Rob Kendrick wrote: > In message you > wrote: > > > Out of curiousity... > > > > > c={1,3} print(c) > > nil > > > print(c) > > 1 > > > print(c) > > 3 > > > > > > > Why does table indexing begin at 1 and not zero? I guess this is just a > > convention, but I've become accustomed to zero based arrays :) > > Thats something I found had to get used to, but I did :) Fair enough :) ```
Open this post in threaded view
|

## Re: newbee question...

 In reply to this post by Chris ```From: "Chris" <[hidden email]> > How can I implement a USER-friendly method to work with 2-dimensional > arrays/matrices. (i.e. create, redim, access elements etc.)? > I'd like to allow my users to do something like... Here's an example of doing it using lua tables as sparse arrays: function arrayNew(NumCols, NumRows) return {} end function arrayValue(arrayA, Col, Pos) local col = arrayA[Col] if type(col) == "table" then return col[Pos] end return nil end redim isn't needed. > arrayC = arrayA -- copy whole array How about: arrayC = clone(arrayA) function clone(aTable) if type(aTable) ~= "table" then return aTable end local newTable = {} local i, v = next(aTable, nil) while i ~= nil do if type(v) == "table" then v = clone(aTable) newTable[i] = v i, v = next(aTable, i) end return newTable end > arrayD = arrayA+arrayB --arithmetic operators How about: arrayD = arrayAdd(clone(arrayA), arrayB) function arrayAdd(arrayA, arrayB) if type(arrayA) ~= "table" or type(arrayB) ~= "table" then error("arrayAdd("..type(arrayA)..", "..type(arrayB)..") - both arguments must be tables") end local i, bValue= next(arrayB, nil) while i ~= nil do local aValue = arrayA[i] if aValue then if type(aValue) == "table" then arrayAdd(aValue, bValue) else arrayA[i] = aValue + bValue end else arrayA[i] = clone(bValue) end i, bValue = next(arrayA, i) end return arrayA end Note: This code isn't tested - I just wrote it in this email. Steve ```
Open this post in threaded view
|

## Re: newbee question...

 In reply to this post by Chris ```Yes that looks good. But I have a vector/matrix library written in C++ that I want to use. I'd like to make it as easy as possible for my (LUA implemented as script) users to access elements. Therefore I have an overloaded operator (). C++ : declaration: double& operator() (int, int); implementation: double& matrix::operator() (int m, int n) { if (m <= 0 || m > m_nRows || n <= 0 || n > m_nCols) Throw(IndexException(m, n, *this)); return data[(m - 1) * ncols + n - 1]; } Is it possible to implement this operator as a LUA extension, so my Users can write a vaild LUA statement like: mat = matrix:new(NumCols, NumRows) mat(1, 1) = 12 mat(1, 2) = 56 mat(2, 1) = 98 mat(2, 2) = 32 mat:delete() cheers, Chris ```
Open this post in threaded view
|

## Re: newbee question...

 In reply to this post by KZerb ```> Forget the unflexibility of "legacy programming languages" like >maybe C or BASIC (>>yuck<<). > You need not to "redimensioning" anything. Just add new elements You are right, and that's one of the reasons why I like LUA. But I want to use LUA as a hassle-free "driver" for my vast collection of numerical libraries written in C/C++. So I think I'll use TOLUA to export my C++ matrix classes. But I'm afraid there is no way to overload round brackets. Q: Do I have to use a "getter" function i.e. number = mat:get(1, 1), or can I overload square brackets to give my users the chance to write something like: number = mat[1, 1]? PS: My app will be used by my students. Most of them are not very good programmers (they are used to matlab), and that's the reason why I'm looking for an easy way to handle matrices. ```
Open this post in threaded view
|

## Re: newbee question...

 ```On Thu, 19 Oct 2000 [hidden email] wrote: > > Forget the unflexibility of "legacy programming languages" like > >maybe C or BASIC (>>yuck<<). > > You need not to "redimensioning" anything. Just add new elements > > You are right, and that's one of the reasons why I like LUA. But I > want to use LUA as a hassle-free "driver" for my vast collection of > numerical libraries written in C/C++. So I think I'll use TOLUA to > export my C++ matrix classes. But I'm afraid there is no way to > overload round brackets. Q: Do I have to use a "getter" function i.e. > number = mat:get(1, 1), or can I overload square brackets to give my > users the chance to write something like: number = mat[1, 1]? Tag Methods should do the trick. Have a look here. http://www.tecgraf.puc-rio.br/lua/manual/new/manual.html#4.8 At a guess, the ones you want to look at are gettable and function. Jonathan. ```
Open this post in threaded view
|

## Re: newbee question...

 In reply to this post by Chris ```Chris <[hidden email]> wrote: > Is it possible to implement this operator as a LUA extension, > so my Users can write a vaild LUA statement like: > > mat = matrix:new(NumCols, NumRows) > mat(1, 1) = 12 > mat(1, 2) = 56 > mat(2, 1) = 98 > mat(2, 2) = 32 > mat:delete() If you don't require the arrays to be sparse, you could just create tables for the first n-1 dimensions, and let assignment do the rest. Wouldn't something like what I scetched out below do the trick? -- assumes you have the usual "deep copy" clone routine defined... Matrix = { clone = clone } function Matrix:new(rows) return Matrix:clone():dim(rows) end function Matrix:dim(rows) for r=1, rows do if not self[r] then self[r] = {} end end return self end function Matrix:delete() self = nil end mat = Matrix:new(5) mat = 12 mat = 56 mat = 98 mat = 32 mat:dim(10) -- redimension matB = mat:clone() -- copy mat:delete() -- free x = matB print (x) -- 98 matB:delete() I guess this is only practical if the dimensions are few or very small. Cheers, Eric __________________________________________________ Do You Yahoo!? Yahoo! Messenger - Talk while you surf! It's FREE. http://im.yahoo.com/ ```
Open this post in threaded view
|

## Re: newbee question...

 In reply to this post by Chris ```>function Matrix:delete() > self = nil >end despite the appeareances, this does not set the value of the caller object to nil: it only sets the value of the local variable 'self' to nil. this variable is an ordinary local variable (except that it's implicit), which is initialized to the value of the caller object. --lhf ```
Open this post in threaded view
|

## Re: newbee question...

 In reply to this post by Chris ```Oh, yeah. Sorry about that! I've only been playing with the language for days, so I missed a subtle point: 'x = nil' does not affect the table x refers to, it merely reduces the number of references to that table (by one). Thanks, Eric --- Luiz Henrique de Figueiredo <[hidden email]> wrote: > >function Matrix:delete() > > self = nil > >end > > despite the appeareances, this does not set the value of the caller object to > nil: it only sets the value of the local variable 'self' to nil. > this variable is an ordinary local variable (except that it's implicit), > which is initialized to the value of the caller object. > --lhf __________________________________________________ Do You Yahoo!? Yahoo! Messenger - Talk while you surf! It's FREE. http://im.yahoo.com/ ```
Open this post in threaded view
|

## Re: newbee question...

 In reply to this post by Chris ```>'x = nil' does not affect the table x refers to, it merely reduces the number of >references to that table (by one). Lua does not use reference counting; it uses mark-and-sweep. --lhf ```
 In reply to this post by Luiz Henrique de Figueiredo ```On Fri, Oct 20, 2000 at 10:10:51PM -0200, Luiz Henrique de Figueiredo wrote: > >function Matrix:delete() > > self = nil > >end > > despite the appeareances, this does not set the value of the caller object to > nil: it only sets the value of the local variable 'self' to nil. > this variable is an ordinary local variable (except that it's implicit), > which is initialized to the value of the caller object. What languages are there which don't have the behavior Lua does? For example, C++ and Python both do the same thing Lua does. ** C++ void MyObject:my_method(void) { this = NULL; // this is just an implied local variable } ** Python class MyObject: def my_method(self): self = none // in Python it's more explicit somewhat like lua -- David Jeske (N9LCA) + http://www.chat.net/~jeske/ + [hidden email] ```
 ```On Fri, 20 Oct 2000, David Jeske wrote: > ** C++ > > void MyObject:my_method(void) { > this = NULL; // this is just an implied local variable > } Hallo, Actually it would change the object because "this" is a pointer, a concept that doesn't exist in Lua neither in Python. But C++ is smart enough to not allow assigments to "this". --Alex [hidden email] Lab. de Computação Gráfica/UFC +----------------------------------------------------------------------------+ |"Minha força vem da solidão. Não tenho medo das chuvas tempestuosas nem das | | grandes ventanias soltas, pois eu também sou o escuro da noite." | | - Clarice Lispector | +----------------------------------------------------------------------------+ ```