|
|
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
|
|
> 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
|
|
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[0])
nil
> print(c[1])
1
> print(c[2])
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.
|
|
In message <Pine.BSO.4.21.0010191007130.9656-100000@...> 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[0])
> nil
> > print(c[1])
> 1
> > print(c[2])
> 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.
|
|
On Thu, 19 Oct 2000, Rob Kendrick wrote:
> In message <Pine.BSO.4.21.0010191007130.9656-100000@...> you
> wrote:
>
> > Out of curiousity...
> >
> > > c={1,3} print(c[0])
> > nil
> > > print(c[1])
> > 1
> > > print(c[2])
> > 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 :)
|
|
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
|
|
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
|
|
> 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.
|
|
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.
|
|
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[1][1] = 12
mat[1][2] = 56
mat[2][1] = 98
mat[2][2] = 32
mat:dim(10) -- redimension
matB = mat:clone() -- copy
mat:delete() -- free
x = matB[2][1]
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/
|
|
>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
|
|
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/
|
|
>'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 |
+----------------------------------------------------------------------------+
|
|