Hi all,
I have enhanved TwoDimensionalArray to include arithmetic for block
matrices and have an operation array2 (similar to matrix for Matrix) for
easy creation of
two-dimensional array and would suggest to include this into the next
version:
(1) -> )r array2-jg-test
A11 := matrix [[2]]
(1) [2]
Type: Matrix(Integer)
A12 := matrix [[1,2,3]]
(2) [1 2 3]
Type: Matrix(Integer)
A21 := matrix [[1],[7]]
+1+
(3) | |
+7+
Type: Matrix(Integer)
A22 := matrix [[-3,1,0],[5,5,3]]
+- 3 1 0+
(4) | |
+ 5 5 3+
Type: Matrix(Integer)
A := array2([[A11, A12],[A21, A22]])$ARRAY2(Matrix Integer)
+[2] [1 2 3] +
| |
(5) |+1+ +- 3 1 0+|
|| | | ||
++7+ + 5 5 3++
Type:
TwoDimensionalArray(Matrix(Integer))
B11 := matrix [[2]]
(6) [2]
Type: Matrix(Integer)
B21:= matrix [[2],[3], [1]]
+2+
| |
(7) |3|
| |
+1+
Type: Matrix(Integer)
B := array2 [[B11],[B21]]$ARRAY2(Matrix Integer)
+[2]+
| |
|+2+|
(8) || ||
||3||
|| ||
++1++
Type:
TwoDimensionalArray(Matrix(Integer))
A
+[2] [1 2 3] +
| |
(9) |+1+ +- 3 1 0+|
|| | | ||
++7+ + 5 5 3++
Type:
TwoDimensionalArray(Matrix(Integer))
B
+[2]+
| |
|+2+|
(10) || ||
||3||
|| ||
++1++
Type:
TwoDimensionalArray(Matrix(Integer))
A*B
+[15] +
| |
(11) |+- 1+|
|| ||
++42 ++
Type:
TwoDimensionalArray(Matrix(Integer))
--
Mit freundlichen Grüßen
Johannes Grabmeier
Prof. Dr. Johannes Grabmeier
Köckstraße 1, D-94469 Deggendorf
Tel. +49-(0)-991-2979584, Tel. +49-(0)-151-681-70756
Tel. +49-(0)-991-3615-141 (d), Fax: +49-(0)-32224-192688
--
You received this message because you are subscribed to the Google Groups
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/fricas-devel/2fa80ab2-6eb3-2a41-bb78-c397fdb08063%40grabmeier.net.
)abbrev category ARR2CAT TwoDimensionalArrayCategory
++ Two dimensional array categories and domains
++ Author:
++ Date Created: 27 October 1989
++ updated J. Grabmeier November 2019: columnSums, rowSums
++ updated J. Grabmeier August 2019: array2, *, arrayMultiply
++ Keywords: array, data structure
++ Examples:
++ References:
TwoDimensionalArrayCategory(R, Row, Col) : Category == Definition where
++ TwoDimensionalArrayCategory is a general array category which
++ allows different representations and indexing schemes.
++ Rows and columns may be extracted with rows returned as objects
++ of type Row and columns returned as objects of type Col.
++ The index of the 'first' row may be obtained by calling the
++ function 'minRowIndex'. The index of the 'first' column may
++ be obtained by calling the function 'minColIndex'. The index of
++ the first element of a 'Row' is the same as the index of the
++ first column in an array and vice versa.
R : Type
Row : IndexedAggregate(Integer, R)
Col : IndexedAggregate(Integer, R)
PI ==> PositiveInteger
NNI ==> NonNegativeInteger
LNNI ==> List(NNI)
LI ==> List(Integer)
SI ==> Segment(Integer)
LSI ==> List(SI)
Definition == Join(HomogeneousAggregate(R), _
shallowlyMutable, finiteAggregate) with
if R has Comparable then Comparable
--% Array creation
new : (NonNegativeInteger, NonNegativeInteger, R) -> %
++ new(m, n, r) is an m-by-n array all of whose entries are r
qnew : (NonNegativeInteger, NonNegativeInteger) -> %
++ qnew(m, n) is is an m-by-n uninitilized array
fill! : (%, R) -> %
++ fill!(m, r) fills m with r's
array2: List List R -> %
++ array2(lili) constructs a 2-dimensional array, the inner list being
the rows.
--% Size inquiries
minRowIndex : % -> Integer
++ minRowIndex(m) returns the index of the 'first' row of the array m
maxRowIndex : % -> Integer
++ maxRowIndex(m) returns the index of the 'last' row of the array m
minColIndex : % -> Integer
++ minColIndex(m) returns the index of the 'first' column of the array m
maxColIndex : % -> Integer
++ maxColIndex(m) returns the index of the 'last' column of the array m
nrows : % -> NonNegativeInteger
++ nrows(m) returns the number of rows in the array m
ncols : % -> NonNegativeInteger
++ ncols(m) returns the number of columns in the array m
--% Part extractions
elt : (%, Integer, Integer) -> R
++ elt(m, i, j) returns the element in the ith row and jth
++ column of the array m
++ error check to determine if indices are in proper ranges
qelt : (%, Integer, Integer) -> R
++ qelt(m, i, j) returns the element in the ith row and jth
++ column of the array m
++ NO error check to determine if indices are in proper ranges
elt : (%, Integer, Integer, R) -> R
++ elt(m, i, j, r) returns the element in the ith row and jth
++ column of the array m, if m has an ith row and a jth column,
++ and returns r otherwise
row : (%, Integer) -> Row
++ row(m, i) returns the ith row of m
++ error check to determine if index is in proper ranges
column : (%, Integer) -> Col
++ column(m, j) returns the jth column of m
++ error check to determine if index is in proper ranges
parts : % -> List R
++ parts(m) returns a list of the elements of m in row major order
listOfLists : % -> List List R
++ \spad{listOfLists(m)} returns the rows of the array m as a list
++ of lists.
subMatrix : (%, Integer, Integer, Integer, Integer) -> %
++ \spad{subMatrix(x, i1, i2, j1, j2)} extracts the submatrix
++ \spad{[x(i, j)]} where the index i ranges from \spad{i1} to \spad{i2}
++ and the index j ranges from \spad{j1} to \spad{j2}.
elt : (%, Integer, LI) -> %
++ \spad{elt(x, row, colList)} returns an 1-by-n array consisting
++ of elements of x, where \spad{n = # colList}.
++ If \spad{colList = [j<1>, j<2>, ..., j<n>]}, then the \spad{(k, l)}th
++ entry of \spad{elt(x, row, colList)} is \spad{x(row, j<l>)}.
elt : (%, LI, Integer) -> %
++ \spad{elt(x, rowList, col)} returns an m-by-1 array consisting
++ of elements of x, where \spad{m = # rowList}.
++ If \spad{rowList = [i<1>, i<2>, ..., i<m>]}, then the \spad{(k, l)}th
++ entry of \spad{elt(x, rowList, col)} is \spad{x(i<k>, col)}.
elt : (%, LI, LI) -> %
++ \spad{elt(x, rowList, colList)} returns an m-by-n array consisting
++ of elements of x, where \spad{m = # rowList} and \spad{n = # colList}.
++ If \spad{rowList = [i<1>, i<2>, ..., i<m>]} and \spad{colList =
++ [j<1>, j<2>, ..., j<n>]}, then the \spad{(k, l)}th entry of
++ \spad{elt(x, rowList, colList)} is \spad{x(i<k>, j<l>)}.
elt : (%, SI, SI) -> %
++ \spad{elt(x, s1, s2)} is equivalent to
++ \spad{elt(x, expand(s1), expand(s2))} but should be more
++ convenient and more efficient.
elt : (%, LI, SI) -> %
++ \spad{elt(x, rowList, s)} is equivalent to
++ \spad{elt(x, rowList, expand(s))} but should be more
++ convenient and more efficient.
elt : (%, SI, LI) -> %
++ \spad{elt(x, s, colList)} is equivalent to
++ \spad{elt(x, expand(s), colList)} but should be more
++ convenient and more efficient.
elt : (%, Integer, LSI) -> %
++ \spad{elt(x, row, ls2)} is equivalent to \spad{elt(x, row, l2)}
++ where l2 is obtained appending expansions of elements of ls2,
++ but should be more convenient and more efficient.
elt : (%, LSI, Integer) -> %
++ \spad{elt(x, ls1, col)} is equivalent to \spad{elt(x, l1, col)}
++ where l1 is obtained appending expansions of elements of ls1,
++ but should be more convenient and more efficient.
setelt! : (%, Integer, LSI, %) -> %
++ \spad{setelt!(x, row, ls2)} is equivalent to
++ \spad{setelt!(x, row, l2)} where l2 is obtained appending
++ expansions of elements of ls2, but should be more convenient
++ and more efficient.
setelt! : (%, LSI, Integer, %) -> %
++ \spad{setelt!(x, ls1, col)} is equivalent to
++ \spad{setelt!(x, l1, col)} where l1 is obtained appending
++ expansions of elements of ls1, but should be more convenient
++ and more efficient.
-- Works by coercing single integers to segments of integers
-- elt : (%, LI, LSI) -> %
-- elt : (%, LSI, LI) -> %
elt : (%, SI, LSI) -> %
++ \spad{elt(x, s1, ls2)} is equivalent to \spad{elt(x, l1, l2)}
++ where li is obtained appending expansions of elements of lsi,
++ but should be more convenient and more efficient.
elt : (%, LSI, SI) -> %
++ \spad{elt(x, ls1, s2)} is equivalent to \spad{elt(x, l1, l2)}
++ where li is obtained appending expansions of elements of lsi,
++ but should be more convenient and more efficient.
elt : (%, LSI, LSI) -> %
++ \spad{elt(x, ls1, ls2)} is equivalent to \spad{elt(x, l1, l2)}
++ where li is obtained appending expansions of elements of lsi,
++ but should be more convenient and more efficient.
rowSlice : % -> Segment(Integer)
++ \spad{rowSlice(m)} returns a segment s such that for
++ m the access m(s, j) gives the j-th column.
colSlice : % -> Segment(Integer)
++ \spad{colSlice(m)} returns a segment s such that for
++ m the access m(i, s) gives the i-th row.
--% Part assignments
setelt! : (%, Integer, Integer, R) -> R
++ setelt!(m, i, j, r) sets the element in the ith row and jth
++ column of m to r
++ error check to determine if indices are in proper ranges
qsetelt! : (%, Integer, Integer, R) -> R
++ qsetelt!(m, i, j, r) sets the element in the ith row and jth
++ column of m to r
++ NO error check to determine if indices are in proper ranges
setRow! : (%, Integer, Row) -> %
++ setRow!(m, i, v) sets to ith row of m to v
setColumn! : (%, Integer, Col) -> %
++ setColumn!(m, j, v) sets to jth column of m to v
setelt! : (%, Integer, LI, %) -> %
++ \spad{setelt!(x, row, colList)} assigns to an 1-by-n selection
++ of the array, where \spad{n = # colList}.
setelt! : (%, LI, Integer, %) -> %
++ \spad{setelt!(x, rowList, col)} assigns to an m-by-1 selection
++ of the array, where \spad{m = # rowList}.
setelt! : (%, List Integer, List Integer, %) -> %
++ \spad{setelt!(x, rowList, colList, y)} destructively alters
++ the array x. If y is \spad{m}-by-\spad{n},
++ \spad{rowList = [i<1>, i<2>, ..., i<m>]}
++ and \spad{colList = [j<1>, j<2>, ..., j<n>]}, then
++ \spad{x(i<k>, j<l>)}
++ is set to \spad{y(k, l)} for \spad{k = 1, ..., m} and
++ \spad{l = 1, ..., n}.
setelt! : (%, SI, SI, %) -> %
++ \spad{setelt!(x, s1, s2)} is equivalent to
++ \spad{setelt!(x, expand(s1), expand(s2))} but should be more
++ convenient and more efficient.
setelt! : (%, LI, SI, %) -> %
++ \spad{setelt!(x, l1, s2)} is equivalent to
++ \spad{setelt!(x, l1, expand(s2))} but should be more
++ convenient and more efficient.
setelt! : (%, SI, LI, %) -> %
++ \spad{setelt!(x, s1, l2)} is equivalent to
++ \spad{setelt!(x, expand(s1), l2)} but should be more
++ convenient and more efficient.
-- Works by coercing single integers to segments of integers
-- setelt! : (%, LI, LSI, %) -> %
-- setelt! : (%, LSI, LI, %) -> %
setelt! : (%, SI, LSI, %) -> %
++ \spad{setelt!(x, s1, ls2)} is equivalent to \spad{setelt!(x, l1, l2)}
++ where li is obtained appending expansions of elements of lsi,
++ but should be more convenient and more efficient.
setelt! : (%, LSI, SI, %) -> %
++ \spad{setelt!(x, ls1, s2)} is equivalent to \spad{setelt!(x, l1, l2)}
++ where li is obtained appending expansions of elements of lsi,
++ but should be more convenient and more efficient.
setelt! : (%, LSI, LSI, %) -> %
++ \spad{setelt!(x, ls1, ls1)} is equivalent to
++ \spad{setelt!(x, l1, l2)} where li is obtained appending
++ expansions of elements of lsi, but should be more convenient
++ and more efficient.
setsubMatrix! : (%, Integer, Integer, %) -> %
++ \spad{setsubMatrix(x, i1, j1, y)} destructively alters the
++ array x. Here \spad{x(i, j)} is set to \spad{y(i-i1+1, j-j1+1)} for
++ \spad{i = i1, ..., i1-1+nrows y} and \spad{j = j1, ..., j1-1+ncols y}.
-- manipulations
swapRows! : (%, Integer, Integer) -> %
++ \spad{swapRows!(m, i, j)} interchanges the \spad{i}th and \spad{j}th
++ rows of m. This destructively alters the array.
swapColumns! : (%, Integer, Integer) -> %
++ \spad{swapColumns!(m, i, j)} interchanges the \spad{i}th and
++ \spad{j}th columns of m. This destructively alters the array.
transpose : % -> %
++ \spad{transpose(m)} returns the transpose of the array m.
squareTop : % -> %
++ \spad{squareTop(m)} returns an n-by-n array consisting of the first
++ n rows of the m-by-n array m. Error: if
++ \spad{m < n}.
horizConcat : (%, %) -> %
++ \spad{horizConcat(x, y)} horizontally concatenates two arrays with
++ an equal number of rows. The entries of y appear to the right
++ of the entries of x. Error: if the arrays
++ do not have the same number of rows.
horizConcat : (List %) -> %
++ \spad{horizConcat(l)} horizontally concatenates all members of l
++ Error: if the arrays do not have the same number of rows.
vertConcat : (%, %) -> %
++ \spad{vertConcat(x, y)} vertically concatenates two arrays with an
++ equal number of columns. The entries of y appear below
++ of the entries of x. Error: if the arrays
++ do not have the same number of columns.
vertConcat : (List %) -> %
++ \spad{vertConcat(l)} vertically concatenates all members of l
++ Error: if the arrays do not have the same number of columns.
blockConcat : (List List %) -> %
++ \spad{blockConcat(ll)} concatenates arrays row and
++ column wise, building a array from blocks. The order
++ is row major as in \spad{matrix}.
vertSplit : (%, PI) -> List %
++ \spad{vertSplit(a, n)} splits a into n arrays
++ of equal size row wise.
++ Error: if number of rows of a is not divisible by n.
vertSplit : (%, LNNI) -> List %
++ \spad{vertSplit(a, [n1, ..., ni])} splits a into
++ arrays having n1, ..., ni rows.
++ Error: if number of rows of a is different than
++ n1+ ... + ni.
horizSplit : (%, PI) -> List %
++ \spad{horizSplit(a, n)} splits a into n arrays
++ of equal size column wise.
++ Error: if number of columns of a is not divisible by n.
horizSplit : (%, LNNI) -> List %
++ \spad{horizSplit(a, [n1, n2, ..., ni])} splits a into
++ arrays having n1, ..., ni columns.
++ Error: if number of columns of a is different than
++ n1 + ... + ni.
blockSplit : (%, PI, PI) -> List List %
++ \spad{blockSplit(a, n, m)} splits a into n*m
++ subarrays of equal size row and column wise, dividing
++ a into blocks.
++ Error: if number of rows of a is not divisible by n
++ or number of columns of a is not divisible by m.
blockSplit : (%, LNNI, LNNI) -> List List %
++ \spad{blockSplit(a, [n1,...,ni], [m1,...,mi])} splits a
++ into multiple subarraus row and column wise, such that
++ element at position k, l has nk rows and ml columns.
++ Error: if number of rows of a is different than
++ n1 + ... + ni or number of columns of a is different
++ than m1 + ... + mj
-- Map and Zip
map : (R -> R, %) -> %
++ map(f, a) returns \spad{b}, where \spad{b(i, j) = f(a(i, j))} for all
\spad{i, j}
map! : (R -> R, %) -> %
++ map!(f, a) assign \spad{a(i, j)} to \spad{f(a(i, j))} for all
\spad{i, j}
map : ((R, R) -> R, %, %) -> %
++ map(f, a, b) returns \spad{c}, where \spad{c(i, j) = f(a(i, j), b(i,
j))}
++ for all \spad{i, j}
map : ((R, R) -> R, %, %, R) -> %
++ map(f, a, b, r) returns \spad{c}, where \spad{c(i, j) = f(a(i, j),
b(i, j))} when both
++ \spad{a(i, j)} and \spad{b(i, j)} exist;
++ else \spad{c(i, j) = f(r, b(i, j))} when \spad{a(i, j)} does not exist;
++ else \spad{c(i, j) = f(a(i, j), r)} when \spad{b(i, j)} does not exist;
++ otherwise \spad{c(i, j) = f(r, r)}.
if R has AbelianSemiGroup then
columnSums: % -> Row
rowSums: % -> Col
if R has "*": (R, R) -> R and R has "+": (R, R) -> R then
"*": (%,%) -> %
arrayMultiply: (%,%) -> %
add
minr ==> minRowIndex
maxr ==> maxRowIndex
minc ==> minColIndex
maxc ==> maxColIndex
mini ==> minIndex
maxi ==> maxIndex
--% Predicates
import from Integer
any?(f, m) ==
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
f(qelt(m, i, j)) => return true
false
every?(f, m) ==
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
not f(qelt(m, i, j)) => return false
true
size?(m, n) == nrows(m) * ncols(m) = n
less?(m, n) == nrows(m) * ncols(m) < n
more?(m, n) == nrows(m) * ncols(m) > n
if R has Comparable then
smaller?(m1, m2) ==
mri1 := minRowIndex(m1)
mri2 := minRowIndex(m2)
mri1 < mri2 => true
mri2 < mri1 => false
minr := mri1
mri1 := maxRowIndex(m1)
mri2 := maxRowIndex(m2)
mri1 < mri2 => true
mri2 < mri1 => false
maxr := mri1
mci1 := minColIndex(m1)
mci2 := minColIndex(m2)
mci1 < mci2 => true
mci2 < mci1 => false
minc := mci1
mci1 := maxColIndex(m1)
mci2 := maxColIndex(m2)
mci1 < mci2 => true
mci2 < mci1 => false
maxc := mci1
for i in minr..maxr repeat
for j in minc..maxc repeat
el1 := m1(i, j)
el2 := m2(i, j)
smaller?(el1, el2) => return true
if not(el1 = el2) then return false
false
--% Size inquiries
# m == nrows(m) * ncols(m)
--% Part extractions
elt(m, i, j, r) ==
i < minRowIndex(m) or i > maxRowIndex(m) => r
j < minColIndex(m) or j > maxColIndex(m) => r
qelt(m, i, j)
count(f : R -> Boolean, m : %) ==
num : NonNegativeInteger := 0
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
if f(qelt(m, i, j)) then num := num + 1
num
parts m ==
entryList : List R := []
for i in maxRowIndex(m)..minRowIndex(m) by -1 repeat
for j in maxColIndex(m)..minColIndex(m) by -1 repeat
entryList := concat(qelt(m, i, j), entryList)
entryList
listOfLists x ==
ll : List List R := []
for i in maxr(x)..minr(x) by -1 repeat
l : List R := []
for j in maxc(x)..minc(x) by -1 repeat
l := cons(qelt(x, i, j), l)
ll := cons(l, ll)
ll
subMatrix(x, i1, i2, j1, j2) ==
(i2 + 1 < i1) => error "subMatrix: bad row indices"
(j2 + 1 < j1) => error "subMatrix: bad column indices"
rows := qcoerce(i2 - i1 + 1)@NonNegativeInteger
cols := qcoerce(j2 - j1 + 1)@NonNegativeInteger
y := qnew(rows, cols)
rows = 0 or cols = 0 => y
(i1 < minr(x)) or (i2 > maxr(x)) =>
error "subMatrix: index out of range"
(j1 < minc(x)) or (j2 > maxc(x)) =>
error "subMatrix: index out of range"
for i in minr(y)..maxr(y) for k in i1..i2 repeat
for j in minc(y)..maxc(y) for l in j1..j2 repeat
qsetelt!(y, i, j, qelt(x, k, l))
y
elt(x : %, row : Integer, colList : LI) ==
(row < minr(x)) or (row > maxr(x)) =>
error "elt: index out of range"
for ej in colList repeat
(ej < minc(x)) or (ej > maxc(x)) =>
error "elt: index out of range"
y := qnew(1, # colList)
for ej in colList for j in minc(y)..maxc(y) repeat
qsetelt!(y, 1, j, qelt(x, row, ej))
y
elt(x : %, rowList : LI, col : Integer) ==
for ei in rowList repeat
(ei < minr(x)) or (ei > maxr(x)) =>
error "elt: index out of range"
(col < minc(x)) or (col > maxc(x)) =>
error "elt: index out of range"
y := qnew(# rowList, 1)
for ei in rowList for i in minr(y)..maxr(y) repeat
qsetelt!(y, i, 1, qelt(x, ei, col))
y
elt(x : %, rowList : List Integer, colList : List Integer) ==
for ei in rowList repeat
(ei < minr(x)) or (ei > maxr(x)) =>
error "elt: index out of range"
for ej in colList repeat
(ej < minc(x)) or (ej > maxc(x)) =>
error "elt: index out of range"
y := qnew(# rowList, # colList)
for ei in rowList for i in minr(y)..maxr(y) repeat
for ej in colList for j in minc(y)..maxc(y) repeat
qsetelt!(y, i, j, qelt(x, ei, ej))
y
check_seg(s : SI, lb : Integer, ub : Integer) : NonNegativeInteger ==
ii := incr(s)
i1 := low(s)
i2 := high(s)
-- Empty segment:
(ii > 0 and i2 + 1 < i1) or (ii < 0 and i1 + 1 < i2) =>
error "check_seg: bad indices"
(i1 > i2 and ii > 0) or (i2 > i1 and ii < 0) => 0
-- Regular segment:
0 < ii =>
(i2 + 1 < i1) => error "check_seg: index out of range"
cc := qcoerce(i2 - i1 + ii)@NonNegativeInteger
cc < ii => cc
i1 < lb or ub < i2 =>
error "check_seg: index out of range"
ii = 1 => cc
qcoerce(cc quo ii)@NonNegativeInteger
ii < 0 =>
ii := -ii
(i1 + 1 < i2) or i2 < lb or ub < i1 =>
error "check_seg: index out of range"
cc := qcoerce(i1 - i2 + ii)@NonNegativeInteger
cc < ii => cc
i2 < lb or ub < i1 =>
error "check_seg: index out of range"
ii = 1 => cc
qcoerce(cc quo ii)@NonNegativeInteger
error "chec_seg: zero increment"
elt(x : %, rowList : LI, sc : SI) : % ==
lc := low(sc)
uc := high(sc)
ic := incr(sc)
nr := # rowList
nc := check_seg(sc, minc(x), maxc(x))
y := qnew(nr, nc)
nr = 0 or nc = 0 => y
for i in minr(y)..maxr(y) for k in rowList repeat
for j in minc(y)..maxc(y) for l in lc..uc by ic repeat
qsetelt!(y, i, j, qelt(x, k, l))
y
elt(x : %, sr : SI, colList : LI) : % ==
lr := low(sr)
ur := high(sr)
ir := incr(sr)
nr := check_seg(sr, minr(x), maxr(x))
nc := # colList
y := qnew(nr, nc)
nr = 0 or nc = 0 => y
for i in minr(y)..maxr(y) for k in lr..ur by ir repeat
for j in minc(y)..maxc(y) for l in colList repeat
qsetelt!(y, i, j, qelt(x, k, l))
y
elt(x : %, sr : SI, sc : SI) : % ==
lr := low(sr)
ur := high(sr)
lc := low(sc)
uc := high(sc)
ir := incr(sr)
ic := incr(sc)
ir = 1 and ic = 1 => subMatrix(x, lr, ur, lc, uc)
nr := check_seg(sr, minr(x), maxr(x))
nc := check_seg(sc, minc(x), maxc(x))
y := qnew(nr, nc)
nr = 0 or nc = 0 => y
for i in minr(y)..maxr(y) for k in lr..ur by ir repeat
for j in minc(y)..maxc(y) for l in lc..uc by ic repeat
qsetelt!(y, i, j, qelt(x, k, l))
y
check_segs(ls : LSI, lb : Integer, ub : Integer) : NonNegativeInteger ==
res : NonNegativeInteger := 0
for s in ls repeat
res := res + check_seg(s, lb, ub)
res
elt(x : %, row : Integer, lsc : LSI) : % ==
nc := check_segs(lsc, minc(x), maxc(x))
y := qnew(1, nc)
nc = 0 => y
j := minc(y)
for sc in lsc repeat
for l in low(sc)..high(sc) by incr(sc) repeat
qsetelt!(y, 1, j, qelt(x, row, l))
j := j + 1
y
elt(x : %, lsr : LSI, col : Integer) : % ==
nr := check_segs(lsr, minr(x), maxr(x))
y := qnew(nr, 1)
nr = 0 => y
i := minr(y)
for sr in lsr repeat
for k in low(sr)..high(sr) by incr(sr) repeat
qsetelt!(y, i, 1, qelt(x, k, col))
i := i + 1
y
elt(x : %, sr : SI, lsc : LSI) : % ==
lr := low(sr)
ur := high(sr)
ir := incr(sr)
nr := check_seg(sr, minr(x), maxr(x))
nc := check_segs(lsc, minc(x), maxc(x))
y := qnew(nr, nc)
nr = 0 or nc = 0 => y
j := minc(y)
for sc in lsc repeat
for l in low(sc)..high(sc) by incr(sc) repeat
for i in minr(y)..maxr(y) for k in lr..ur by ir repeat
qsetelt!(y, i, j, qelt(x, k, l))
j := j + 1
y
elt(x : %, lsr : LSI, sc : SI) : % ==
lc := low(sc)
uc := high(sc)
ic := incr(sc)
nr := check_segs(lsr, minr(x), maxr(x))
nc := check_seg(sc, minc(x), maxc(x))
y := qnew(nr, nc)
nr = 0 or nc = 0 => y
i := minr(y)
for sr in lsr repeat
for k in low(sr)..high(sr) by incr(sr) repeat
for j in minc(y)..maxc(y) for l in lc..uc by ic repeat
qsetelt!(y, i, j, qelt(x, k, l))
i := i + 1
y
elt(x : %, lsr : LSI, lsc : LSI) : % ==
nr := check_segs(lsr, minr(x), maxr(x))
nc := check_segs(lsc, minc(x), maxc(x))
y := qnew(nr, nc)
nr = 0 or nc = 0 => y
i := minr(y)
for sr in lsr repeat
lr := low(sr)
ur := high(sr)
ir := incr(sr)
for k in lr..ur by ir repeat
j := minc(y)
for sc in lsc repeat
for l in low(sc)..high(sc) by incr(sc) repeat
qsetelt!(y, i, j, qelt(x, k, l))
j := j + 1
i := i + 1
y
rowSlice(x :%) : Segment(Integer) ==
minr(x)..maxr(x)
colSlice(x :%) : Segment(Integer) ==
minc(x)..maxc(x)
-- Setting parts
setelt!(x : %, row : Integer, colList : LI, y : %) ==
(row < minr(x)) or (row > maxr(x)) =>
error "setelt!: index out of range"
for ej in colList repeat
(ej < minc(x)) or (ej > maxc(x)) =>
error "setelt!: index out of range"
((nrows y) ~= 1) or ((# colList) ~= (ncols y)) =>
error "setelt!: matrix has bad dimensions"
rowiy := minr(y)
for ej in colList for j in minc(y)..maxc(y) repeat
qsetelt!(x, row, ej, qelt(y, rowiy, j))
y
setelt!(x : %, rowList : LI, col : Integer, y : %) ==
for ei in rowList repeat
(ei < minr(x)) or (ei > maxr(x)) =>
error "setelt!: index out of range"
(col < minc(x)) or (col > maxc(x)) =>
error "setelt!: index out of range"
((# rowList) ~= (nrows y)) or ((ncols y) ~= 1) =>
error "setelt!: matrix has bad dimensions"
coliy := minc(y)
for ei in rowList for i in minr(y)..maxr(y) repeat
qsetelt!(x, ei, col, qelt(y, i, coliy))
y
setelt!(x : %, rowList : List Integer, colList : List Integer, y : %) ==
for ei in rowList repeat
(ei < minr(x)) or (ei > maxr(x)) =>
error "setelt!: index out of range"
for ej in colList repeat
(ej < minc(x)) or (ej > maxc(x)) =>
error "setelt!: index out of range"
((# rowList) ~= (nrows y)) or ((# colList) ~= (ncols y)) =>
error "setelt!: matrix has bad dimensions"
for ei in rowList for i in minr(y)..maxr(y) repeat
for ej in colList for j in minc(y)..maxc(y) repeat
qsetelt!(x, ei, ej, qelt(y, i, j))
y
setelt!(x : %, sr : SI, sc : SI, y : %) ==
lr := low(sr)
ur := high(sr)
lc := low(sc)
uc := high(sc)
ir := incr(sr)
ic := incr(sc)
-- ir = 1 and ic = 1 => subMatrix(x, lr, ur, lc, uc)
nr := check_seg(sr, minr(x), maxr(x))
nc := check_seg(sc, minc(x), maxc(x))
nrows(y) ~= nr or ncols(y) ~= nc =>
error "setelt!: matrix has bad dimensions"
nr = 0 or nc = 0 => y
for i in minr(y)..maxr(y) for k in lr..ur by ir repeat
for j in minc(y)..maxc(y) for l in lc..uc by ic repeat
qsetelt!(x, k, l, qelt(y, i, j))
y
setelt!(x : %, rowList : LI, sc : SI, y : %) ==
lc := low(sc)
uc := high(sc)
ic := incr(sc)
nr := # rowList
nc := check_seg(sc, minc(x), maxc(x))
nrows(y) ~= nr or ncols(y) ~= nc =>
error "setelt!: matrix has bad dimensions"
nr = 0 or nc = 0 => y
for i in minr(y)..maxr(y) for k in rowList repeat
for j in minc(y)..maxc(y) for l in lc..uc by ic repeat
qsetelt!(x, k, l, qelt(y, i, j))
y
setelt!(x : %, sr : SI, colList : LI, y : %) ==
lr := low(sr)
ur := high(sr)
ir := incr(sr)
nr := check_seg(sr, minr(x), maxr(x))
nc := # colList
nrows(y) ~= nr or ncols(y) ~= nc =>
error "setelt!: matrix has bad dimensions"
nr = 0 or nc = 0 => y
for i in minr(y)..maxr(y) for k in lr..ur by ir repeat
for j in minc(y)..maxc(y) for l in colList repeat
qsetelt!(x, k, l, qelt(y, i, j))
y
setelt!(x : %, row : Integer, lsc : LSI, y : %) ==
nc := check_segs(lsc, minc(x), maxc(x))
nrows(y) ~= 1 or ncols(y) ~= nc =>
error "setelt!: matrix has bad dimensions"
nc = 0 => y
i := minr(y)
j := minc(y)
for sc in lsc repeat
for l in low(sc)..high(sc) by incr(sc) repeat
qsetelt!(x, row, l, qelt(y, i, j))
j := j + 1
y
setelt!(x : %, lsr : LSI, col : Integer, y : %) ==
nr := check_segs(lsr, minr(x), maxr(x))
nrows(y) ~= nr or ncols(y) ~= 1 =>
error "setelt!: matrix has bad dimensions"
nr = 0 => y
i := minr(y)
j := minc(y)
for sr in lsr repeat
for k in low(sr)..high(sr) by incr(sr) repeat
qsetelt!(x, k, col, qelt(y, i, j))
i := i + 1
y
setelt!(x : %, sr : SI, lsc : LSI, y : %) ==
lr := low(sr)
ur := high(sr)
ir := incr(sr)
nr := check_seg(sr, minr(x), maxr(x))
nc := check_segs(lsc, minc(x), maxc(x))
nrows(y) ~= nr or ncols(y) ~= nc =>
error "setelt!: matrix has bad dimensions"
nr = 0 or nc = 0 => y
j := minc(y)
for sc in lsc repeat
for l in low(sc)..high(sc) by incr(sc) repeat
for i in minr(y)..maxr(y) for k in lr..ur by ir repeat
qsetelt!(x, k, l, qelt(y, i, j))
j := j + 1
y
setelt!(x : %, lsr : LSI, sc : SI, y : %) ==
lc := low(sc)
uc := high(sc)
ic := incr(sc)
nr := check_segs(lsr, minr(x), maxr(x))
nc := check_seg(sc, minc(x), maxc(x))
nrows(y) ~= nr or ncols(y) ~= nc =>
error "setelt!: matrix has bad dimensions"
nr = 0 or nc = 0 => y
i := minr(y)
for sr in lsr repeat
for k in low(sr)..high(sr) by incr(sr) repeat
for j in minc(y)..maxc(y) for l in lc..uc by ic repeat
qsetelt!(x, k, l, qelt(y, i, j))
i := i + 1
y
setelt!(x : %, lsr : LSI, lsc : LSI, y : %) ==
nr := check_segs(lsr, minr(x), maxr(x))
nc := check_segs(lsc, minc(x), maxc(x))
nrows(y) ~= nr or ncols(y) ~= nc =>
error "setelt!: matrix has bad dimensions"
nr = 0 or nc = 0 => y
i := minr(y)
for sr in lsr repeat
lr := low(sr)
ur := high(sr)
ir := incr(sr)
for k in lr..ur by ir repeat
j := minc(y)
for sc in lsc repeat
for l in low(sc)..high(sc) by incr(sc) repeat
qsetelt!(x, k, l, qelt(y, i, j))
j := j + 1
i := i + 1
y
setsubMatrix!(x, i1, j1, y) ==
i2 := i1 + nrows(y) - 1
j2 := j1 + ncols(y) - 1
(i1 < minr(x)) or (i2 > maxr(x)) =>
error "setsubMatrix!: inserted matrix too big, "
"use subMatrix to restrict it"
(j1 < minc(x)) or (j2 > maxc(x)) =>
error "setsubMatrix!: inserted matrix too big, "
"use subMatrix to restrict it"
for i in minr(y)..maxr(y) for k in i1..i2 repeat
for j in minc(y)..maxc(y) for l in j1..j2 repeat
qsetelt!(x, k, l, qelt(y, i, j))
x
-- Manipulations
swapRows!(x, i1, i2) ==
(i1 < minr(x)) or (i1 > maxr(x)) or (i2 < minr(x)) or _
(i2 > maxr(x)) => error "swapRows!: index out of range"
i1 = i2 => x
for j in minc(x)..maxc(x) repeat
r := qelt(x, i1, j)
qsetelt!(x, i1, j, qelt(x, i2, j))
qsetelt!(x, i2, j, r)
x
swapColumns!(x, j1, j2) ==
(j1 < minc(x)) or (j1 > maxc(x)) or (j2 < minc(x)) or _
(j2 > maxc(x)) => error "swapColumns!: index out of range"
j1 = j2 => x
for i in minr(x)..maxr(x) repeat
r := qelt(x, i, j1)
qsetelt!(x, i, j1, qelt(x, i, j2))
qsetelt!(x, i, j2, r)
x
transpose(x : %) ==
ans := qnew(ncols x, nrows x)
for i in minr(ans)..maxr(ans) repeat
for j in minc(ans)..maxc(ans) repeat
qsetelt!(ans, i, j, qelt(x, j, i))
ans
squareTop x ==
nrows x < (cols := ncols x) =>
error "squareTop: number of columns exceeds number of rows"
ans := qnew(cols, cols)
for i in minr(x)..(minr(x) + cols - 1) repeat
for j in minc(x)..maxc(x) repeat
qsetelt!(ans, i, j, qelt(x, i, j))
ans
horizConcat(x, y) == horizConcat([x, y])
horizConcat(la : List %) ==
empty?(la) =>
error "horizConcat: empty list"
a1 := first(la)
nr := nrows(a1)
nc := ncols(a1)
for a in rest(la) repeat
nr ~= nrows(a) =>
error "horizConcat: array must have same number of rows"
nc := nc + ncols(a)
ans := qnew(nr, nc)
for i in minr(a1)..maxr(a1) repeat
l := minc(ans)
for a in la repeat
for j in minc(a)..maxc(a) repeat
qsetelt!(ans, i, l, qelt(a, i, j))
l := l + 1
ans
vertConcat(x, y) == vertConcat([x, y])
vertConcat(la : List %) ==
empty?(la) =>
error "vertConcat: empty list"
a1 := first(la)
nr := nrows(a1)
nc := ncols(a1)
for a in rest(la) repeat
nc ~= ncols(a) =>
error "vertConcat: array must have same number of columns"
nr := nr + nrows(a)
ans := qnew(nr, nc)
l := minr(ans)
for a in la repeat
for i in minr(a)..maxr(a) repeat
for j in minc(a)..maxc(a) repeat
qsetelt!(ans, l, j, qelt(a, i, j))
l := l + 1
ans
blockConcat(LLA: List List %) : % ==
vertConcat([horizConcat(LA) for LA in LLA])
vertSplit(A : %, r : PI) : List % ==
dr := nrows(A) exquo r
dr case "failed" => error "split does not result in an equal division"
mir := minr A
mic := minc A
mac := maxc A
[ subMatrix(A, mir+i*dr, mir+(i+1)*dr-1, mic, mac) for i in 0..(r-1) ]
vertSplit(A : %, lr : LNNI) : List % ==
reduce("+", lr) ~= nrows(A) =>
error "split does not result in proper partition"
l : List NNI := cons(1, scan(_+, lr, 1$NNI)$ListFunctions2(NNI, NNI))
mir := minr(A) -1 -- additional shift because l starts at 1
mic := minc A
mac := maxc A
[subMatrix(A, mir+l(i-1), mir+l(i)-1, mic, mac) for i in 2..#l]
horizSplit(A : %, c : PI) : List % ==
dc := ncols(A) exquo c
dc case "failed" => error "split does not result in an equal division"
mir := minr A
mar := maxr A
mic := minc A
[ subMatrix(A, mir, mar, mic+i*dc, mic+(i+1)*dc-1) for i in 0..(c-1) ]
horizSplit(A : %, lc : LNNI) : List % ==
reduce("+", lc) ~= ncols(A) =>
error "split does not result in proper partition"
l : List NNI := cons(1, scan(_+, lc, 1$NNI)$ListFunctions2(NNI, NNI))
mir := minr A
mar := maxr A
mic := minc(A) -1 -- additional shift because l starts at 1
[subMatrix(A, mir, mar, mic+l(i-1), mic+l(i)-1) for i in 2..#l]
blockSplit(A : %, nr : PI, nc : PI) : List List % ==
-- The map version does not work with OpenAxiom.
--map( (X:M):(List M) +-> horizSplit(X, nc), vertSplit(A, nr)
)$ListFunctions2(M, List M)
[ horizSplit(X, nc) for X in vertSplit(A, nr) ]
blockSplit(A : %, lr : LNNI, lc : LNNI) : List List % ==
--map( (X:M):(List M) +-> horizSplit(X, lc), vertSplit(A, lr)
)$ListFunctions2(M, List M)
[horizSplit(X, lc) for X in vertSplit(A, lr)]
--% Creation
copy m ==
ans := qnew(nrows m, ncols m)
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
qsetelt!(ans, i, j, qelt(m, i, j))
ans
fill!(m, r) ==
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
qsetelt!(m, i, j, r)
m
map(f : R -> R, m : %) : % ==
ans := qnew(nrows m, ncols m)
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
qsetelt!(ans, i, j, f(qelt(m, i, j)))
ans
map!(f, m) ==
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
qsetelt!(m, i, j, f(qelt(m, i, j)))
m
map(f, m, n) ==
(nrows(m) ~= nrows(n)) or (ncols(m) ~= ncols(n)) =>
error "map: arguments must have same dimensions"
ans := qnew(nrows m, ncols m)
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
qsetelt!(ans, i, j, f(qelt(m, i, j), qelt(n, i, j)))
ans
map(f, m, n, r) ==
-- FIXME: what if minRowIndex differ?
maxRow := max(maxRowIndex m, maxRowIndex n)
maxCol := max(maxColIndex m, maxColIndex n)
ans := qnew(max(nrows m, nrows n), max(ncols m, ncols n))
for i in minRowIndex(m)..maxRow repeat
for j in minColIndex(m)..maxCol repeat
qsetelt!(ans, i, j, f(elt(m, i, j, r), elt(n, i, j, r)))
ans
setRow!(m, i, v) ==
i < minRowIndex(m) or i > maxRowIndex(m) =>
error "setRow!: index out of range"
for j in minColIndex(m)..maxColIndex(m) _
for k in minIndex(v)..maxIndex(v) repeat
qsetelt!(m, i, j, v.k)
m
setColumn!(m, j, v) ==
j < minColIndex(m) or j > maxColIndex(m) =>
error "setColumn!: index out of range"
for i in minRowIndex(m)..maxRowIndex(m) _
for k in minIndex(v)..maxIndex(v) repeat
qsetelt!(m, i, j, v.k)
m
if R has _= : (R, R) -> Boolean then
m = n ==
eq?(m, n) => true
(nrows(m) ~= nrows(n)) or (ncols(m) ~= ncols(n)) => false
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
not (qelt(m, i, j) = qelt(n, i, j)) => return false
true
member?(r, m) ==
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
qelt(m, i, j) = r => return true
false
count(r : R, m : %) == count(x +-> x = r, m)
if Row has shallowlyMutable and Row has LinearAggregate(R) then
row(m, i) ==
i < minRowIndex(m) or i > maxRowIndex(m) =>
error "row: index out of range"
(nc := ncols m) = 0 => empty()
mci := minColIndex(m)
v : Row := new(nc, qelt(m, i, mci))
for j in mci..maxColIndex(m) _
for k in minIndex(v)..maxIndex(v) repeat
qsetelt!(v, k, qelt(m, i, j))
v
if Col has shallowlyMutable and Col has LinearAggregate(R) then
column(m, j) ==
j < minColIndex(m) or j > maxColIndex(m) =>
error "column: index out of range"
(nr := nrows m) = 0 => empty()
mri := minRowIndex(m)
v : Col := new(nr, qelt(m, mri, j))
for i in mri..maxRowIndex(m) _
for k in minIndex(v)..maxIndex(v) repeat
qsetelt!(v, k, qelt(m, i, j))
v
if R has CoercibleTo(OutputForm) then
coerce(m : %) ==
l : List List OutputForm
l := [[qelt(m, i, j) :: OutputForm _
for j in minColIndex(m)..maxColIndex(m)] _
for i in minRowIndex(m)..maxRowIndex(m)]
matrix l
)abbrev domain IIARRAY2 InnerIndexedTwoDimensionalArray
InnerIndexedTwoDimensionalArray(R, mnRow, mnCol, Row, Col) : _
Exports == Implementation where
++ This is an internal type which provides an implementation of
++ 2-dimensional arrays as PrimitiveArray's of PrimitiveArray's.
R : Type
mnRow, mnCol : Integer
NNI ==> NonNegativeInteger
Row : FiniteLinearAggregate R
Col : FiniteLinearAggregate R
Exports ==> TwoDimensionalArrayCategory(R, Row, Col)
Implementation ==> add
Qsize ==> MATRIX_SIZE$Lisp
Qnew ==> MAKE_MATRIX$Lisp
Qnew1 ==> MAKE_MATRIX1$Lisp
Qnrows ==> ANROWS$Lisp
Qncols ==> ANCOLS$Lisp
Qelt2 ==> QAREF2O$Lisp
Qsetelt2 ==> QSETAREF2O$Lisp
--% Primitive array creation
empty() == Qnew(0, 0)
qnew(rows, cols) == Qnew(rows, cols)
new(rows, cols, a) == Qnew1(rows, cols, a)
array2(l: List List R): % ==
a2 := qnew(#l :: NNI, #first(l) :: NNI)
for i in 1..#l for ll in l repeat
for j in 1..#ll for r in ll repeat
qsetelt!(a2, i, j, r)
a2
--% Size inquiries
minRowIndex m == mnRow
minColIndex m == mnCol
maxRowIndex m == nrows m + mnRow - 1
maxColIndex m == ncols m + mnCol - 1
nrows m == Qnrows(m)
ncols m == Qncols(m)
--% Part selection/assignment
qelt(m, i, j) == Qelt2(m, i, j, mnRow, mnCol)
elt(m : %, i : Integer, j : Integer) ==
i < minRowIndex(m) or i > maxRowIndex(m) =>
error "elt: index out of range"
j < minColIndex(m) or j > maxColIndex(m) =>
error "elt: index out of range"
qelt(m, i, j)
qsetelt!(m, i, j, r) == Qsetelt2(m, i, j, r, mnRow, mnCol)
setelt!(m : %, i : Integer, j : Integer, r : R) ==
i < minRowIndex(m) or i > maxRowIndex(m) =>
error "setelt!: index out of range"
j < minColIndex(m) or j > maxColIndex(m) =>
error "setelt!: index out of range"
qsetelt!(m, i, j, r)
if R has SetCategory then
latex(m : %) : String ==
s : String := "\left[ \begin{array}{"
j : Integer
for j in minColIndex(m)..maxColIndex(m) repeat
s := concat(s,"c")$String
s := concat(s,"} ")$String
i : Integer
for i in minRowIndex(m)..maxRowIndex(m) repeat
for j in minColIndex(m)..maxColIndex(m) repeat
s := concat(s, latex(qelt(m, i, j))$R)$String
if j < maxColIndex(m) then s := concat(s, " & ")$String
if i < maxRowIndex(m) then s := concat(s, " \\ ")$String
concat(s, "\end{array} \right]")$String
if R has "*": (R, R) -> R and R has "+": (R, R) -> R then
arrayMultiply(x: %, y: %): % ==
(ncols x ~= nrows y) =>
error "can't multiply 2-dimensional arrays of incompatible dimensions"
ans := qnew(nrows x, ncols y)
for i in minRowIndex(x)..maxRowIndex(x) repeat
for j in minColIndex(y)..maxColIndex(y) repeat
li : List R :=
[qelt(x, i, l) * qelt(y, k, j) for l in
minColIndex(x)..maxColIndex(x)
for k in minRowIndex(y)..maxRowIndex(y) ]
entry : R := reduce("+", li)
qsetelt!(ans, i, j, entry)
ans
((x: %) * (y: %)): % == arrayMultiply(x, y)
if R has AbelianSemiGroup then
columnSums(m: %): Row ==
lLm : List List R := listOfLists m
cS : List R := []
for rw in lLm repeat cS := concat(cS, reduce(_+, rw) )
construct cS
rowSums(m: %): Col ==
lLm : List List R := listOfLists transpose m
cS : List R := []
for rw in lLm repeat cS := concat(cS, reduce(_+, rw) )
construct cS
)abbrev domain IARRAY2 IndexedTwoDimensionalArray
IndexedTwoDimensionalArray(R, mnRow, mnCol) : Exports == Implementation where
++ An IndexedTwoDimensionalArray is a 2-dimensional array where
++ the minimal row and column indices are parameters of the type.
++ Rows and columns are returned as IndexedOneDimensionalArray's with
++ minimal indices matching those of the IndexedTwoDimensionalArray.
++ The index of the 'first' row may be obtained by calling the
++ function 'minRowIndex'. The index of the 'first' column may
++ be obtained by calling the function 'minColIndex'. The index of
++ the first element of a 'Row' is the same as the index of the
++ first column in an array and vice versa.
R : Type
mnRow, mnCol : Integer
Row ==> IndexedOneDimensionalArray(R, mnCol)
Col ==> IndexedOneDimensionalArray(R, mnRow)
Exports ==> TwoDimensionalArrayCategory(R, Row, Col)
Implementation ==>
InnerIndexedTwoDimensionalArray(R, mnRow, mnCol, Row, Col)
)abbrev domain ARRAY2 TwoDimensionalArray
TwoDimensionalArray(R) : Exports == Implementation where
++ A TwoDimensionalArray is a two dimensional array with
++ 1-based indexing for both rows and columns.
R : Type
Row ==> OneDimensionalArray R
Col ==> OneDimensionalArray R
Exports ==> TwoDimensionalArrayCategory(R, Row, Col)
Implementation ==>
InnerIndexedTwoDimensionalArray(R, 1, 1, Row, Col) add
Qelt2 ==> QAREF2O$Lisp
Qsetelt2 ==> QSETAREF2O$Lisp
-- qelt and qsetelt! are logically unnecessary, but good for
-- performance
qelt(m, i, j) == Qelt2(m, i, j, 1@Integer, 1@Integer)
qsetelt!(m, i, j, r) == Qsetelt2(m, i, j, r, 1@Integer, 1@Integer)
--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
--All rights reserved.
--
--Redistribution and use in source and binary forms, with or without
--modification, are permitted provided that the following conditions are
--met:
--
-- - Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
--
-- - Redistributions in binary form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in
-- the documentation and/or other materials provided with the
-- distribution.
--
-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
-- names of its contributors may be used to endorse or promote products
-- derived from this software without specific prior written permission.
--
--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
A11 := matrix [[2]]
A12 := matrix [[1,2,3]]
A21 := matrix [[1],[7]]
A22 := matrix [[-3,1,0],[5,5,3]]
A := array2([[A11, A12],[A21, A22]])$ARRAY2(Matrix Integer)
B11 := matrix [[2]]
B21:= matrix [[2],[3], [1]]
B := array2 [[B11],[B21]]$ARRAY2(Matrix Integer)
A
B
A*B