/*
* MatrixContent.hpp
*
* Created on: Jul 2, 2010
* Author: crueger
*/
#ifndef MATRIXCONTENT_HPP_
#define MATRIXCONTENT_HPP_
/** MatrixContent is a wrapper for gsl_matrix.
*
* The GNU Scientific Library contaisn some very well written routines for
* linear algebra problems. However, it's syntax is C and hence it does not
* lend itself to readable written code, i.e. C = A * B, where A, B, and C
* are all matrices. Writing code this way is very convenient, concise and
* also in the same manner as one would type in MatLab.
* However, with C++ and its feature to overload functions and its operator
* functions such syntax is easy to create.
*
* Hence, this class is a C++ wrapper to gsl_matrix. There already some other
* libraries, however they fall short for the following reasons:
* -# gslwrap: not very well written and uses floats instead of doubles
* -# gslcpp: last change is from 2007 and only very few commits
* -# o2scl: basically, the same functionality as gsl only written in C++,
* however it uses GPLv3 license which is inconvenient for MoleCuilder.
*
*
Howto use MatrixContent
*
* One should not use MatrixContent directly but either have it as a member
* variable in a specialized class or inherit from it.
*
*/
#include
#include
#include "LinearAlgebra/MatrixVector_ops.hpp"
class VectorContent;
/** Dummy structure to create a unique signature.
*
*/
struct MatrixBaseCase{};
class MatrixContent
{
friend std::ostream & operator<<(std::ostream &ost, const MatrixContent &mat);
friend class RealSpaceMatrix;
friend class LinearSystemOfEquations;
// matrix vector products
friend VectorContent const operator*(const VectorContent& vec, const MatrixContent& mat);
friend VectorContent const operator*(const MatrixContent& mat, const VectorContent& vec);
// unit tests
friend class MatrixContentTest;
friend class MatrixContentSymmetricTest;
public:
MatrixContent(size_t rows, size_t columns);
MatrixContent(size_t _rows, size_t _columns, MatrixBaseCase);
MatrixContent(size_t rows, size_t columns, const double *src);
MatrixContent(gsl_matrix *&src);
MatrixContent(const MatrixContent &src);
MatrixContent(const MatrixContent *src);
virtual ~MatrixContent();
// Accessing
double &at(size_t i, size_t j);
const double at(size_t i, size_t j) const;
void set(size_t i, size_t j, const double value);
// Initializing
void setFromDoubleArray(double * x);
void setIdentity();
void setValue(double _value);
void setZero();
// Exchanging elements
bool SwapRows(size_t i, size_t j);
bool SwapColumns(size_t i, size_t j);
bool SwapRowColumn(size_t i, size_t j);
// Transformations
MatrixContent transpose() const;
MatrixContent &transpose();
gsl_vector* transformToEigenbasis();
void sortEigenbasis(gsl_vector *eigenvalues);
// Properties
bool IsNull() const;
bool IsPositive() const;
bool IsNegative() const;
bool IsNonNegative() const;
bool IsPositiveDefinite() const;
double Determinant() const;
// Operators
MatrixContent &operator=(const MatrixContent &src);
const MatrixContent &operator+=(const MatrixContent &rhs);
const MatrixContent &operator-=(const MatrixContent &rhs);
const MatrixContent &operator*=(const MatrixContent &rhs);
const MatrixContent operator*(const MatrixContent &rhs) const;
const MatrixContent &operator&=(const MatrixContent &rhs);
const MatrixContent operator&(const MatrixContent &rhs) const;
const MatrixContent &operator*=(const double factor);
bool operator==(const MatrixContent &rhs) const;
const size_t getRows() const;
const size_t getColumns() const;
VectorContent *getColumnVector(size_t column) const;
VectorContent *getRowVector(size_t row) const;
VectorContent *getDiagonalVector() const;
protected:
double *Pointer(size_t m, size_t n);
const double *const_Pointer(size_t m, size_t n) const;
gsl_matrix * content;
const size_t rows; // store for internal purposes
const size_t columns; // store for internal purposes
private:
};
const MatrixContent operator*(const double factor,const MatrixContent& mat);
const MatrixContent operator*(const MatrixContent &mat,const double factor);
std::ostream & operator<<(std::ostream &ost, const MatrixContent &mat);
/** Matrix view.
* Extension of MatrixContent to contain not a gsl_matrix but only a view on a
* gsl_matrix
*
* We need the above MatrixBaseCase here:
* content, i.e. the gsl_matrix, must not be allocated, as it is just a view
* with an internal gsl_matrix_view. Hence, MatrixBaseCase is just dummy class
* to give the constructor a unique signature.
*/
struct MatrixViewContent : public MatrixContent
{
MatrixViewContent(gsl_matrix_view _view) :
MatrixContent(_view.matrix.size1, _view.matrix.size2, MatrixBaseCase()),
view(_view)
{
content = &view.matrix;
}
~MatrixViewContent(){
content=0;
}
gsl_matrix_view view;
};
#endif /* MATRIXCONTENT_HPP_ */