### Author Topic: Matrix Library  (Read 5140 times)

0 Members and 1 Guest are viewing this topic.

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Matrix Library
« on: June 22, 2012, 06:28:21 pm »
As the title implies, I'm planning on making a matrix library for Lua. I want it to be usable in computer Lua, too, so I don't want to use math.eval or other calculator dependent functions in this library. The math related aspect of this project can be found here.

Spoiler For fixed (I think):
My first roadblock is with being able to make the matrix itself.

I want the matrix to be unable to be edited without using the matrix functions. This can be accomplished using up-values, __index, and __newindex but I cant seem to figure out a good way to do this. I also want all the matrix functions to be available from the matrix.

Basically, I want it to be tamper-proof. I imagine it functioning like like this: (don't worry about the functions them selves)

Code: [Select]
matrix1 = matrix.new({{2, 3, 4}, {3, 4, 5}})matrix2 = matrix.new({{1, 0, 5}, {2, 5, 9}})matrix1:add(matrix2) == matrix.add(matrix1, matrix2) --truematrix1[1] = {2} --errormatrix1[1][1] = 2 --no errormatrix1[1][1] = "2" --converts to numbermatrix1[1][1] = true --errortable.maxn(matrix1) == 0 --true matrix1 doesn't actually contain any values, it forwards them to a local table in the matrix.new functionmatrix1[1][300] = 2 --error wrong dimensions

If anyone has any suggestions, it would be very helpful.

Edit: I've attached a copy to the first post so people don't have to search through the topic for a copy.

Lua Matrix Library
Last Update: July 16, 2012, 03:03:56 pm
Version: 0.9.2
New Features: added lu, trace, det, ref, rref, and rank

« Last Edit: July 16, 2012, 03:04:14 pm by 3rik »
Userbars

#### Levak

• LV9 Veteran (Next: 1337)
• Posts: 1002
• Rating: +208/-39
##### Re: Matrix Library
« Reply #1 on: June 22, 2012, 08:43:16 pm »
In Nspire Lua, it is exactly the goal of the class() function. But as you want it to be also usuable in standard Lua, I guess you should look at this

But ... there is another problem.

In Lua, everything is tables .. and most likely I'm interested in the way someone will handle call errors on elements likes the one you describe. IMHO it is impossible the way you want the errors to be handled.

Also, Lua is multitype, so this :
Code: [Select]
matrix1[1][1] = "2" --converts to numbermatrix1[1][1] = true --error will be possible only with direct calls to functions. The way you want it to be is not possible in Lua, same in many languages.... but I can be wrong.

matrix1[1][1] will be possible with something like this :

matrix1 = {{1, 2, 3}, {4, 5, 6}, ["add"]=function(self, m2) end}
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Re: Matrix Library
« Reply #2 on: June 22, 2012, 08:46:26 pm »
matrix1 = {{1, 2, 3}, {4, 5, 6}, ["add"]=function(self, m2) end}
Code: [Select]
setmetatable(matrix1, {__index=matrix})?
I think it can be done but I'm just not sure how to organize it.
« Last Edit: June 22, 2012, 08:49:33 pm by 3rik »
Userbars

#### Levak

• LV9 Veteran (Next: 1337)
• Posts: 1002
• Rating: +208/-39
##### Re: Matrix Library
« Reply #3 on: June 22, 2012, 09:10:44 pm »
getmetatable(matrix), but yes, it was just to show the content of matrix1.
matrix.new is the function described in the link I gave you.
I do not get mad at people, I just want them to learn the way I learnt.
My website - TI-Planet - iNspired-Lua

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Re: Matrix Library
« Reply #4 on: June 22, 2012, 09:30:40 pm »
here is an example of what I was trying to say:
Code: [Select]
matrix = {}matrix.new = function(data)local mat={}setmetatable(mat, {__index = function(tbl, nobbc)return data[nobbc]end})return matendmatrix1 = matrix.new({{4}})matrix2 = matrix.new({{7}})print(matrix1[1][1], matrix2[1][1], mat, data) --prints 4 7 nil nilnobbc was supposed to be key but I was having issues

This is an insecure example, but it works
« Last Edit: June 22, 2012, 09:53:30 pm by 3rik »
Userbars

#### Jim Bauwens

• Lua! Nspire! Linux!
• Editor
• LV10 31337 u53r (Next: 2000)
• Posts: 1881
• Rating: +206/-7
• Linux!
##### Re: Matrix Library
« Reply #5 on: June 23, 2012, 12:17:42 pm »
Here is the class function (although slightly modified):
Code: [Select]
class = function(prototype)local derived={}  if prototype then derived.__proto = prototype  function derived.__index(t,key)  return rawget(derived,key) or prototype[nobbc]  end  else  function derived.__index(t,key)  return rawget(derived,key)  end  end    function derived.__call(proto,...)  local instance={}  setmetatable(instance,proto)  instance.__obj = true  local init=instance.init  if init then  init(instance,...)  end  return instance  end    setmetatable(derived,derived)  return derivedend
I think you want something like this:

Code: [Select]
Matrix = class()function Matrix:init(mat)    self.matrix = matendfunction Matrix:set(x, y, n)    self.matrix[y][x] = nendmatrix1 = Matrix{{1,2,3},{1,2,3},{1,2,3}}matrix2 = Matrix{{1,2,3},{1,2,3}}matrix1:set(1,1,3)
matrix1 and matrix2 are not connected in anyway. You can expand the matrix class to your wishes.
Also, with metatables/-methods you could even make that matrix3=matrix1+matrix2 is possible
« Last Edit: June 23, 2012, 12:17:56 pm by jimbauwens »

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Re: Matrix Library
« Reply #6 on: June 23, 2012, 12:35:00 pm »
It's just that I don't want the data to be directly accessible to the programmer. I also want zeros to be stored as nils but when they're indexed, they return a 0. This is my version. It's still a work in progress.

I'm having issues with [ key ] turning into [nobbc] so I attached the file instead.
Userbars

#### Jim Bauwens

• Lua! Nspire! Linux!
• Editor
• LV10 31337 u53r (Next: 2000)
• Posts: 1881
• Rating: +206/-7
• Linux!
##### Re: Matrix Library
« Reply #7 on: June 23, 2012, 12:48:21 pm »
If you don't want users to have direct write access to the table, you can use something like this:

Code: [Select]
function createProxy(tbl) local mt = {} local proxy = {} mt.__index = function (_, key) return tbl[ key] end mt.__newindex = function () print("You are not allowed to write to this table!") end setmetatable(proxy, mt) return proxyenda = createProxy{1,2,3,4,5}print(a[2])a[2] = 3
I'm taking a look at your code.

Edit: ouch, the forum is changing table keys to nobbc
Edit2: Okay, I think class you be something for you. You should be able to protect your variables enough.
« Last Edit: June 23, 2012, 12:55:32 pm by jimbauwens »

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Re: Matrix Library
« Reply #8 on: June 23, 2012, 01:15:00 pm »
It's just that the matrix is a bunch of tables inside a table. Since the tables are passed by reference they could be altered using class(). Another tricky part is that when assigning to a spot in the matrix like
Code: [Select]
A[1][2] = 6the A[1] is found by __index not __newindex so it is like
Code: [Select]
B = A[1]B[2] = 6--or(A[1])[2] = 6 the reference to A[1] is assigned to B and then B[2] is assigned 6. This means __index and __newindex have to work together to allow assignment but control what can be assigned where while protecting the reference to the actual data.
« Last Edit: June 23, 2012, 01:16:29 pm by 3rik »
Userbars

#### Jim Bauwens

• Lua! Nspire! Linux!
• Editor
• LV10 31337 u53r (Next: 2000)
• Posts: 1881
• Rating: +206/-7
• Linux!
##### Re: Matrix Library
« Reply #9 on: June 23, 2012, 04:06:12 pm »
Well, here is almost the same for a matrix:

Code: [Select]
function createProxy(tbl) local mt = {} local proxy = {} mt.__index = function (t, key) local rownumber = rawget(t, "rownumber") if rownumber then return tbl[ rownumber][ key] else return tbl[ key] end end mt.__newindex = function () print("You are not allowed to write to this table!") end for key, row in ipairs(tbl) do proxy[ key] = {} proxy[ key].rownumber = key setmetatable(proxy[ key], mt) end setmetatable(proxy, mt) return proxyenda = createProxy{{5,4,3,2,1},{3,6,9,1}}print(a[ 2][ 3])a[ 2][ 3] = 3print(a[ 2][ 3])
« Last Edit: June 23, 2012, 04:07:00 pm by jimbauwens »

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Re: Matrix Library
« Reply #10 on: June 23, 2012, 04:20:29 pm »
One issue with this kind of matrix is that it allows a whole row to be assigned at one time without being checked if all the values are numbers or nils. I also want to still be able to assign to the matrix, just not directly. Also I would like to make all zeros be nils in the matrix. It allows large spaece matrices to be stored without taking up a massive amount of space.
Code: [Select]
a = matrix.new({[10000] = { [100000] = 8}})a[2][3] = 6print(a[2][3]+a[250][44]+a[10000][100000]) --prints 14
« Last Edit: June 23, 2012, 04:23:58 pm by 3rik »
Userbars

#### Jim Bauwens

• Lua! Nspire! Linux!
• Editor
• LV10 31337 u53r (Next: 2000)
• Posts: 1881
• Rating: +206/-7
• Linux!
##### Re: Matrix Library
« Reply #11 on: June 23, 2012, 04:24:08 pm »
It should not allow it. You can modify __newindex so to parse the input and possible modify it.
The above code is just the concept, you can build on it and make it do what you want.

Edit: wait, it does. Let me fix it
« Last Edit: June 23, 2012, 04:25:18 pm by jimbauwens »

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Re: Matrix Library
« Reply #12 on: June 23, 2012, 04:30:20 pm »
I think this is getting closer to what I came up with. It's just that my code is so inflated.
Userbars

#### Jim Bauwens

• Lua! Nspire! Linux!
• Editor
• LV10 31337 u53r (Next: 2000)
• Posts: 1881
• Rating: +206/-7
• Linux!
##### Re: Matrix Library
« Reply #13 on: June 23, 2012, 04:35:56 pm »
Okay, I guess you just need to modify some things to get it working.
However, why don't you just make the matrix local to your functions, so only your functions can access it ?
That way you could have matrix.getValue and matrix.setValue. Matrix[ y][ x] would not work. That way you don't need to deal with lot's of stuff.
« Last Edit: June 23, 2012, 04:36:05 pm by jimbauwens »

#### 3rik

• LV3 Member (Next: 100)
• Posts: 92
• Rating: +8/-0
• My TI-84+ SE
##### Re: Matrix Library
« Reply #14 on: June 23, 2012, 04:39:01 pm »
I was considering that. If this is too much to manage, I'll probably just switch to that plan.
Userbars