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 >
Wrap
Text File
|
1994-10-25
|
7KB
|
220 lines
-- Copyright (C) International Computer Science Institute, 1994. COPYRIGHT --
-- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
-- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in --
-- the file "Doc/License" of the Sather distribution. The license is also --
-- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA. --
--------> Please email comments to "sather-bugs@icsi.berkeley.edu". <----------
-- array2.sa: Two-dimensional arrays.
-------------------------------------------------------------------
class ARRAY2{T} is
-- Two-dimensional arrays of elements of type T.
private include AREF{T} aclear->aclear;
private attr asize2:INT; -- Size of the fastest changing dimension.
private asize1: INT is return(asize/asize2) end;
create(d1,d2:INT):SAME
-- A new two-dimensional array with dimensions `d1 x d2'
-- initialized to void.
pre d1>0 and d2>0 is
res::=new(d1*d2);
res.asize2:=d2;
return(res); end;
create(a: ARRAY{ARRAY{T}}): SAME
-- Create a new array with the same dimensions and values as
-- a, which is an array of arrays(rows).
-- Assume that all the rows of "a" have the same number of elements
pre a.size > 0 and a[0].size > 0 is
sz1 ::= a.size;
sz2 ::= a[0].size;
res ::= #SAME(sz1,sz2);
loop r::=sz1.times!;
loop c::=sz2.times!; res[r,c] := a[r][c]; end end;
return(res);
end;
copy: SAME
-- Return a new 2D array with the same set of values as self
pre ~void(self) and nr > 0 and nc > 0 is
res ::= #SAME(nr,nc);
res.acopy(self);
return(res);
end;
copy(a: ARRAY{ARRAY{T}}) is
-- Copy as much of a as will fit into self
loop
r::=nr.min(a.size).times!;
row ::= a[r];
loop set_row!(r,row.elt!) end end end;
aget(i1,i2:INT):T is
-- The element with indices `[i1,i2]'.
return([i1*asize2+i2]) end;
aset(i1,i2:INT,val:T) is
-- Set the element with indices `[i1,i2]' to val.
[i1*asize2+i2]:=val end;
nr: INT is
-- The size of the first dimension of the array. Number of rows
return(asize/asize2) end;
nc: INT is
-- The size of the second dimension of the array. Number of cols
return(asize2) end;
row_ind!: INT is
-- Yield each value of the first index in order. The rows
loop yield(asize1.times!); end end;
col_ind!:INT is
-- Yield each value of the second index in order. The columns
loop yield(asize2.times!); end end;
diag_elt!: T is
-- Yield values along the diagonal (square in smaller dimension)
loop ind ::= (nr.min(nc)).times!; yield([ind,ind]) end; end;
set_diag_elt!(val:T!) is
-- Set values along the diagonal (square in smaller dimension)
loop id ::= (nr.min(nc)).times!; [id,id] := val; yield; end; end;
inds!:TUP{INT,INT} is
-- Yield tuples of the indices of self in lexicographical order.
loop row ::=asize1.times!;
loop yield(#TUP{INT,INT}(row,asize2.times!)); end end end;
elt!: T is
-- Yield all elements in row major order
loop yield(aelt!) end; end;
set!(val:T!) is
-- Set all elements in row major order
loop aset!(val); yield; end end;
row_elt!(row:INT):T is
-- Yield elements by varying index 2 and holding index 1 at `row'.
-- The elements of a row "row"
loop yield(aelt!(row*nc,nc,1)); end end;
col_elt!(col:INT):T is
-- Yield elements by varying index 1 and holding index 2 at `col'.
-- The elements of a "column" col
loop yield(aelt!(col,nr,nc)); end end;
set_row!(row:INT, val:T!) is
-- Set to val elements with varying index 2 and index 1 fixed at `row'.
-- i.e. setting a row "row"
loop aset!(row*nc,nc,val); yield end end;
set_col!(col:INT, val:T!) is
-- Set to val elements with varying index 1 and index 2 fixed at `col'.
-- i.e. setting the column col
loop aset!(col,nr,nc,val); yield end end;
transpose: SAME is
-- Return a new array containing the transpose of self
res ::= #SAME(nc,nr);
res.to_transpose_of(self);
return(res) end;
to_transpose_of(a1:SAME)
-- Set self to the transpose of a1.
pre a1.nr=nc and a1.nc=nr is
loop t::=inds!; [t.t1,t.t2]:=a1[t.t2,t.t1] end;
end;
to_portion_of(a1: SAME) is
-- Copy into self as much of arg as will fit and return it. Don't
-- alter other elements.
loop r::=nr.min(a1.nr).times!;
loop set_row!(r,a1.row_elt!(r)) end end end;
end; -- class ARRAY2{T}
-------------------------------------------------------------------
class TEST_ARRAY2 is
include TEST;
-- INT and its iters should be tested before this class is tested.
main is
-- Note: Some operations are tested in the matrix class
-- (transpose, to_portion_of).
-- More convenient to do the tests there??
class_name("ARRAY2");
a ::= #ARRAY2{INT}(3,4);
test("create1 and nr",a.nr.str,"3");
test("create1 and nc",a.nc.str,"4");
ainit: ARRAY{ARRAY{INT}} := ||0,1,2,3|,|10,11,12,13|,|20,21,22,23||;
a2 ::= #ARRAY2{INT}(ainit);
test("create2 and nr",a2.nr.str,"3");
test("create2 and nc",a2.nc.str,"4");
test("aget",a2[0,2].str,"2");
test("aget",a2[0,2].str,"2");
test("aget",a2[1,3].str,"13");
test("aget[2,3]",a2[2,3].str,"23");
a2[0,2] := 3; test("aset",a2[0,2].str,"3");
a2[0,2] := 2; test("aset",a2[0,2].str,"2");
a2[1,1] := 99; test("aset",a2[1,1].str,"99");
a2[1,1] := 11; test("aset",a2[1,1].str,"11");
-- The row indices
res::=""; loop res := res+" "+a.row_ind! end;
test("row",res," 0 1 2");
res:=""; loop res := res+" "+a.col_ind! end;
test("col",res," 0 1 2 3");
res:="";
loop
res := res+" "+a.inds!.t1+","+a.inds!.t2 end;
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");
-- The 1th column of a2
res:=""; loop res := res+" "+a2.col_elt!(1) end;
test("col 1",res," 1 11 21");
-- The 2 column of a2
res:=""; loop res := res+" "+a2.col_elt!(2) end;
test("col_elt 2",res," 2 12 22");
-- The 1th row of a2
res:=""; loop res := res+" "+a2.row_elt!(1) end;
test("row 1",res," 10 11 12 13");
-- The 2 row of a2
res:=""; loop res := res+" "+a2.row_elt!(2) end;
test("row_elt 2",res," 20 21 22 23");
-- Set column 2 of b to col 1 of a2
b::=a.copy;
loop b.set_col!(2,a2.col_elt!(1)) end;
res:=""; loop res := res+" "+b.col_elt!(2) end;
test("set col 2 1 ",res," 1 11 21");
-- Set column 3 of b to col 2 of a2
b:=a.copy;
loop b.set_col!(3,a2.col_elt!(2)) end;
res:=""; loop res := res+" "+b.col_elt!(3) end;
test("set_col 3 2 ",res," 2 12 22");
-- Set row 0 of c to row 1 of a2
c::=a.copy; loop c.set_row!(0,a2.row_elt!(1)) end;
res:=""; loop res := res+" "+c.row_elt!(0) end;
test("set_row 0 1",res," 10 11 12 13");
-- Set row 1 of c to row 0 of a2
c:=a.copy; loop c.set_row!(1,a2.row_elt!(0)) end;
res:=""; loop res := res+" "+c.row_elt!(1) end;
test("set_row 1 0",res," 0 1 2 3");
finish;
end;
end;