/* * Matrix.cpp * * Created on: Jun 25, 2010 * Author: crueger */ #include "Matrix.hpp" #include "Helpers/Assert.hpp" #include "Exceptions/NotInvertibleException.hpp" #include "Helpers/fast_functions.hpp" #include "Helpers/Assert.hpp" #include "vector.hpp" #include "VectorContent.hpp" #include "MatrixContent.hpp" #include #include #include using namespace std; Matrix::Matrix() { content = new MatrixContent(); content->content = gsl_matrix_calloc(NDIM, NDIM); createViews(); } Matrix::Matrix(const double* src){ content = new MatrixContent(); content->content = gsl_matrix_alloc(NDIM, NDIM); set(0,0, src[0]); set(1,0, src[1]); set(2,0, src[2]); set(0,1, src[3]); set(1,1, src[4]); set(2,1, src[5]); set(0,2, src[6]); set(1,2, src[7]); set(2,2, src[8]); createViews(); } Matrix::Matrix(const Matrix &src){ content = new MatrixContent(); content->content = gsl_matrix_alloc(NDIM, NDIM); gsl_matrix_memcpy(content->content,src.content->content); createViews(); } Matrix::Matrix(MatrixContent* _content) : content(_content) { createViews(); } Matrix::~Matrix() { // delete all views for(int i=NDIM;i--;){ delete rows_ptr[i]; } for(int i=NDIM;i--;){ delete columns_ptr[i]; } delete diagonal_ptr; gsl_matrix_free(content->content); delete content; } void Matrix::createViews(){ // create row views for(int i=NDIM;i--;){ VectorContent *rowContent = new VectorViewContent(gsl_matrix_row(content->content,i)); rows_ptr[i] = new Vector(rowContent); } // create column views for(int i=NDIM;i--;){ VectorContent *columnContent = new VectorViewContent(gsl_matrix_column(content->content,i)); columns_ptr[i] = new Vector(columnContent); } // create diagonal view VectorContent *diagonalContent = new VectorViewContent(gsl_matrix_diagonal(content->content)); diagonal_ptr = new Vector(diagonalContent); } void Matrix::one(){ for(int i=NDIM;i--;){ for(int j=NDIM;j--;){ set(i,j,i==j); } } } Matrix &Matrix::operator=(const Matrix &src){ if(&src!=this){ gsl_matrix_memcpy(content->content,src.content->content); } return *this; } Matrix &Matrix::operator+=(const Matrix &rhs){ gsl_matrix_add(content->content, rhs.content->content); return *this; } Matrix &Matrix::operator-=(const Matrix &rhs){ gsl_matrix_sub(content->content, rhs.content->content); return *this; } Matrix &Matrix::operator*=(const Matrix &rhs){ (*this) = (*this)*rhs; return *this; } Matrix Matrix::operator+(const Matrix &rhs) const{ Matrix tmp = *this; tmp+=rhs; return tmp; } Matrix Matrix::operator-(const Matrix &rhs) const{ Matrix tmp = *this; tmp-=rhs; return tmp; } Matrix Matrix::operator*(const Matrix &rhs) const{ gsl_matrix *res = gsl_matrix_alloc(NDIM, NDIM); gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, content->content, rhs.content->content, 0.0, res); MatrixContent *content= new MatrixContent(); content->content = res; return Matrix(content); } double &Matrix::at(size_t i, size_t j){ ASSERT(i>=0&&i=0&&jcontent, i, j); } const double Matrix::at(size_t i, size_t j) const{ ASSERT(i>=0&&i=0&&jcontent, i, j); } Vector &Matrix::row(size_t i){ ASSERT(i>=0&&i=0&&i=0&&i=0&&i=0&&i=0&&jcontent,i,j,value); } double Matrix::determinant() const{ return at(0,0)*at(1,1)*at(2,2) + at(0,1)*at(1,2)*at(2,0) + at(0,2)*at(1,0)*at(2,1) - at(2,0)*at(1,1)*at(0,2) - at(2,1)*at(1,2)*at(0,0) - at(2,2)*at(1,0)*at(0,1); } Matrix Matrix::invert() const{ double det = determinant(); if(fabs(det)content, factor); return *this; } Matrix operator*(const double factor,const Matrix& mat){ Matrix tmp = mat; tmp*=factor; return tmp; } Matrix operator*(const Matrix &mat,const double factor){ return factor*mat; } bool Matrix::operator==(const Matrix &rhs) const{ for(int i=NDIM;i--;){ for(int j=NDIM;j--;){ if(fabs(at(i,j)-rhs.at(i,j))>MYEPSILON){ return false; } } } return true; } /** Blows the 6-dimensional \a cell_size array up to a full NDIM by NDIM matrix. * \param *symm 6-dim array of unique symmetric matrix components * \return allocated NDIM*NDIM array with the symmetric matrix */ Matrix ReturnFullMatrixforSymmetric(const double * const symm) { Matrix matrix; matrix.set(0,0, symm[0]); matrix.set(1,0, symm[1]); matrix.set(2,0, symm[3]); matrix.set(0,1, symm[1]); matrix.set(1,1, symm[2]); matrix.set(2,1, symm[4]); matrix.set(0,2, symm[3]); matrix.set(1,2, symm[4]); matrix.set(2,2, symm[5]); return matrix; }; ostream &operator<<(ostream &ost,const Matrix &mat){ for(int i = 0;icontent, vec.content->content, 0.0, res); VectorContent *content = new VectorContent(); content->content = res; return Vector(content); } Vector &operator*=(Vector& lhs,const Matrix &mat){ lhs = mat*lhs; return lhs; }