Friday, June 15, 2012

Python code for Gaussian Elimination Algorithm


This is a homework for Math 630: Linear Algebra     
Textbook : Linear Algebra and Its Applications, G. Strang, Thomson Brooks ISBN: 0030105676  

Code Brief

  • Written in Python
  • All matrix indices (row and column) are Zero-based
  • line 1-92 Algorithm
  • line 92-332  Tests

=======================Begin of Code=============================
001  import unittest
002  
003  ######################################
004  # Three elementary transformation 
005  ######################################
006  def SwapRow(aMatrix, aRow1, aRow2):
007      if aRow1!=aRow2:     
008          aMatrix[aRow1],aMatrix[aRow2] = aMatrix[aRow2],aMatrix[aRow1];       
009  
010  def ScaleRow(aMatrix, aRow, aScalar):
011      aMatrix[aRow] = map(lambda x:x*aScalar,aMatrix[aRow]);
012              
013  def CombineRow(aMatrix, aAddTo, aAddBy, aScalar):   
014      aMatrix[aAddTo] = map(lambda x,y:x+y*aScalar, 
015                            aMatrix[aAddTo],aMatrix[aAddBy]);
016                                                       
017      def DoZeroCorrection(aValue): #not tested
018          if IsZero(aValue): 
019              return 0;
020          else: 
021              return aValue;        
022      aMatrix[aAddTo] = map(DoZeroCorrection, aMatrix[aAddTo]);    
023  
024  ######################################
025  # Helpers  
026  ######################################
027  def GetPivotCoeff(aPivot, aTarget):
028      return -1.0*(aTarget+0.0)/(aPivot+0.0);  
029  
030  EPSION = 0.000001; # 1 over million                       
031  def IsZero(aValue):
032      return  abs(aValue)<EPSION;           
033  
034  def IsZeroRow(aRow):
035      return len(filter(IsZero,aRow))== len(aRow); 
036  
037  
038  ######################################
039  # Operations
040  ######################################
041  def PivotDown(aMatrix, aLastNonZeroRow, aRow, aCol):
042      for i in range(aRow+1,aLastNonZeroRow+1):
043          if IsZeroRow(aMatrix[i]):
044              continue;
045              
046          CombineRow(aMatrix,i,aRow,
047                     GetPivotCoeff(aMatrix[aRow][aCol],aMatrix[i][aCol]))       
048          
049  def MakeColumnPivot(aMatrix, aRow, aLastNonZeroRow, aCol):      
050      for c in range(aCol,len(aMatrix[0])):
051          for r in range(aRow,aLastNonZeroRow+1):
052              if not IsZero(aMatrix[r][c]):
053                  SwapRow(aMatrix,aRow,r);
054                  return c;
055                  
056      # This line will never be hit, because after doing MakeRowPivot,
057      #at least, current row has non-zero entry, thus return with the 
058      # shortcut in SwapRow when Row1=Row2                 
059      return len(aMatrix[0])-1;                
060  
061  def MakeRowPivot(aMatrix, aCurrRow, aLastNonZeroRow):
062      for r in range(aLastNonZeroRow,aCurrRow,-1):
063          if IsZeroRow(aMatrix[aCurrRow]):
064              SwapRow(aMatrix,aCurrRow,r);
065          else:
066              return r;
067   
068      return aCurrRow;
069          
070  
071  
072  ######################################
073  # Gaussian Elimination Algorithm
074  ######################################
075  def DoGaussianElimination(aMatrix):
076      M = len(aMatrix);
077      N = len(aMatrix[0]);
078      
079      pivotCol = 0;                    
080      lastRow = M-1;
081      for pivotRow in range(0,M): 
082          lastRow = MakeRowPivot(aMatrix, pivotRow,lastRow)                              
083          if pivotRow >= lastRow:  #In case that all rows down are zero
084              break;   
085                       
086          pivotCol = MakeColumnPivot(aMatrix,pivotRow,lastRow,pivotCol);
087          if pivotCol >= (N-1):    #In case that all rows down are zero
088              break;
089              
090          PivotDown(aMatrix,lastRow,pivotRow,pivotCol);
091             
092          pivotCol +=1; 
093         
094   
095                  
096  ######################################
097  # Test fixtures
098  ######################################                
099  class TestEGAlgorithm(unittest.TestCase):         
100      def testDoGaussianElimination_EmptyRow(self):        
101          B = [ [ 0, 0]];
102          A = [ [ 0, 0]];
103          DoGaussianElimination(A);              
104          self.assertEqual(A,B);  
105          B = [ [ 0, 0],
106                [ 0, 0]];
107          A = [ [ 0, 0],
108                [ 0, 0]];
109          DoGaussianElimination(A);              
110          self.assertEqual(A,B);                  
111          B = [ [ 0, 0],
112                [ 0, 0],
113                [ 0, 0]];
114          A = [ [ 0, 0],
115                [ 0, 0],
116                [ 0, 0]];
117          DoGaussianElimination(A);
118          self.assertEqual(A,B);
119          
120          B = [ [11,12],
121                [ 0,-1],
122                [ 0, 0]];
123          A = [ [11,12],
124                [22,23],
125                [ 0, 0]];
126          DoGaussianElimination(A);
127          self.assertEqual(A,B);                      
128          A = [ [0,  0],
129                [22,23],
130                [11,12]];
131          DoGaussianElimination(A);
132          self.assertEqual(A,B);
133          A = [ [11,12],
134                [ 0, 0],
135                [22,23]];
136          DoGaussianElimination(A);
137          self.assertEqual(A,B);         
138          
139          B = [ [11,12],
140                [ 0, 0],
141                [ 0, 0]];
142          A = [ [ 0, 0],
143                [ 0, 0],
144                [11,12]];
145          DoGaussianElimination(A);
146          self.assertEqual(A,B);
147          A = [ [11,12],
148                [ 0, 0],
149                [ 0, 0]];
150          DoGaussianElimination(A);              
151          self.assertEqual(A,B);  
152          
153      def testDoGaussianElimination_Rank(self):   
154          # M > N case
155          A = [ [0,0],     
156                [0,1],
157                [0,0],
158                [1,0]];
159          B = [ [1,0],    
160                [0,1],
161                [0,0],
162                [0,0]];
163          DoGaussianElimination(A);
164          self.assertEqual(A,B);     
165         
166          # N > M case 
167          A = [ [0,0,0,0,0,1],     
168                [0,0,0,1,0,0],
169                [0,0,0,0,0,0],
170                [1,0,0,0,0,0]];
171          B = [ [1,0,0,0,0,0],     
172                [0,0,0,1,0,0],
173                [0,0,0,0,0,1],
174                [0,0,0,0,0,0]];
175          DoGaussianElimination(A);
176          self.assertEqual(A,B);                                               
177                              
178      def testDoGaussianElimination_Column(self):    
179          A = [ [0,0,0,0,0],     
180                [0,0,0,0,0],
181                [0,0,0,0,1],
182                [0,0,1,0,0],
183                [1,0,0,0,0]];
184          B = [ [1,0,0,0,0],    
185                [0,0,1,0,0],
186                [0,0,0,0,1],
187                [0,0,0,0,0],
188                [0,0,0,0,0]];
189          DoGaussianElimination(A);
190          self.assertEqual(A,B);                         
191          
192          A = [ [0,1, 3],
193                [0,2, 4]];
194          B = [ [0,1, 3],
195                [0,0,-2]];
196          DoGaussianElimination(A);
197          self.assertEqual(A,B); 
198          
199          A = [ [0,12,0],
200                [0,22,0],
201                [0,32,0]];
202          B = [ [0,12,0],
203                [0, 0,0],
204                [0, 0,0]];              
205          DoGaussianElimination(A);
206          self.assertEqual(A,B); 
207                        
208          A = [[0,  0, 0],
209               [21,22,23],
210               [0,  0, 0]];
211          B = [[21,22,23],
212               [0,  0, 0],
213               [0,  0, 0]];              
214          DoGaussianElimination(A);
215          self.assertEqual(A,B); 
216                        
217      def testDoGaussianElimination_Textbook(self):
218          # Simple elimination example(Textbook p.12)
219          A = [ [ 2, 1, 1, 5],
220                [ 4,-6, 0,-2],
221                [-2, 7, 2, 9]];
222          B = [ [ 2, 1, 1,  5],
223                [ 0,-8,-2,-12],
224                [ 0, 0, 1,  2]]; 
225          DoGaussianElimination(A);
226          self.assertEqual(A,B);   
227          
228          # Roundoff error test(Textbook p.62)
229          A = [ [ 0.0001, 1.0, 1],
230                [    1.0, 1.0, 2]];
231          B = [ [ 0.0001,  1.0,    1],
232                [      0,-9999,-9998]];
233          DoGaussianElimination(A);
234          self.assertEqual(A,B); 
235  
236          
237      def testIsEqualToZero(self):
238          self.assertTrue(IsZero(EPSION/2.0));
239          self.assertFalse(IsZero(EPSION));
240          self.assertFalse(IsZero(EPSION+EPSION/10.0));
241                
242      def testGetPivotCoeff(self):
243          self.assertEquals(GetPivotCoeff(1,2),-2);
244          self.assertEquals(GetPivotCoeff(3,1),-1.0/3.0);
245   
246      def testIsZeroRow(self):
247          r = [0];
248          self.assertTrue(IsZeroRow(r));        
249          r = [0,0];
250          self.assertTrue(IsZeroRow(r));        
251          r = [0,0,0];
252          self.assertTrue(IsZeroRow(r));                
253  
254          r = [0,1];
255          self.assertFalse(IsZeroRow(r));
256          r = [0,0,1];
257          self.assertFalse(IsZeroRow(r));
258  
259          r = [1,0];
260          self.assertFalse(IsZeroRow(r));
261          r = [1,0,0];
262          self.assertFalse(IsZeroRow(r));
263          r = [1,0,1];
264          self.assertFalse(IsZeroRow(r));
265          
266                              
267      def testSwap(self):
268          a = [[11,12],[21,22]];
269          b = [[21,22],[11,12]];
270          SwapRow(a,0,1)
271          self.assertEquals(a,b);
272          
273          a = [[11,12]];
274          b = [[11,12]];
275          SwapRow(a,0,0)
276          self.assertEquals(a,b);
277          
278          a = [[11,12]];
279          b = [[11,12]];
280          SwapRow(a,0,0)
281          self.assertEquals(a,b);
282                          
283          a = [[11],[21]];
284          b = [[21],[11]];
285          SwapRow(a,0,1)
286          self.assertEquals(a,b);
287  
288          a = [[11],[21]];
289          b = [[21],[11]];
290          SwapRow(a,1,0)
291          self.assertEquals(a,b);
292                 
293      def testScalaRow(self):
294          a = [[11,12]];
295          b = [[110,120]];        
296          ScaleRow(a,0,10.0);
297          self.assertEquals(a,b); 
298          
299          a = [[11],[12]];
300          b = [[110],[12]];        
301          ScaleRow(a,0,10.0);
302          self.assertEquals(a,b);  
303          
304          a = [[11,12],[21,22]];
305          b = [[110,120],[21,22]];        
306          ScaleRow(a,0,10.0);
307          self.assertEquals(a,b);        
308          b = [[110,120],[210,220]];        
309          ScaleRow(a,1,10.0);
310          self.assertEquals(a,b);        
311  
312      def testCombineRow(self):    
313          a = [[11],
314               [21]];
315          b = [[2111],
316               [  21]];        
317          CombineRow(a,0,1,100);
318          self.assertEquals(a,b);         
319             
320          a = [[11,12],
321               [21,22]];
322          b = [[2111,2212],
323               [  21,  22]];        
324          CombineRow(a,0,1,100);
325          self.assertEquals(a,b);       
326          
327          a = [[11,12],
328               [21,22]];
329          b = [[  11,  12],
330               [1121,1222]];        
331          CombineRow(a,1,0,100);
332          self.assertEquals(a,b);           
333          
334                  
335  if __name__ == "__main__":
336      unittest.main();
337       

