newbee question...

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

newbee question...

Chris
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

Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

KZerb
> 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




Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Jonathan Adamczewski
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.


Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Rob Kendrick-4
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.

Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Jonathan Adamczewski
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 :)


Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Steve Dekorte-6
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


Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Chris
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


Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Chris
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.


Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Jonathan Adamczewski
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.


Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Eric Tetz-2
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[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/

Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Luiz Henrique de Figueiredo
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

Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Eric Tetz-2
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/

Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Luiz Henrique de Figueiredo
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

Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

David Jeske-3
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]

Reply | Threaded
Open this post in threaded view
|

Re: newbee question...

Alex Sandro Queiroz e Silva
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						     |
+----------------------------------------------------------------------------+