Advertisement
GeeckoDev

matrix.lua

Sep 9th, 2011
432
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.34 KB | None | 0 0
  1. --/ Matrix class for Lua \--
  2.  
  3.  
  4. Matrix = {}
  5. Matrix.__index = Matrix
  6.  
  7.  
  8. -- \
  9. -- | Constructor
  10. -- /
  11.  
  12.  
  13. -- Returns a (n,p) order matrix.
  14. function Matrix:new(n, p)
  15.   if n < 0 or p < 0 then
  16.     return nil
  17.   end
  18.   if n == 0 or p == 0 then
  19.     n, p = 0, 0
  20.   end
  21.  
  22.   local t = {n=n, p=p}
  23.   setmetatable(t, self)
  24.   for i=1, n do
  25.     t[i] = {}
  26.     for j=1, p do
  27.       t[i][j] = 0
  28.     end
  29.   end
  30.  
  31.   return t
  32. end
  33.  
  34.  
  35. -- \
  36. -- | Methods
  37. -- /
  38.  
  39.  
  40. -- Prints a matrix to the shell.
  41. function Matrix:print()
  42.   if self.n == 0 or self.p == 0 then
  43.     print("||")
  44.     return
  45.   end
  46.  
  47.   for i=1, self.n do
  48.     io.write("|")
  49.     for j=1, self.p do
  50.       io.write(self[i][j])
  51.       if j ~= self.p then
  52.         io.write(" ")
  53.       end
  54.     end
  55.     io.write("|\n")
  56.   end
  57. end
  58.    
  59.  
  60. -- Fills a matrix with values from 'list'.
  61. function Matrix:fill(list)
  62.   if self.n * self.p ~= #list then
  63.     return
  64.   end
  65.  
  66.   for i=1, self.n do
  67.     for j=1, self.p do
  68.       self[i][j] = list[(i-1)*self.p + j]
  69.     end
  70.   end
  71. end
  72.  
  73.  
  74. -- Fills a matrix' row 'i' with values from 'list'.
  75. function Matrix:fillRow(list, i)
  76.   if i < 1 or i > self.n then
  77.     return
  78.   end
  79.   if self.p ~= #list then
  80.     return
  81.   end
  82.  
  83.   self[i] = list
  84. end
  85.  
  86.  
  87. -- Fills a matrix' column 'j' with values from 'list'.
  88. function Matrix:fillColumn(list, j)
  89.   if j < 1 or j > self.p then
  90.     return
  91.   end
  92.   if self.n ~= #list then
  93.     return
  94.   end
  95.  
  96.   for i=1, self.n do
  97.     self[i][j] = list[i]
  98.   end
  99. end
  100.  
  101.  
  102. -- Checks if a matrix has the same dimensions of 'm'.
  103. function Matrix:isEquivalent(m)
  104.   return self.n == m.n and self.p == m.p
  105. end
  106.  
  107.  
  108. -- Checks if a matrix is symetric.
  109. function Matrix:isSymetric()
  110.   return self == self:transpose()
  111. end
  112.  
  113.  
  114. -- Checks if a matrix is anti-symetric.
  115. function Matrix:isAntiSymetric()
  116.   return self == -self:transpose()
  117. end
  118.  
  119.  
  120. -- Checks if a matrix is upper triangular.
  121. function Matrix:isUpperTriangular()
  122.   for i=1, self.n do
  123.     for j=1, i-1 do
  124.       if self[i][j] ~= 0 then
  125.         return false
  126.       end
  127.     end
  128.   end
  129.  
  130.   return true
  131. end
  132.  
  133.  
  134. -- Checks if a matrix is lower triangular.
  135. function Matrix:isLowerTriangular()
  136.   for i=1, self.n do
  137.     for j=i+1, self.p do
  138.       if self[i][j] ~= 0 then
  139.         return false
  140.       end
  141.     end
  142.   end
  143.  
  144.   return true
  145. end
  146.  
  147.  
  148. -- Checks if a matrix is the inverse of 'm'
  149. function Matrix:isInverse(m)
  150.   if self:isEquivalent(m) == false or self.n ~= self.p then
  151.     return false
  152.   end
  153.  
  154.   local t = self * m;
  155.  
  156.   if t:isUpperTriangular() == false then
  157.     return false
  158.   end
  159.   if t:isLowerTriangular() == false then
  160.     return false
  161.   end
  162.  
  163.   for i=1, t.n do
  164.     if (t[i][i] ~= 1) then
  165.       return false
  166.     end
  167.   end
  168.  
  169.   return true  
  170. end
  171.  
  172.  
  173. -- Returns a 'n'-th order square matrix.
  174. function Matrix:square(n)
  175.   return Matrix:new(n, n)
  176. end
  177.  
  178.  
  179. -- Returns a 'n'-th order diagonal matrix, using values from 'list'.
  180. function Matrix:diagonal(list)
  181.   local t = Matrix:square(#list)
  182.  
  183.   for i=1, #list do
  184.     t[i][i] = list[i]
  185.   end
  186.  
  187.   return t
  188. end
  189.  
  190.  
  191. -- Returns a 'n'-th order identity matrix.
  192. function Matrix:identity(n)
  193.   local t = Matrix:square(n)
  194.  
  195.   for i=1, n do
  196.     t[i][i] = 1
  197.   end
  198.  
  199.   return t
  200. end
  201.  
  202.  
  203. -- Returns the transposed of a matrix.
  204. function Matrix:transpose()
  205.   local t = Matrix:new(self.p, self.n)
  206.  
  207.   for i=1, self.n do
  208.     t:fillColumn(self[i],i)
  209.   end
  210.  
  211.   return t
  212. end
  213.  
  214.  
  215. -- \
  216. -- | Operators overcharge
  217. -- /
  218.  
  219.  
  220. -- Checks if 'a' equals 'b'
  221. function Matrix.equals(a, b)
  222.   if a:isEquivalent(b) == false then
  223.     return false
  224.   end
  225.  
  226.   for i=1, a.n do
  227.     for j=1, a.p do
  228.       if a[i][j] ~= b[i][j] then
  229.         return false
  230.       end
  231.     end
  232.   end
  233.  
  234.   return true
  235. end
  236.  
  237.  
  238. -- Returns the matrix sum of 'a' and 'b'
  239. function Matrix.sum(a, b)
  240.   if a:isEquivalent(b) == false then
  241.     return nil
  242.   end
  243.  
  244.   local t = Matrix:new(a.n, a.p)
  245.   for i=1, a.n do
  246.     for j=1, a.p do
  247.       t[i][j] = a[i][j] + b[i][j]
  248.     end
  249.   end
  250.  
  251.   return t
  252. end
  253.  
  254.  
  255. -- Returns the matrix difference of 'a' and 'b'
  256. function Matrix.difference(a, b)
  257.   if a:isEquivalent(b) == false then
  258.     return nil
  259.   end
  260.  
  261.   local t = Matrix:new(a.n, a.p)
  262.   for i=1, a.n do
  263.     for j=1, a.p do
  264.       t[i][j] = a[i][j] - b[i][j]
  265.     end
  266.   end
  267.  
  268.   return t
  269. end
  270.  
  271.  
  272. -- Returns the negative of a matrix
  273. function Matrix.negative(m)
  274.   return Matrix:new(m.n, m.p) - m
  275. end
  276.  
  277.  
  278. -- Returns the product of a matrix and a real 'r'
  279. function Matrix.rproduct(m, r)
  280.   local t = Matrix:new(m.n, m.p)
  281.  
  282.   for i=1, t.n do
  283.     for j=1, t.p do
  284.       t[i][j] = m[i][j] * r
  285.     end
  286.   end
  287.  
  288.   return t
  289. end
  290.  
  291.  
  292. -- Returns the matrix product of 'a' and 'b'
  293. function Matrix.product(a, b)
  294.   if getmetatable(a) ~= Matrix then
  295.     return Matrix.rproduct(b, a)
  296.   end
  297.   if getmetatable(b) ~= Matrix then
  298.     return Matrix.rproduct(a, b)
  299.   end
  300.   if a.p ~= b.n then
  301.     return nil
  302.   end
  303.  
  304.   local t = Matrix:new(a.n, b.p)
  305.   for i=1, a.n do
  306.     for j=1, b.p do
  307.       t[i][j] = 0
  308.       for k=1, a.p do
  309.         t[i][j] = t[i][j] + a[i][k] * b[k][j]
  310.       end
  311.     end
  312.   end
  313.  
  314.   return t
  315. end
  316.  
  317.  
  318. Matrix.__add = Matrix.sum
  319. Matrix.__sub = Matrix.difference
  320. Matrix.__mul = Matrix.product
  321. Matrix.__pow = nil
  322. Matrix.__unm = Matrix.negative
  323. Matrix.__concat = nil
  324. Matrix.__eq = Matrix.equals
  325. Matrix.__lt = nil
  326. Matrix.__le = nil
  327.  
  328. -- EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement