A normal user should never need to know about the class DenseMatImpl; see below for notes aimed at library maintainers.
An dense martrix object is a matrix represented in the most natural
way: as a 2-dimensional array of its entries. For instance a
DenseMat of 4 rows and 3 columns will contain 12=4x3 entries.
Contrast this with the a SparseMatrix where the values (and
positions) of only the non-zero entries are recorded.
To create a DenseMat you need to specify its ring R and dimensions
(r rows and c columns). By default the matrix is filled with
zeroes; alternatively the entries may be initialized from a vector
of vector.
NewDenseMat(R, r, c) -- an r-by-c matrix filled with zero(R)
NewDenseMat(R, VV) -- a matrix whose (i,j) entry is VV[i][j]
To create a copy of a matrix, MatrixView, ConstMatrixView use the call
NewDenseMat(M);
Currently a DenseMat has no special operations in addition to those
for a general matrix. Here is a brief summary of those operations
BaseRing(M) -- the ring to which the matrix entries belong
NumRows(M) -- the number of rows in M (may be zero)
NumCols(M) -- the number of columns in M (may be zero)
cout << M -- print out the value of the matrix
M(i,j) -- a copy of entry (i,j) in the matrix
SetEntry(M,i,j,value) -- set entry (i,j) of matrix M to value
The implementation is really quite straightforward (apart from keeping
proper track of RingElemRawPtrs when exceptions may occur).
DenseMatImpl is a concrete class derived from MatrixBase (see
matrix). As such it supplies definitions for all pure virtual
functions.
DenseMatImpl represents the value of a matrix as an object of type
vector< vector<RingElemRawPtr> >
The convention used is that the outer vector has an entry for each row,
and each inner vector contains the values of that row. The indices of
a matrix entry correspond directly to the vector<> indices needed to
get at the value of that entry. The advantage of using a vector of
vector is that resizing is relatively simple (compared to mapping the
entries into a single vector whose length is equal to the total number
of matrix entries).
Note that each entry in a DenseMatImpl is a RingElemRawPtr, so
care must be taken to handle exceptions in a way which doesn't leak
memory.
A DenseMatImpl object keeps explicit track of its own size (in the data
members myNumRows and myNumColumns). This makes life easier when
handling matrices one of whose dimensions is zero. The space overhead
should normally be utterly negligible.
Member functions accepting indices use CoCoA_ASSERT to check the validity of the index values. This is useful during debugging but should cost nothing when compiled with debugging turned off.
Using RingElemRawPtr may not have been my brightest idea (because
it becomes hard to make all functions fully exception clean).
The pseudo-ctor from vector of vector should probably be a template fn; this would offer better flexibility to the user (e.g. could initialize from a vector of vector of int).
This is a first implementation: simplicity was paramount, efficiency disregarded.