欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

matrix.c

开放源码的编译器open watcom 1.6.0版的源代码
C
第 1 页 / 共 2 页
字号:
//
// Copyright (C) 1991 Texas Instruments Incorporated.
// Copyright (C) 1992 General Electric Company.
//
// 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, General Electric Company,
// provides this software "as is" without express or implied warranty.
//

#include <cool/Matrix.h>                        // header of matrix and its envelope

//## hack to workaround BC++ 3.1 Envelope bug
#define CoolEnvelope CoolEnvelope_Matrix

// compare_s -- Pointer operator== function
template<class Type> 
Boolean (*CoolMatrix<Type>::compare_s)(const Type&, const Type&);


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

template<class Type> 
CoolMatrix<Type>::CoolMatrix(unsigned int rows, unsigned int cols)
: CoolBase_Matrix(rows, cols) {
  this->data = new Type*[rows];                 // Allocate the row memory
  Type* columns = new Type[cols*rows];          // Allocate the array of elmts
  for (int i = 0; i < rows; i ++)               // For each row in the Matrix
    this->data[i] = &columns[i*cols];           // Fill in address of row
  if (this->compare_s == NULL)                  // If not set yet
    this->compare_s = &CoolMatrix_is_data_equal; // Default is_equal
}


// Matrix -- constructor specifiying size of matrix and initial value
// Input:    Row, Column parameters and initial value
// Output:   None

template<class Type> 
CoolMatrix<Type>::CoolMatrix(unsigned int rows, unsigned int cols,
                                    const Type& value)
: CoolBase_Matrix(rows, cols) {
  this->data = new Type*[rows];                 // Allocate the row memory
  Type* columns = new Type[cols*rows];          // Allocate the array of elmts
  for (int i = 0; i < rows; i ++) {             // For each row in the Matrix
    this->data[i] = &columns[i*cols];           // Fill in address of row
    for (int j = 0; j < cols; j++)              // For each element in column
      this->data[i][j] = value;                 // Assign initial value
  }
  if (this->compare_s == NULL)                  // If not set yet
    this->compare_s = &CoolMatrix_is_data_equal; // Default is_equal
}

// Matrix -- constructor specifiying size of matrix and initial values
// Input:    Rows, Column parameters and initial values
// Output:   None
// Note: Arguments in ... can only be pointers, primitive types like int, double,
//       and NOT OBJECTS, passed by reference or value, like vectors, matrices;
//       because constructors must be known and called at compile time!!!
//       Cannot have char in ..., because char is 1 instead of 4 bytes, and 
//       va_arg expects sizeof(Type) a multiple of 4 bytes.

template<class Type> 
CoolMatrix<Type>::CoolMatrix(unsigned int rows, unsigned int cols, int n,
                                    Type v00 ...)
