home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / LIBRARY / ARRAY2.SA < prev    next >
Text File  |  1994-10-25  |  7KB  |  220 lines

  1. -- Copyright (C) International Computer Science Institute, 1994.  COPYRIGHT  --
  2. -- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
  3. -- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in    --
  4. -- the file "Doc/License" of the Sather distribution.  The license is also   --
  5. -- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA.  --
  6. --------> Please email comments to "sather-bugs@icsi.berkeley.edu". <----------
  7.  
  8. -- array2.sa: Two-dimensional arrays.
  9.  
  10. -------------------------------------------------------------------
  11. class ARRAY2{T} is
  12.    -- Two-dimensional arrays of elements of type T.
  13.    private include AREF{T}   aclear->aclear;
  14.    
  15.    private attr asize2:INT;    -- Size of the fastest changing dimension.
  16.  
  17.    private asize1: INT is return(asize/asize2) end;
  18.    
  19.    create(d1,d2:INT):SAME 
  20.       -- A new two-dimensional array with dimensions `d1 x d2'
  21.       -- initialized to void.
  22.       pre d1>0 and d2>0 is
  23.       res::=new(d1*d2);
  24.       res.asize2:=d2;
  25.       return(res); end;
  26.  
  27.    create(a: ARRAY{ARRAY{T}}): SAME 
  28.       -- Create a new array with the same dimensions and values as
  29.       -- a, which is an array of arrays(rows). 
  30.       -- Assume that all the rows of "a" have the same number of elements
  31.       pre a.size > 0 and a[0].size > 0 is
  32.       sz1 ::= a.size;
  33.       sz2 ::= a[0].size;
  34.       res ::= #SAME(sz1,sz2);
  35.       loop r::=sz1.times!; 
  36.      loop c::=sz2.times!; res[r,c] := a[r][c]; end end;
  37.       return(res);
  38.       end;
  39.      
  40.    copy: SAME 
  41.       -- Return a new 2D array with the same set of values as self
  42.       pre ~void(self) and nr > 0 and nc > 0 is
  43.       res ::= #SAME(nr,nc);
  44.       res.acopy(self);
  45.       return(res);
  46.       end;
  47.       
  48.    copy(a: ARRAY{ARRAY{T}}) is
  49.       -- Copy as much of a as will fit into self
  50.       loop 
  51.      r::=nr.min(a.size).times!;
  52.      row ::= a[r];
  53.      loop set_row!(r,row.elt!) end end end;   
  54.  
  55.    aget(i1,i2:INT):T is
  56.       -- The element with indices `[i1,i2]'.
  57.       return([i1*asize2+i2]) end;
  58.  
  59.    aset(i1,i2:INT,val:T) is
  60.       -- Set the element with indices `[i1,i2]' to val.
  61.       [i1*asize2+i2]:=val end;      
  62.    
  63.    nr: INT is 
  64.       -- The size of the first dimension of the array. Number of rows
  65.       return(asize/asize2) end;
  66.    
  67.    nc: INT is
  68.       -- The size of the second dimension of the array. Number of cols
  69.       return(asize2) end;
  70.  
  71.    row_ind!: INT is
  72.       -- Yield each value of the first index in order. The rows
  73.       loop yield(asize1.times!); end end;
  74.    
  75.    col_ind!:INT is
  76.       -- Yield each value of the second index in order. The columns
  77.       loop yield(asize2.times!); end end;
  78.    
  79.    diag_elt!: T is
  80.       -- Yield values along the diagonal (square in smaller dimension)
  81.       loop ind ::= (nr.min(nc)).times!; yield([ind,ind]) end; end;
  82.  
  83.    set_diag_elt!(val:T!) is
  84.       -- Set values along the diagonal (square in smaller dimension)
  85.       loop id ::= (nr.min(nc)).times!; [id,id] := val; yield;  end; end;
  86.    
  87.    inds!:TUP{INT,INT} is
  88.       -- Yield tuples of the indices of self in lexicographical order.
  89.       loop row ::=asize1.times!;
  90.      loop yield(#TUP{INT,INT}(row,asize2.times!)); end end end;
  91.  
  92.    elt!: T is
  93.       -- Yield all elements in row major order
  94.       loop yield(aelt!) end; end;
  95.    
  96.    set!(val:T!) is
  97.       -- Set all elements in row major order
  98.       loop aset!(val); yield; end end;
  99.       
  100.    row_elt!(row:INT):T is
  101.       -- Yield elements by varying index 2 and holding index 1 at `row'.
  102.       -- The elements of a row "row"
  103.       loop yield(aelt!(row*nc,nc,1)); end end;
  104.  
  105.    col_elt!(col:INT):T is
  106.       -- Yield elements by varying index 1 and holding index 2 at `col'.
  107.       -- The elements of a "column" col
  108.       loop yield(aelt!(col,nr,nc)); end end;
  109.  
  110.    set_row!(row:INT, val:T!) is
  111.       -- Set to val elements with varying index 2 and index 1 fixed at `row'.
  112.       -- i.e. setting a row "row"
  113.       loop aset!(row*nc,nc,val); yield end end;
  114.  
  115.    set_col!(col:INT, val:T!) is
  116.       -- Set to val elements with varying index 1 and index 2 fixed at `col'.
  117.       -- i.e. setting the column col 
  118.       loop aset!(col,nr,nc,val); yield end end;
  119.  
  120.    transpose: SAME is
  121.       -- Return a new array containing the transpose of self
  122.       res ::= #SAME(nc,nr);
  123.       res.to_transpose_of(self);
  124.       return(res) end;
  125.    
  126.    to_transpose_of(a1:SAME)
  127.       -- Set self to the transpose of a1.
  128.       pre a1.nr=nc and a1.nc=nr is
  129.       loop t::=inds!; [t.t1,t.t2]:=a1[t.t2,t.t1] end;
  130.       end;
  131.    
  132.    to_portion_of(a1: SAME) is
  133.       -- Copy into self as much of arg as will fit and return it. Don't
  134.       -- alter other elements.
  135.       loop r::=nr.min(a1.nr).times!;
  136.      loop set_row!(r,a1.row_elt!(r)) end end end;
  137.  
  138.  
  139. end; -- class ARRAY2{T}
  140.  
  141. -------------------------------------------------------------------
  142. class TEST_ARRAY2 is
  143.    include TEST;
  144.    
  145. -- INT and its iters should be tested before this class is tested.
  146.    main is
  147.       -- Note: Some operations are tested in the matrix class
  148.       -- (transpose, to_portion_of).
  149.       -- More convenient to do the tests there??
  150.       class_name("ARRAY2");
  151.       a ::= #ARRAY2{INT}(3,4);
  152.       test("create1 and nr",a.nr.str,"3");
  153.       test("create1 and nc",a.nc.str,"4");
  154.       ainit: ARRAY{ARRAY{INT}} := ||0,1,2,3|,|10,11,12,13|,|20,21,22,23||;
  155.       a2 ::= #ARRAY2{INT}(ainit);
  156.       test("create2 and nr",a2.nr.str,"3");
  157.       test("create2 and nc",a2.nc.str,"4");
  158.       test("aget",a2[0,2].str,"2");
  159.       test("aget",a2[0,2].str,"2");
  160.       test("aget",a2[1,3].str,"13");
  161.       test("aget[2,3]",a2[2,3].str,"23");
  162.       a2[0,2] := 3; test("aset",a2[0,2].str,"3");
  163.       a2[0,2] := 2; test("aset",a2[0,2].str,"2");
  164.       a2[1,1] := 99; test("aset",a2[1,1].str,"99");
  165.       a2[1,1] := 11; test("aset",a2[1,1].str,"11");
  166.       
  167.      -- The row indices
  168.       res::="";   loop res := res+" "+a.row_ind! end;
  169.       test("row",res," 0 1 2");
  170.       res:="";  loop res := res+" "+a.col_ind! end;
  171.       test("col",res," 0 1 2 3");
  172.       res:=""; 
  173.       loop 
  174.      res := res+" "+a.inds!.t1+","+a.inds!.t2 end;
  175.       test("inds",res," 0,0 0,1 0,2 0,3 1,0 1,1 1,2 1,3 2,0 2,1 2,2 2,3");
  176.  
  177.           -- The 1th column of a2
  178.       res:="";  loop res := res+" "+a2.col_elt!(1) end;
  179.       test("col 1",res," 1 11 21");
  180.       
  181.      -- The 2 column of a2
  182.       res:="";  loop res := res+" "+a2.col_elt!(2) end;
  183.       test("col_elt 2",res," 2 12 22");
  184.       
  185.      -- The 1th row of a2
  186.       res:="";  loop res := res+" "+a2.row_elt!(1) end;
  187.       test("row 1",res," 10 11 12 13");
  188.  
  189.            -- The 2 row of a2
  190.       res:="";  loop res := res+" "+a2.row_elt!(2) end;
  191.       test("row_elt 2",res," 20 21 22 23");
  192.  
  193.      -- Set column 2 of b to col 1 of a2
  194.       b::=a.copy;        
  195.       loop b.set_col!(2,a2.col_elt!(1)) end;
  196.       res:="";  loop res := res+" "+b.col_elt!(2) end;
  197.       test("set col 2 1 ",res," 1 11 21");
  198.       
  199.            -- Set column 3 of b to col 2 of a2
  200.       b:=a.copy;        
  201.       loop b.set_col!(3,a2.col_elt!(2)) end;
  202.       res:="";  loop res := res+" "+b.col_elt!(3) end;
  203.       test("set_col 3 2 ",res," 2 12 22");
  204.  
  205.      -- Set row 0 of c  to row 1 of a2
  206.       c::=a.copy;  loop c.set_row!(0,a2.row_elt!(1)) end;
  207.       res:="";  loop res := res+" "+c.row_elt!(0) end;
  208.       test("set_row 0 1",res," 10 11 12 13");
  209.       
  210.      -- Set row 1 of c  to row 0 of a2
  211.       c:=a.copy;  loop c.set_row!(1,a2.row_elt!(0)) end;
  212.       res:="";  loop res := res+" "+c.row_elt!(1) end;
  213.       test("set_row 1 0",res," 0 1 2 3");
  214.       finish;
  215.       end;
  216.    
  217. end;
  218.    
  219.       
  220.