Category : C++ Source Code
Archive   : BLFMATH.ZIP
Filename : MATRIX.MTH
// matrix.mth: Matrix class template methods
// Copyright(c) 1993 Azarona Software. All rights reserved.
/////////////////////////////////////////////////////////////
template
void Matrix
// Does a two-dimensional copy from m to this matrix,
// copying as much data as possible without reallocating
// this matrix. Assumes a worst case non-contiguous
// submatrix.
{
// sc = column vector pointer to rows of s
// tc = column vector pointer to rows of t
VecPtr
VecPtr
// sr = row vector pointer to columns of s
// tr = row vector pointer to columns of t
// We only need to initialize strides for now
VecPtr
VecPtr
unsigned nr = nrows;
if (nr > m.nrows) nr = m.nrows;
unsigned nc = ncols;
if (nc > m.ncols) nc = m.ncols;
for (unsigned i = 0; i
tr = tc; // Point to current row of t
sr = sc; // Point to current row of s
for (unsigned j = 0; j
tr++; // Next column
sr++; // Ditto
}
tc++; // Next row
sc++; // Ditto
}
nrows = nr; // New size of matrix, may be smaller
ncols = nc;
}
template
void Matrix
// Shares data with another matrix.
{
data.Share(m.data);
nrows = m.nrows; ncols = m.ncols;
colstride = m.colstride; rowstride = m.rowstride;
}
template
Matrix
// Constructs a row-major matrix with nr rows and nc columns.
// If size isn't zero, and s isn't zero, then we copy the
// low-level C array s into the matrix. If null vector is
// returned from data constructor, we set up the matrix
// null as well.
: data(nr * nc, s)
{
if (data.IsNull()) {
nrows = 0; ncols = 0; colstride = 1; rowstride = 1;
}
else {
nrows = nr; ncols = nc; colstride = nc; rowstride = 1;
}
}
template
Matrix
// Copy constructor that shares all of the matrix m.
: data(m.data)
{
if (data.IsNull()) {
nrows = 0; ncols = 0; colstride = 1; rowstride = 1;
}
else {
nrows = m.nrows; ncols = m.ncols;
colstride = m.colstride; rowstride = m.rowstride;
}
}
template
Matrix
unsigned sr, unsigned sc,
unsigned nr, unsigned nc)
// Constructor that constructs a submatrix of matrix m.
// If styp==SHARED, it means to share the data with m.
// NOTE: If sharing, we initially create a null vector, and
// then we immediately rebind to shared vector. If copying,
// a row-major sub matrix is created, and if nr == 0,
// then m.nrows is used. If nc == 0, then m.ncols is used.
// WARNING: No checks are made on the consistency of the
// input parameters. Caller beware.
: data((styp == SHARED) ?
0 : ((nr ? nr : m.nrows) * (nc ? nc : m.ncols)))
{
unsigned start_ofs, n;
if (nr) {
nrows = nr;
}
else {
nrows = m.nrows;
sr = 0;
}
if (nc) {
ncols = nc;
}
else {
ncols = m.ncols;
sc = 0;
}
if (styp == SHARED) { // Sharing
// When sharing, strides are always same as parent strides
colstride = m.colstride;
rowstride = m.rowstride;
// Compute length of underlying vector and offset
// Either colstride or rowstride == 1.
if (rowstride == 1) {
n = colstride * (nrows-1) + ncols;
}
else {
n = rowstride * (ncols-1) + nrows;
}
start_ofs = sr * colstride + rowstride * sc;
data.Share(Vector
}
else {
if (data.IsNull()) {
nrows = 0; ncols = 0; colstride = 1; rowstride = 1;
}
else {
// Setup as a row-major matrix
colstride = ncols; rowstride = 1;
// Copy data from shared submatrix into allocated space
// Note that the constructor is called recursively here,
// to create a shared submatrix used for the copy.
Copy(Matrix
}
}
}
template
Matrix
// Return a clone of this matrix. This clone will
// be unique, (with vector rep refcnt = 1), and
// will be row-major. (THus, it's not precisely a clone.)
// Note: If allocation fails, a null matrix is returned.
{
Matrix
temp.Copy(*this);
return temp;
}
template
int Matrix
// Ensures that this matrix uniquely owns its matrix data.
// (ie. the vector reference count is 1).
// Might have to copy matrix data to ensure this.
// Returns 1 if can make unique, 0 if can't (allocation
// for copy failed.)
{
if (!IsUnique()) { // Need to copy to make unique
Matrix
if (c.IsNull()) return 0; // Couldn't copy
Share(c); // Share with copy
}
return 1;
}
template
Matrix
// Returns a transpose of this matrix. Does not have to move
// the elements of the matrix around, just merely changes
// interpretation between row-major and column-major ordering.
{
Matrix
// Interchange number of rows and cols
unsigned temp = t.nrows;
t.nrows = t.ncols;
t.ncols = temp;
// Interchange row stride and column stride
temp = t.colstride;
t.colstride = t.rowstride;
t.rowstride = temp;
return t;
}
#ifndef NO_RANGE_CHECK
template
unsigned Matrix
// Check for row index being in bounds. If not in
// bounds, call the error handler.
{
if (i >= nrows) i = HandleRangeErr(i, nrows);
return i;
}
template
unsigned Matrix
// Check for column index being in bounds. If not
// in bounds, call the error handler.
{
if (i >= ncols) i = HandleRangeErr(i, ncols);
return i;
}
#endif
template
TYPE &Matrix
// Two-dimensional subscripting for non-const matrices.
// Note that either colstride or rowstride will be one.
{
return data.start[CHECKROW(r)*colstride + CHECKCOL(c)*rowstride];
}
template
const TYPE &Matrix
// Two-dimensional subscripting for const matrices.
// Note that either colstride or rowstride will be one.
{
return data.start[CHECKROW(r)*colstride + CHECKCOL(c)*rowstride];
}
template
Matrix
// Set all elements in the matrix to the value x.
// Assumes a worst case non-contiguous sub-matrix.
{
// tc = column vector pointer to rows of t
// tr = row vector pointer to columns of t
VecPtr
VecPtr
for (unsigned i = 0; i
for (unsigned j = 0; j
tr++; // Next column
}
tc++; // Next row
}
return *this;
}
template
Vector
// Return a row slice of a matrix. Remember, either colstride
// or rowstride is 1.
{
return Vector
ncols, rowstride, CHECKROW(r)*colstride);
}
template
const Vector
// Return a row slice of a matrix. Remember, either colstride
// or rowstride is 1.
{
return Vector
ncols, rowstride, CHECKROW(r)*colstride);
}
template
Vector
// Return a column slice of a matrix. Remember, either colstride
// or rowstride is 1.
{
return Vector
nrows, colstride, CHECKCOL(c)*rowstride);
}
template
const Vector
// Return a column slice of a matrix. Remember, either colstride
// or rowstride is 1.
{
return Vector
nrows, colstride, CHECKCOL(c)*rowstride);
}
template
Vector
// Return a diagonal slice of a square matrix. If the
// matrix isn't square, we use the smallest dimension
// for the diagonal length.
{
unsigned dlen = (nrows <= ncols) ? nrows : ncols;
unsigned diag_stride = (rowstride == 1) ? colstride : rowstride;
diag_stride++;
return Vector
}
template
const Vector
// Return a diagonal slice of a square matrix. If the
// matrix isn't square, we use the smallest dimension
// for the diagonal length.
{
unsigned dlen = (nrows <= ncols) ? nrows : ncols;
unsigned diag_stride = (rowstride == 1) ? colstride : rowstride;
diag_stride++;
return Vector
}
template
Vector
// Returns a 1D vector with all of the data for the matrix.
// If it isn't possible for the 1D data to be contiguous,
// (as will be the case for some submatrices), then a
// null vector is returned.
// ASSUMES either colstride or rowstride == 1.
{
if (ncols == colstride || nrows == rowstride)
return Vector
else return Vector
}
template
const Vector
// Returns a 1D vector with all of the data for the matrix.
// If it isn't possible for the 1D data to be contiguous,
// (as will be the case for some submatrices), then a
// null vector is returned.
// ASSUMES either colstride or rowstride == 1.
{
if (ncols == colstride || nrows == rowstride)
return Vector
else return Vector
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/