HellCreator Project by Dmitry Salomatine
sdihellcreator@bezeqint.net
Israel 2003
Original file name: ml_Gaus.lua
http://sdihchp.users3.50megs.com

   1  -- SDI_HellCreator
   2  -- Salomatine Dmitry.
   3  -- sdihellcreator@bezeqint.net
   4  -- Israel
   5  -- start       26.05.2003
   6  -- revision    03.06.2003
   7  
   8  require("ml_cd");--first check for core class lua
   9  require("ml_util");-- useful utills
  10  require("ml_fco");-- fraction
  11  
  12  Matrix={};
  13  local Matrix_mt = Class(Matrix);
  14  --this function make array of Frac objects
  15  function Matrix:makearray(size)
  16      if isNum(size) and size>0 then
  17      local t={};
  18      for i=1,size do
  19      t[i]=Frac:Frac();
  20      end
  21      return t;
  22      else
  23      return nil;
  24      end
  25  end
  26  --this function makes matrix nxm
  27  function Matrix:makerows(rows,size)
  28      if isNum2(rows,size) and rows>0 and size>0 then
  29      local t={};
  30      for i=1,rows do
  31      t[i]=self:makearray(size);
  32      end
  33      return t;
  34      else
  35      return nil;
  36      end
  37  end
  38  --function that generate variables names
  39  function Matrix:generatenames(columns)
  40      if isNum(columns) and columns>0 then
  41      local t={};
  42      for i=1,columns do
  43      t[i]=string.format("X%d",i);
  44      end
  45      return t;
  46      else
  47      return nil;
  48      end
  49  end
  50  
  51  --new function for the Matrix object
  52  --you must provide:
  53  --size of matrix(rows,columns)
  54  --do we need extended column of free members
  55  --and if you whant the names for variables if not they will be
  56  --generated automaticaly in format x1...xn
  57  
  58  function Matrix:new(trows,tcolumns,tstar,tnames)
  59      local tr,tfm,cn=nil,nil,nil;
  60      local ti,tj=0,0;
  61      if trows and isNum(trows) and trows>0 then
  62         if tcolumns and isNum(tcolumns) and tcolumns>0then
  63            ti=trows;
  64            tj=tcolumns;
  65            tr=self:makerows(trows,tcolumns);--nxm matrix
  66            if tstar and type(tstar)=="boolean" and tstar==true then
  67               tfm=self:makearray(trows);--R star(free members)
  68            end
  69            if tnames and type(tnames)=="table" and table.getn(tnames)>=trows then
  70               cn=tnames;
  71            else
  72               cn=self:generatenames(tcolumns);
  73            end
  74         end
  75      end
  76      return setmetatable({R=tr,CFm=tfm,Names=cn,mi=ti,mj=tj}, Matrix_mt);
  77  end
  78  --default constructor for object via new
  79  function Matrix:Matrix()
  80      return Matrix:new(2,2,true);--default 2x2|2 have zero value
  81  end
  82  --function creates and return I matrix
  83  function Matrix:I(size)
  84      local tmo=Matrix:new(size,size,false);
  85      for i=1,size do
  86         self.R[i][i]:SetF(1);
  87      end
  88      return tmo;
  89  end
  90  --function creates and return scalar matrix
  91  --Matrix of type A=nI
  92  function Matrix:N(size,n)
  93      local tmo=Matrix:new(size,size,false);
  94      for i=1,size do
  95         self.R[i][i]:SetF(n);
  96      end
  97      return tmo;
  98  end
  99  --function remove row
 100  function Matrix:RemRow(idx)
 101      if idx and isNum(idx) and idx>=1 and idx<=self.mi then
 102         
 103      else--remove all rows
 104         
 105      end
 106  end
 107  --function add whole row
 108  function Matrix:AddRow(after)
 109      if after then
 110         if after<=0 then--make it first
 111            --push all exist down
 112            --and insert new one
 113            print("not implemented yet");
 114         else--we have some positive ofset
 115            if after>self.mi then
 116               after=self.mi;
 117            end
 118            --push all exist from after position down
 119            --and insert new one between them
 120            print("not implemented yet"); 
 121         end
 122      else
 123         --default push to bottom of the Matrix
 124         self.R[self.mi+1]=self:makearray(self.mj);
 125         if self.CFm then--we have extended column
 126            self.CFm[self.mi+1]=Frac:Frac();
 127         end
 128         self.mi=self.mi+1;
 129      end
 130  end
 131  --function set the value to i,j member of matrix
 132  --if we have extended column j must be equal to max column+1
 133  --o it is Frac object or number
 134  function Matrix:Set(ti,tj,o)
 135      if ti and tj and isNum2(ti,tj) and o then
 136         if ti<=self.mi and tj<=self.mj then
 137            self.R[ti][tj]:Set(o:Get());
 138         else
 139            if self.CFm and ti<=self.mi and tj==self.mj+1 then
 140               self.CFm[ti]:Set(o:Get());
 141            end
 142         end
 143      end
 144  end
 145  
 146  --core function of matrix class
 147  --actualy solves the equations
 148  --brings the matrix to ESHELON view
 149  function Matrix:Solve()
 150      local pp=false;--found problematic pivote
 151      for i=1,self.mi do
 152         --we can't range more then number of columns so break
 153         if i>self.mj then break; end
 154         --first check if pivote not zero
 155         if i<=self.mj and self.R[i][i]:GetFP()==0 then --swap columns with their names
 156            pp=true;--problem found
 157            --find column in this row that not starting with 0
 158            for k=i,self.mj do
 159               if self.R[i][k]:GetFP()~=0 then--we found one we like
 160                  --swap between columns names and break
 161                  --swap names
 162                  self.Names[i],self.Names[k]=self.Names[k],self.Names[i];
 163                  --swap columns
 164                  for p=1,self.mi do
 165                     self.R[p][i],self.R[p][k]=self.R[p][k],self.R[p][i];
 166                  end
 167                  pp=false;--problem solved
 168                  break;
 169               end
 170            end
 171         end
 172         if pp==true then--we steel have pivote problem
 173            --try to solve it by swaping rows in down positions
 174           
 175         end
 176         --if we get to here probably all problems have been solved
 177         --check and procceed to the actualy rows manipulations
 178         for k=i+1,self.mi do
 179            if self.R[i][i]:GetFP()~=0 and self.R[k][i]:GetFP()~=0 then--procceed dirug
 180            --find proportion to get zero in first member
 181            local tf=Frac:Frac();
 182            tf:Set(self.R[k][i]:Div(self.R[i][i]));
 183            local ter=Frac:Frac();
 184            ter:Set(self.R[i][i]:Mul(tf));
 185            self.R[k][i]:Set(self.R[k][i]:Sub(ter));
 186            if self.CFm then--we have extended column
 187               ter:Set(self.CFm[i]:Mul(tf));
 188               self.CFm[k]:Set(self.CFm[k]:Sub(ter));
 189            else--it is homogenic matrix
 190               --so just do nothing
 191            end
 192               --print("Proportion in row "..k.." is"..tf:GetFP());
 193            end
 194         end
 195      --show product in this stage of proccessing
 196      print("Solving stage:"..i);
 197      self:Show();
 198      print("Press Enter to next stage");
 199      local x=io.read();
 200      end
 201  end
 202  
 203  --function just show matrix homogenic or not om the screen
 204  --with variables names
 205  function Matrix:Show()
 206      local ts="";
 207      for i=1,self.mj do
 208      ts=string.format("%s %+5s",ts,self.Names[i]);
 209      end
 210      print(ts);
 211      for i=1,self.mi do
 212          ts="(";
 213         for j=1,self.mj do
 214         ts=string.format("%s %.3f",ts,self.R[i][j]:GetFP());
 215         end
 216         if self.CFm then--we have extended column
 217         ts=string.format("%s | %.3f )",ts,self.CFm[i]:GetFP());
 218         else--it is homogenic matrix
 219         ts=string.format("%s | 0 )",ts);
 220         end
 221         print(ts);
 222      end
 223  end
 224  
 225  --tests
 226  function da() os.execute("cls");dofile("ml_gaus.lua");end
 227  mtest=Matrix:new(3,3,true,{"a","b","c"});
 228  a=Frac:new();
 229  a:SetF(1);
 230  mtest:Set(1,1,a);
 231  a:SetF(2);
 232  mtest:Set(1,2,a);
 233  a:SetF(3);
 234  mtest:Set(1,3,a);
 235  a:SetF(4);
 236  mtest:Set(1,4,a);
 237  a:SetF(1);
 238  mtest:Set(2,1,a);
 239  a:SetF(2);
 240  mtest:Set(2,2,a);
 241  a:SetF(3);
 242  mtest:Set(2,3,a);
 243  a:SetF(4);
 244  mtest:Set(2,4,a);
 245  a:SetF(1);
 246  mtest:Set(3,1,a);
 247  a:SetF(2);
 248  mtest:Set(3,2,a);
 249  a:SetF(3);
 250  mtest:Set(3,3,a);
 251  a:SetF(4);
 252  mtest:Set(3,4,a);
 253  mtest:AddRow();
 254  print("Start position");
 255  mtest:Show();
 256  mtest:Solve();

Lua source files to HTML converted 06/04/03 14:13:32