: CoolBase_Matrix(rows, cols) {
#if ERROR_CHECKING
  if (((sizeof(Type) % 4) != 0) ||              // Cause alignment problems
      (sizeof(Type) > 8))                       // User defined classes?
    this->va_arg_error(#Type, sizeof(Type));    // So, cannot use this constructor
#endif
  this->data = new Type*[rows];                 // Allocate the row memory
  Type* columns = new Type[cols*rows];          // Allocate the array of elmts
  int i;
  for (i = 0; i < rows; i ++)                   // For each row in the Matrix
    this->data[i] = &columns[i*cols];           // Fill in address of row
  if (n > 0) {                                  // If user specified values
    va_list argp;                               // Declare argument list
    va_start (argp, v00);                       // Initialize macro
    for (i = 0; i < rows && n; i++)             // For remaining values given
      for (int j = 0; j < cols && n; j++, n--)  // Moving sequentially in Matrix
        if ((i == 0) && (j == 0))
          this->data[0][0] = v00;               // Hack for v00 ...
        else
          this->data[i][j] = va_arg(argp, Type); // Extract and assign
    va_end(argp);
  }
  if (this->compare_s == NULL)                  // If not set yet
    this->compare_s = &CoolMatrix_is_data_equal; // Default is_equal
}

// Matrix -- Construct a matrix from a block array of data, stored row-wise.
// Input     number of rows and columns, and array of r*c data.
// Ouput     None

template<class Type>
CoolMatrix<Type>::CoolMatrix(unsigned int rows, unsigned int cols,
                                    const Type* data_block) 
: CoolBase_Matrix(rows,cols) {
  this->data = new Type*[num_rows];             // Allocate the row memory
  int n = num_rows * num_cols;                  // Number of elements 
  Type* columns = new Type[n];                  // Allocate the array of elmts
  for (int d = 0; d < n; d++)                   // Copy all the data elements
    columns[d] = data_block[d];
  for (int i = 0; i < num_rows; i ++)           // For each row in the Matrix
    this->data[i] = &columns[i*num_cols];       // Fill in address of row
}


// Matrix -- Copy constructor
// Input:    Matrix reference
// Output:   None

template<class Type> 
CoolMatrix<Type>::CoolMatrix(const CoolMatrix<Type>& m)
: CoolBase_Matrix(m) {
  this->data = new Type*[this->num_rows];       // Allocate the row memory
  Type* columns = new Type[num_cols*num_rows];  // Allocate the array of elmts
  for (int i = 0; i < num_rows; i ++) {         // For each row in the Matrix
    this->data[i] = &columns[i*num_cols];       // Fill in address of row
    for (int j = 0; j < this->num_cols; j++)    // For each element in column
      this->data[i][j] = m.data[i][j];          // Copy value
  }
}


// ~Matrix -- Destructor for Matrix class that frees up storage
// Input:     *this
// Output:    None

template<class Type> 
CoolMatrix<Type>::~CoolMatrix() {
  delete [] this->data[0];                      // Free up the array of elmts
  delete [] this->data;                         // Free up the row memory
}

// fill -- Set all elements of a matrix to a specified fill value
// Input:  this*, reference to fill value
// Output: None

template<class Type> 
void CoolMatrix<Type>::fill (const Type& value) {
  for (int i = 0; i < this->num_rows; i++)      // For each row in the Matrix
    for (int j = 0; j < this->num_cols; j++)    // For each element in column
      this->data[i][j] = value;                 // Assign fill value
}

// operator= -- Overload the assignment operator to assign a single 
//              value to the elements of a Matrix. 
// Input:       *this, reference to a value
// Output:      Reference to updated Matrix object

template<class Type> 
CoolMatrix<Type>& CoolMatrix<Type>::operator= (const Type& value) {
  for (int i = 0; i < this->num_rows; i++)      // For each row in Matrix
    for (int j = 0; j < this->num_cols; j++)    // For each column in Matrix
      this->data[i][j] = value;                 // Assign value
  return *this;                                 // Return Matrix reference
}


// operator= -- Overload the assignment operator to copy the elements
//              in one Matrix to another. The existing storage for the 
//              destination matrix is freed up and new storage of the same 
//              size as the source is allocated.
// Input:       *this, reference to Matrix
// Output:      Reference to copied Matrix object

template<class Type> 
CoolMatrix<Type>& CoolMatrix<Type>::operator= (const CoolMatrix<Type>& m) {
  if (this != &m) {                             // make sure *this != m
    if (this->num_rows != m.num_rows || this->num_cols != m.num_cols) {
      delete [] this->data[0];                  // Free up the array of elmts
      delete [] this->data;                     // Free up the row memory
      this->num_rows = m.num_rows;              // Copy rows
      this->num_cols = m.num_cols;              // Copy columns 
      this->data = new Type*[this->num_rows];   // Allocate the rows
      Type* columns = new Type[num_cols*num_rows]; // Allocate the columns
      for (int i = 0; i < this->num_rows; i++)     // For each row
        this->data[i] = &columns[i*num_cols];      // Fill in address of row
    }
    for (int i = 0; i < this->num_rows; i++)    // For each row in the Matrix
      for (int j = 0; j < this->num_cols; j++)  // For each element in column
        this->data[i][j] = m.data[i][j];        // Copy value
  }
  return *this;                                 // Return Matrix reference
}

// operator== -- Compare the elements of two Matrices of Type Type using
//               the Compare pointer to funtion (default is ==). If one 
//               Matrix has more rows and/or columns than the other, the
//               result is FALSE
// Input:        Reference to Matrix of Type Type
// Output:       TRUE/FALSE

template<class Type> 
Boolean CoolMatrix<Type>::operator== (const CoolMatrix<Type>& m) const {
  if (this->num_rows != m.num_rows || this->num_cols != m.num_cols) // Size?
    return FALSE;                                                   // Then not equal
  for (int i = 0; i < this->num_rows; i++)                          // For each row
    for (int j = 0; j < this->num_cols; j++)                        // For each columne
      if ((*this->compare_s)(this->data[i][j],m.data[i][j]) == FALSE) // Same?
        return FALSE;                                                 // Then no match
  return TRUE;                                                // Else same, so return TRUE
}


// is_data_equal -- Default data comparison function if user has not provided
//                  another one. Note that this is not inline because we need
    //                  to take the address of it for the compare static variable
// Input:           Two Type references
// Output:          TRUE/FALSE

template<class Type>
  Boolean CoolMatrix_is_data_equal (const Type& t1, const Type& t2) {
    return (t1 == t2);
  }


// set_compare -- Specify the comparison function to be used
//                in logical tests of vector elements
// Input:         Pointer to a compare function
// Output:        None

template<class Type> 
void CoolMatrix<Type>::set_compare ( register /*Compare##*/Boolean (*c)(const Type&, const Type&)) {
  if (c == NULL)                                // If no argument supplied
    this->compare_s = &CoolMatrix_is_data_equal; // Default is_equal
  else
    this->compare_s = c;                        // Else set to user function
}

// operator<< -- Overload the output operator to print a matrix
// Input:        ostream reference, Matrix reference
// Output:       ostream reference

template<class Type>
  ostream& operator<< (ostream& s, const CoolMatrix<Type>& m) {
    for (int i = 0; i < m.rows(); i++) {        // For each row in matrix
      for (int j = 0; j < m.columns(); j++)     // For each column in matrix
        s << m.data[i][j] << " ";               // Output data element
      s << "\n";                                        // Output newline
    }
    return (s);                                 // Return ostream reference
}



// operator+= -- Destructive matrix addition of a scalar.
// Input:        this*, scalar value
// Output:       New matrix reference

template<class Type> 
CoolMatrix<Type>& CoolMatrix<Type>::operator+= (const Type& value) {
  for (int i = 0; i < this->num_rows; i++)      // For each row
    for (int j = 0; j < this->num_cols; j++)    // For each element in column
      this->data[i][j] += value;                // Add scalar
  return *this;
}

// operator*= -- Destructive matrix multiplication by a scalar.
// Input:        this*, scalar value
// Output:       New matrix reference


template<class Type> 
CoolMatrix<Type>& CoolMatrix<Type>::operator*= (const Type& value) {
  for (int i = 0; i < this->num_rows; i++)      // For each row
    for (int j = 0; j < this->num_cols; j++)    // For each element in column
      this->data[i][j] *= value;                // Multiply by scalar
  return *this;
}

// operator/= -- Destructive matrix division by a scalar.
// Input:        this*, scalar value
// Output:       New matrix reference

template<class Type> 
CoolMatrix<Type>& CoolMatrix<Type>::operator/= (const Type& value) {
  for (int i = 0; i < this->num_rows; i++)      // For each row
    for (int j = 0; j < this->num_cols; j++)    // For each element in column
      this->data[i][j] /= value;                // division by scalar
  return *this;
}


// operator+= -- Destructive matrix addition with assignment. Note that the
//               dimensions of each matrix must be identical
// Input:        this*, matrix reference
// Output:       Updated this* matrix reference

template<class Type> 
CoolMatrix<Type>& CoolMatrix<Type>::operator+= (const CoolMatrix<Type>& m) {
  if (this->num_rows != m.num_rows || this->num_cols != m.num_cols) // Size?
    this->dimension_error ("operator+=", "Type", 
                           this->num_rows, this->num_cols, m.num_rows, m.num_cols);
  for (int i = 0; i < this->num_rows; i++)      // For each row
    for (int j = 0; j < this->num_cols; j++)    // For each element in column
      this->data[i][j] += m.data[i][j];         // Add elements
  return *this;
}


// operator-= -- Destructive matrix subtraction with assignment. Note that the
//               dimensions of each matrix must be identical
// Input:        this*, matrix reference
// Output:       Updated this* matrix reference

template<class Type> 
CoolMatrix<Type>& CoolMatrix<Type>::operator-= (const CoolMatrix<Type>& m) {
  if (this->num_rows != m.num_rows || this->num_cols != m.num_cols) // Size?
    this->dimension_error ("operator-=", "Type", 
                           this->num_rows, this->num_cols, m.num_rows, m.num_cols);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -