/***************************************************************************
* GMatrixBase.hpp - Abstract matrix base class *
* ----------------------------------------------------------------------- *
* copyright (C) 2006-2014 by Juergen Knoedlseder *
* ----------------------------------------------------------------------- *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see . *
* *
***************************************************************************/
/**
* @file GMatrixBase.hpp
* @brief Abstract matrix base class definition
* @author Juergen Knoedlseder
*/
#ifndef GMATRIXBASE_HPP
#define GMATRIXBASE_HPP
/* __ Includes ___________________________________________________________ */
#include
#include "GBase.hpp"
#include "GVector.hpp"
/***********************************************************************//**
* @class GMatrixBase
*
* @brief Abstract matrix base class interface definition
*
* This class provides the abstract interface for all matrix classes. A
* GammaLib matrix is a two dimensional array of double precision values
* that is commonly used for linear algebra computations.
*
* The matrix classes were designed in a manner so that matrices can be used
* in a natural syntax that is comparable to the syntax used for scalar
* values. In particular, the following matrix operations are available:
*
* assigned_matrix = matrix;
* assigned_matrix = value;
* added_matrix = matrix1 + matrix2;
* added_matrix += matrix;
* subtracted_matrix = matrix1 - matrix2;
* subtracted_matrix -= matrix;
* multiplied_matrix = matrix1 * matrix2;
* multiplied_matrix *= matrix;
* scaled_matrix = matrix * scale;
* scaled_matrix = scale * matrix;
* scaled_matrix *= scale;
* divided_matrix = matrix / factor;
* divided_matrix /= factor;
* negated_matrix = -matrix;
*
* where @p matrix, @p matrix1 and @p matrix2 are matrices, and
* @p value, @p scale and @p factor are double precision values. For the
* value assignment operator, each matrix element is assigned the specified
* value. For the scaling and division operators, every matrix element is
* multiplied or divided by the specified value.
*
* Matrices can also be compared using
*
* if (matrix == another_matrix) ...
* if (matrix != another_matrix) ...
*
* where identify is defined as having the same number of rows and columns
* and every element having the same value.
*
* Matrix elements are accessed using the access operators or the at() methods
*
* double element = matrix(row, column);
* double element = matrix.at(row, column);
*
* the difference being that the access operators do NOT but the at()
* methods do perform validity checking of the @p row and @p column
* arguments. Access operators and at() methods exist for non-const and
* const references.
*
* For more efficient matrix access, methods operating on matrix rows and
* columns are available. The
*
* GVector row = matrix.row(index);
* GVector column = matrix.column(index);
*
* methods return a row or a column in a GVector object, while the
*
* GVector row;
* GVector column;
* ...
* matrix.row(index, row);
* matrix.column(index, column);
*
* store a row or a column provided by a GVector object into the matrix.
* Obviously, the vector needs to be of the same size as the number of rows
* or columns available in the matrix. Adding of matrix elements row-by-row
* or column-by-column is done using the
*
* matrix.add_to_row(index, row);
* matrix.add_to_column(index, column);
*
* methods.
*
* Matrix multiplication with a vector is done using
*
* GVector vector;
* ...
* GVector product = matrix * vector;
*
* where the size of @p vector needs to be identical to the number of
* columns in the matrix.
*
* Furthermore, the following methods exist for matrix transformations:
*
* new_matrix = matrix.transpose(); // Transposes matrix
* new_matrix = matrix.invert(); // Inverts matrix
* new_vector = matrix.solve(vector); // Solves linear matrix equation
* new_matrix = matrix.abs(); // Returns matrix with all elements replaced by their absolute values
*
* The following methods allow to access matrix attributes:
*
* matrix.fill(); // Percentage of non-zero elements in matrix [0,1]
* matrix.min(); // Minimum matrix element
* matrix.max(); // Maximum matrix element
* matrix.sum(); // Sum of all matrix elements
* matrix.rows(); // Number of rows in matrix
* matrix.columns(); // Number of columns in matrix
* matrix.size(); // Number of elements in matrix
***************************************************************************/
class GMatrixBase : public GBase {
public:
// Constructors and destructors
GMatrixBase(void);
GMatrixBase(const GMatrixBase& matrix);
virtual ~GMatrixBase(void);
// Pure virtual operators
virtual double& operator()(const int& row, const int& column) = 0;
virtual const double& operator()(const int& row, const int& column) const = 0;
virtual GVector operator*(const GVector& vector) const = 0;
// Base class operators
virtual GMatrixBase& operator=(const GMatrixBase& matrix);
virtual bool operator==(const GMatrixBase& matrix) const;
virtual bool operator!=(const GMatrixBase& matrix) const;
// Pure virtual methods
virtual void clear(void) = 0;
virtual GMatrixBase* clone(void) const = 0;
virtual std::string classname(void) const = 0;
virtual double& at(const int& row, const int& column) = 0;
virtual const double& at(const int& row, const int& column) const = 0;
virtual GVector row(const int& row) const = 0;
virtual void row(const int& row, const GVector& vector) = 0;
virtual GVector column(const int& column) const = 0;
virtual void column(const int& column, const GVector& vector) = 0;
virtual void add_to_row(const int& row, const GVector& vector) = 0;
virtual void add_to_column(const int& column, const GVector& vector) = 0;
virtual double fill(void) const = 0;
virtual double min(void) const = 0;
virtual double max(void) const = 0;
virtual double sum(void) const = 0;
virtual std::string print(const GChatter& chatter = NORMAL) const = 0;
// Base class methods
const int& size(void) const;
const int& columns(void) const;
const int& rows(void) const;
protected:
// Protected methods
void init_members(void);
void copy_members(const GMatrixBase& matrix);
void free_members(void);
void select_non_zero(void);
void scale_elements(const double& scalar);
void set_all_elements(const double& value);
double get_min_element(void) const;
double get_max_element(void) const;
double get_element_sum(void) const;
std::string print_elements(const GChatter& chatter = NORMAL,
const int& num = 15) const;
std::string print_row_compression(const GChatter& chatter = NORMAL) const;
std::string print_col_compression(const GChatter& chatter = NORMAL) const;
// Protected data area
int m_rows; //!< Number of rows
int m_cols; //!< Number of columns
int m_elements; //!< Number of elements stored in matrix
int m_alloc; //!< Size of allocated matrix memory
int m_num_rowsel; //!< Number of selected rows (for compressed decomposition)
int m_num_colsel; //!< Number of selected columns (for compressed decomposition)
int* m_colstart; //!< Column start indices (m_cols+1)
int* m_rowsel; //!< Row selection (for compressed decomposition)
int* m_colsel; //!< Column selection (for compressed decomposition)
double* m_data; //!< Matrix data
};
/***********************************************************************//**
* @brief Return number of matrix elements
*
* @return Number of matrix elements.
*
* Returns the number of matrix elements that are stored in the matrix.
***************************************************************************/
inline
const int& GMatrixBase::size(void) const
{
return (m_elements);
}
/***********************************************************************//**
* @brief Return number of matrix columns
*
* @return Number of matrix columns.
*
* Returns the number of matrix columns.
***************************************************************************/
inline
const int& GMatrixBase::columns(void) const
{
return (m_cols);
}
/***********************************************************************//**
* @brief Return number of matrix rows
*
* @return Number of matrix rows.
*
* Returns the number of matrix rows.
***************************************************************************/
inline
const int& GMatrixBase::rows(void) const
{
return (m_rows);
}
#endif /* GMATRIXBASE_HPP */