Would you like to make this site your homepage? It's fast and easy...
Yes, Please make this my home page!
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();