==========================End of Code=============================

Monday, June 11, 2012

Confusing SAS statements

Here are some wiered (different with other programming languge) SAS syntax:
1. IF statement in DATA steps.
eg. IF expression ;
if the expression fails, the process will skip rest statements and start over the next observation in the DATA step.
2. RETAIN and SUM expression
e.g. sumVar+ValueExpression
the initiation of SUM variable is 0, instead of missing value like other variables. When you need an other than zero initiation for sumVar, you have to use modifier RETAIN. This is not consistent grammar design.
3. Left SUBSTR
e.g. SUBSTR(TagetStr, insertPos, length)=InsertString
overloaded the function, left assigment

Monday, June 4, 2012

Note on mathematical statistics: 6.2 Rao-Cramer lower bound and efficency

Mindmap for Section 6.2 Rao-Cramer lower bound and efficiency
Download MindJet file: https://docs.google.com/open?id=0Bw64rMSoJR_Za3FFMWM1LS1QZWs

Research Project on Sampling Rare Population

Term Research Project in Sampling Theory

Title: Sampling Rare Population


Outline
============================================
* Introduction
* Methods of SRP
Disproportional Stratified Sampling
Multiple Frames
Network (Multiplicity) Sampling
Snowball Sampling
Staged methods & Screening
* Example
* Research Note
* Concluding Remarks



Download slide in PDF: https://docs.google.com/open?id=0Bw64rMSoJR_ZM3hnRWNCMVN6THc
Download Reference: https://docs.google.com/document/d/1UsYYLU66HI0PBruoTE8tu6qbwFqVWtGJwdBe4C2OWB4/edit