//
// Copyright (C) 1991 Texas Instruments Incorporated.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated provides this software "as is" without
// express or implied warranty.
//
// Created: MBN 09/11/89 -- Initial design and implementation
// Updated: MJF 03/12/90 -- Added group names to RAISE
//
// The parameterized Matrix<Type>  class is publicly   derived from the  Matrix
// class and implements two dimensional arithmetic matrices of a user specified
// type.   This is accompilshed by using  the parameterized  type capability of
// C++.  The only constraint placed on the type  is  that it must  overload the
// following operators: +, -,  *,  and /. Thus, it will  be possible to have  a
// matrix of  type Complex.  The Matrix<Type> class  is static in size, that is
// once a  Matrix<Type> of  a particular  size has been   declared, there is no
// dynamic growth or resize method available.
//
// The Matrix class is the base class for the parameterized  Matrix<Type> class
// and implements all non-type specific functionality. The private data section
// contains two slots to maintain  the row  and column specification. There are
// two constructors  for  the Matrix  class. The   first   takes  two arguments
// specifying the number of rows and columns. The second takes a reference to a
// Matrix object and  reproduces its state. There  are  two public methods that
// provide accessors to the row  and column slots.  Finally, there are  several
// private  methods  that  are called   by the   parameterized class to  handle
// exceptions.

#ifndef BASE_MATRIXH				// If no Matrix class,
#include <cool/Base_Matrix.h>			// Include header file
#endif	

// Matrix -- Constructor specifiying size of matrix
// Input:    Row, Column parameters
// Output:   None

Matrix::Matrix (int row, int col) {
#if ERROR_CHECKING
  if (row <= 0)					// If invalid size specified
    RAISE (Error, SYM(Matrix), SYM(Invalid_Row),
	   "Matrix::Matrix(): Invalid size %d specified for row", row);
  if (col <= 0)					// If invalid size specified
    RAISE (Error, SYM(Matrix), SYM(Invalid_Col),
	   "Matrix::Matrix(): Invalid size %d specified for column", col);
#endif
  this->num_rows = row;				// Save row count
  this->num_cols = col;				// Save column count
}


// Matrix -- Constructor for reference to another Matrix object
// Input:    Matrix reference
// Output:   None

Matrix::Matrix (const Matrix& m) {
  this->num_rows = m.num_rows;			// Copy row size
  this->num_cols = m.num_cols;			// Copy column size
}


// Matrix -- Destructor for Matrix
// Input:    None
// Output:   None

Matrix::~Matrix () {;}


// get_row_error -- Raise exception for Matrix<Type>::get (row,col) method
// Input:           Type string, row specification
// Output:          None

void Matrix::get_row_error (const char* Type, int r) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Row),
	 "Matrix<%s>::get(): Invalid size %d specified for row", Type, r);
}


// get_col_error -- Raise exception for Matrix<Type>::get (row,col) method
// Input:           Type string, column specification
// Output:          None

void Matrix::get_col_error (const char* Type, int c) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Col),
	 "Matrix<%s>::get(): Invalid size %d specified for column", Type, c);
}


// put_row_error -- Raise exception for Matrix<Type>::put (row,col,value)
// Input:           Type string, row specification
// Output:          None

void Matrix::put_row_error (const char* Type, int r) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Row),
	 "Matrix<%s>::put(): Invalid size %d specified for row", Type, r);
}


// put_col_error -- Raise exception for Matrix<Type>::put (row,col,value)
// Input:           Type string, column specification
// Output:          None

void Matrix::put_col_error (const char* Type, int c) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Col),
	 "Matrix<%s>::put(): Invalid size %d specified for column",Type,c);
}


// op_plus_error -- Raise exception for Matrix<Type>::operator+() method
// Input:           Type string, rowXcol,rowXcol
// Output:          None

void Matrix::op_plus_error (const char* Type, int r1, int c1, int r2, int c2) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Dim),
       "Matrix<%s>::operator+(): Dimensions [%d,%d] and [%d,%d] are different",
	 Type, r1, c1, r2, c2);
}


// op_mult_error -- Raise exception for Matrix<Type>::operator*() method
// Input:           Type string, rowXcol,rowXcol
// Output:          None

void Matrix::op_mult_error (const char* Type, int r1, int c1, int r2, int c2) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Dim),
       "Matrix<%s>::operator*(): Dimensions [%d,%d] and [%d,%d] are different",
	 Type, r1, c1, r2, c2);
}


// op_plus_assign_error -- Raise exception for Matrix<Type>::operator+=()
// Input:                  Type string, rowXcol,rowXcol
// Output:                 None

void Matrix::op_plus_assign_error(const char* Type,int r1,int c1,int r2,int c2) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Dim),
      "Matrix<%s>::operator+=(): Dimensions [%d,%d] and [%d,%d] are different",
	 Type, r1, c1, r2, c2);
}


// op_mult_assign_error -- Raise exception for Matrix<Type>::operator*=()
// Input:                  Type string, rowXcol,rowXcol
// Output:                 None

void Matrix::op_mult_assign_error(const char* Type,int r1,int c1,int r2,int c2) CONST {
  RAISE (Error, SYM(Matrix), SYM(Invalid_Dim),
      "Matrix<%s>::operator*=(): Dimensions [%d,%d] and [%d,%d] are different",
	 Type, r1, c1, r2, c2);
}
