home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume21
/
newmat02
/
part02
/
newmat6.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-01
|
11KB
|
394 lines
//$$ newmat6.cxx Operators, element access, submatrices
// Copyright (C) 1991: R B Davies and DSIR
#include "include.hxx"
#include "boolean.hxx"
typedef double real; // all floating point double
#include "newmat.hxx"
#include "newmatrc.hxx"
//#define REPORT { static ExeCounter ExeCount(__LINE__,6); ExeCount++; }
#define REPORT {}
/*************************** general utilities *************************/
static int tristore(int n) // els in triangular matrix
{ return (n*(n+1))/2; }
/****************************** operators *******************************/
real& Matrix::operator()(int m, int n)
{
if (m<=0 || m>nrows || n<=0 || n>ncols) MatrixError("Index out of range");
return store[(m-1)*ncols+n-1];
}
real& SymmetricMatrix::operator()(int m, int n)
{
if (m<=0 || n<=0 || m>nrows || n>ncols) MatrixError("Index out of range");
if (m>=n) return store[tristore(m-1)+n-1];
else return store[tristore(n-1)+m-1];
}
real& UpperTriangularMatrix::operator()(int m, int n)
{
if (m<=0 || n<m || n>ncols) MatrixError("Index out of range");
return store[(m-1)*ncols+n-1-tristore(m-1)];
}
real& LowerTriangularMatrix::operator()(int m, int n)
{
if (n<=0 || m<n || m>nrows) MatrixError("Index out of range");
return store[tristore(m-1)+n-1];
}
real& DiagonalMatrix::operator()(int m, int n)
{
if (n<=0 || m!=n || m>nrows || n>ncols) MatrixError("Index out of range");
return store[n-1];
}
real& DiagonalMatrix::operator()(int m)
{
if (m<=0 || m>nrows) MatrixError("Index out of range");
return store[m-1];
}
real& ColumnVector::operator()(int m)
{
if (m<=0 || m> nrows) MatrixError("Index out of range");
return store[m-1];
}
real& RowVector::operator()(int n)
{
if (n<=0 || n> ncols) MatrixError("Index out of range");
return store[n-1];
}
#ifndef __ZTC__
real Matrix::operator()(int m, int n) const
{
if (m<=0 || m>nrows || n<=0 || n>ncols) MatrixError("Index out of range");
return store[(m-1)*ncols+n-1];
}
real SymmetricMatrix::operator()(int m, int n) const
{
if (m<=0 || n<=0 || m>nrows || n>ncols) MatrixError("Index out of range");
if (m>=n) return store[tristore(m-1)+n-1];
else return store[tristore(n-1)+m-1];
}
real UpperTriangularMatrix::operator()(int m, int n) const
{
if (m<=0 || n<m || n>ncols) MatrixError("Index out of range");
return store[(m-1)*ncols+n-1-tristore(m-1)];
}
real LowerTriangularMatrix::operator()(int m, int n) const
{
if (n<=0 || m<n || m>nrows) MatrixError("Index out of range");
return store[tristore(m-1)+n-1];
}
real DiagonalMatrix::operator()(int m, int n) const
{
if (n<=0 || m!=n || m>nrows || n>ncols) MatrixError("Index out of range");
return store[n-1];
}
real DiagonalMatrix::operator()(int m) const
{
if (m<=0 || m>nrows) MatrixError("Index out of range");
return store[m-1];
}
real ColumnVector::operator()(int m) const
{
if (m<=0 || m> nrows) MatrixError("Index out of range");
return store[m-1];
}
real RowVector::operator()(int n) const
{
if (n<=0 || n> ncols) MatrixError("Index out of range");
return store[n-1];
}
#endif
AddedMatrix BaseMatrix::operator+(BaseMatrix& bm)
{ REPORT return AddedMatrix(this, &bm); }
MultipliedMatrix BaseMatrix::operator*(BaseMatrix& bm)
{ REPORT return MultipliedMatrix(this, &bm); }
SolvedMatrix InvertedMatrix::operator*(BaseMatrix& bmx)
{ REPORT return SolvedMatrix(bm, &bmx); }
SubtractedMatrix BaseMatrix::operator-(BaseMatrix& bm)
{ REPORT return SubtractedMatrix(this, &bm); }
ShiftedMatrix BaseMatrix::operator+(real f)
{ REPORT return ShiftedMatrix(this, f); }
ScaledMatrix BaseMatrix::operator*(real f)
{ REPORT return ScaledMatrix(this, f); }
ScaledMatrix BaseMatrix::operator/(real f)
{ REPORT return ScaledMatrix(this, 1.0/f); }
ShiftedMatrix BaseMatrix::operator-(real f)
{ REPORT return ShiftedMatrix(this, -f); }
TransposedMatrix BaseMatrix::t() { REPORT return TransposedMatrix(this); }
NegatedMatrix BaseMatrix::operator-() { REPORT return NegatedMatrix(this); }
InvertedMatrix BaseMatrix::i() { REPORT return InvertedMatrix(this); }
ConstMatrix GeneralMatrix::c() const { REPORT return ConstMatrix(this); }
RowedMatrix BaseMatrix::CopyToRow() { REPORT return RowedMatrix(this); }
ColedMatrix BaseMatrix::CopyToColumn() { REPORT return ColedMatrix(this); }
DiagedMatrix BaseMatrix::CopyToDiagonal() { REPORT return DiagedMatrix(this); }
MatedMatrix BaseMatrix::CopyToMatrix(int nrx, int ncx)
{ REPORT return MatedMatrix(this,nrx,ncx); }
GetSubMatrix BaseMatrix::SubMatrix(int first_row, int last_row, int first_col,
int last_col)
{
REPORT
int a = first_row - 1; int b = last_row - first_row + 1;
int c = first_col - 1; int d = last_col - first_col + 1;
if (a<0 || b<=0 || c<0 || d<=0) MatrixError("SubMatrix dimension error");
return GetSubMatrix(this, a, b, c, d, Type().sub());
}
GetSubMatrix BaseMatrix::SymSubMatrix(int first_row, int last_row)
{
REPORT
int a = first_row - 1; int b = last_row - first_row + 1;
if (a<0 || b<=0) MatrixError("SubMatrix dimension error");
return GetSubMatrix( this, a, b, a, b, Type().ssub());
}
GetSubMatrix BaseMatrix::Row(int first_row)
{
REPORT
int a = first_row - 1;
if (a<0) MatrixError("SubMatrix dimension error");
return GetSubMatrix(this, a, 1, 0, NcolsV(), MatrixType::RowV);
}
GetSubMatrix BaseMatrix::Rows(int first_row, int last_row)
{
REPORT
int a = first_row - 1; int b = last_row - first_row + 1;
if (a<0 || b<=0) MatrixError("SubMatrix dimension error");
return GetSubMatrix(this, a, b, 0, NcolsV(), Type().sub());
}
GetSubMatrix BaseMatrix::Col(int first_col)
{
REPORT
int c = first_col - 1;
if (c<0) MatrixError("SubMatrix dimension error");
return GetSubMatrix(this, 0, NrowsV(), c, 1, MatrixType::ColV);
}
GetSubMatrix BaseMatrix::Cols(int first_col, int last_col)
{
REPORT
int c = first_col - 1; int d = last_col - first_col + 1;
if (c<0 || d<=0) MatrixError("SubMatrix dimension error");
return GetSubMatrix(this, 0, NrowsV(), c, d, Type().sub());
}
void GeneralMatrix::operator=(real f)
{ REPORT int i=storage; real* s=store; while (i--) { *s++ = f; } }
void Matrix::operator=(BaseMatrix& X)
{ REPORT CheckConversion(X); Eq(X,MatrixType::Rect); }
void RowVector::operator=(BaseMatrix& X)
{
REPORT CheckConversion(X); Eq(X,MatrixType::RowV);
if (nrows!=1) MatrixError("Illegal conversion to row vector");
}
void ColumnVector::operator=(BaseMatrix& X)
{
REPORT CheckConversion(X); Eq(X,MatrixType::ColV);
if (ncols!=1) MatrixError("Illegal conversion to column vector");
}
void SymmetricMatrix::operator=(BaseMatrix& X)
{ REPORT CheckConversion(X); Eq(X,MatrixType::Sym); }
void UpperTriangularMatrix::operator=(BaseMatrix& X)
{ REPORT CheckConversion(X); Eq(X,MatrixType::UT); }
void LowerTriangularMatrix::operator=(BaseMatrix& X)
{ REPORT CheckConversion(X); Eq(X,MatrixType::LT); }
void DiagonalMatrix::operator=(BaseMatrix& X)
{ REPORT CheckConversion(X); Eq(X,MatrixType::Diag); }
void GeneralMatrix::operator<<(const real* r)
{
REPORT
int i = storage; real* s=store;
while(i--) *s++ = *r++;
}
/************************* element access *********************************/
real& Matrix::element(int m, int n)
{
if (m<0 || m>= nrows || n<0 || n>= ncols) MatrixError("Index out of range");
return store[m*ncols+n];
}
real& SymmetricMatrix::element(int m, int n)
{
if (m<0 || n<0 || m >= nrows || n>=ncols) MatrixError("Index out of range");
if (m>=n) return store[tristore(m)+n];
else return store[tristore(n)+m];
}
real& UpperTriangularMatrix::element(int m, int n)
{
if (m<0 || n<m || n>=ncols) MatrixError("Index out of range");
return store[m*ncols+n-tristore(m)];
}
real& LowerTriangularMatrix::element(int m, int n)
{
if (n<0 || m<n || m>=nrows) MatrixError("Index out of range");
return store[tristore(m)+n];
}
real& DiagonalMatrix::element(int m, int n)
{
if (n<0 || m!=n || m>=nrows || n>=ncols) MatrixError("Index out of range");
return store[n];
}
real& DiagonalMatrix::element(int m)
{
if (m<0 || m>=nrows) MatrixError("Index out of range");
return store[m];
}
real& ColumnVector::element(int m)
{
if (m<0 || m>= nrows) MatrixError("Index out of range");
return store[m];
}
real& RowVector::element(int n)
{
if (n<0 || n>= ncols) MatrixError("Index out of range");
return store[n];
}
/****************************** submatrices *********************************/
void GetSubMatrix::operator<<(BaseMatrix& bmx)
{
REPORT
GeneralMatrix* gmx = bmx.Evaluate();
GeneralMatrix* gm = bm->Evaluate();
if ((BaseMatrix*)gm!=bm) MatrixError("Illegal argument for SubMatrix");
if (row_number != gmx->Nrows() || col_number != gmx->Ncols())
MatrixError("Dimensions don't match");
if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
MatrixError("SubMatrix dimension error");
int i = row_number;
MatrixRow mrx(gmx, LoadOnEntry);
MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
// do need LoadOnEntry
MatrixRowCol sub;
while (i--)
{
mr.SubRowCol(sub, col_skip, col_number); // put values in sub
sub.Copy(mrx); mr.Next(); mrx.Next();
}
gmx->tDelete();
}
void GetSubMatrix::operator<<(const real* r)
{
REPORT
GeneralMatrix* gm = bm->Evaluate();
if ((BaseMatrix*)gm!=bm) MatrixError("Illegal argument for SubMatrix");
if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
MatrixError("SubMatrix dimension error");
int i = row_number;
MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
// do need LoadOnEntry
MatrixRowCol sub;
while (i--)
{
mr.SubRowCol(sub, col_skip, col_number); // put values in sub
sub.Copy(r); mr.Next();
}
}
void GetSubMatrix::operator<<(real r)
{
REPORT
GeneralMatrix* gm = bm->Evaluate();
if ((BaseMatrix*)gm!=bm) MatrixError("Illegal argument for SubMatrix");
if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
MatrixError("SubMatrix dimension error");
int i = row_number;
MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
// do need LoadOnEntry
MatrixRowCol sub;
while (i--)
{
mr.SubRowCol(sub, col_skip, col_number); // put values in sub
sub.Copy(r); mr.Next();
}
}
void GetSubMatrix::Inject(const GeneralMatrix& gmx)
{
REPORT
GeneralMatrix* gm = bm->Evaluate();
if ((BaseMatrix*)gm!=bm) MatrixError("Illegal argument for SubMatrix");
if (row_number != gmx.Nrows() || col_number != gmx.Ncols())
MatrixError("Dimensions don't match");
if (row_skip+row_number > gm->Nrows() || col_skip+col_number > gm->Ncols())
MatrixError("SubMatrix dimension error");
int i = row_number;
MatrixRow mrx((GeneralMatrix*)(&gmx), LoadOnEntry);
MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip);
// do need LoadOnEntry
MatrixRowCol sub;
while (i--)
{
mr.SubRowCol(sub, col_skip, col_number); // put values in sub
sub.Inject(mrx); mr.Next(); mrx.Next();
}
}