Skip to content
Snippets Groups Projects
fullMatrix.h 8.41 KiB
Newer Older
Christophe Geuzaine's avatar
Christophe Geuzaine committed
// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
Christophe Geuzaine's avatar
Christophe Geuzaine committed
//
// See the LICENSE.txt file for license information. Please report all
// bugs and problems to <gmsh@geuz.org>.
#ifndef _FULL_MATRIX_H_
#define _FULL_MATRIX_H_
Christophe Geuzaine's avatar
Christophe Geuzaine committed

Christophe Geuzaine's avatar
Christophe Geuzaine committed
#include <stdio.h>
#include "GmshConfig.h"
#include "GmshMessage.h"
template <class scalar> class fullMatrix;
Christophe Geuzaine's avatar
Christophe Geuzaine committed

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
template <class scalar>
class fullVector
Jean-François Remacle's avatar
Jean-François Remacle committed
{
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  int _r;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  scalar *_data;
  friend class fullMatrix<scalar>;
  fullVector(int r) : _r(r)
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    _data = new scalar[_r];
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
  fullVector(void) : _r(0),_data(0) {}
  fullVector(const fullVector<scalar> &other) : _r(other._r)
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    _data = new scalar[_r];
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    for(int i = 0; i < _r; ++i) _data[i] = other._data[i];
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
  ~fullVector() { if(_data) delete [] _data; }
  bool resize(int r)
  { 
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    if (_r < r){
      if (_data) delete[] _data;
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
      _r = r;
      _data = new scalar[_r];
      return true;
    }
    return false;
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  inline scalar operator () (int i) const
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    return _data[i];
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  inline int size() const { return _r; }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  inline scalar & operator () (int i)
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    return _data[i];
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  inline scalar norm()
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    scalar n = 0.;
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    for(int i = 0; i < _r; ++i) n += _data[i] * _data[i];
    return sqrt(n);
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  inline void scale(const scalar s)
Jean-François Remacle's avatar
Jean-François Remacle committed
  {
    if(s == 0.) 
Christophe Geuzaine's avatar
Christophe Geuzaine committed
      for(int i = 0; i < _r; ++i) _data[i] = 0.;
Christophe Geuzaine's avatar
Christophe Geuzaine committed
      for(int i = 0; i < _r; ++i) _data[i] *= s;
Jean-François Remacle's avatar
Jean-François Remacle committed
  }
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  inline scalar operator *(const fullVector<scalar> &other)
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    scalar s = 0.;
    for(int i = 0; i < _r; ++i) s += _data[i] * other._data[i];
  void axpy(fullVector<scalar> &x, scalar alpha=1.)
#if !defined(HAVE_BLAS)
  {
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    for (int i = 0; i < _r; i++) _data[i] += alpha * x._data[i];
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  void print(const char *name="") const 
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  {
    printf("Printing vector %s:\n", name);
    printf("  ");
    for(int I = 0; I < size(); I++){
Christophe Geuzaine's avatar
Christophe Geuzaine committed
      printf("%12.5E ", (*this)(I));
Jean-François Remacle's avatar
Jean-François Remacle committed
};

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
template <class scalar>
class fullMatrix
  bool _own_data; // should data be freed on delete ?
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  int _r, _c;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  scalar *_data;
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  inline scalar get(int r, int c) const { return (*this)(r, c); }
  inline void set(int r, int c, scalar v){ (*this)(r, c) = v; }
  fullMatrix(scalar *original, int r, int c)
  {
    _r = r;
    _c = c;
    _own_data = false;
    _data = original;
  }
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  fullMatrix(fullMatrix<scalar> &original, int c_start, int c)
  {
Jonathan Lambrechts's avatar
Jonathan Lambrechts committed
    _c = c;
    _r = original._r;
    _own_data = false;
Jonathan Lambrechts's avatar
Jonathan Lambrechts committed
    _data = original._data + c_start * _r;
  fullMatrix(int r, int c) : _r(r), _c(c)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    _data = new scalar[_r * _c];
    _own_data = true;
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  fullMatrix(int r, int c, double *data)
    : _r(r), _c(c), _data(data), _own_data(false)
  fullMatrix(const fullMatrix<scalar> &other) : _r(other._r), _c(other._c)
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    _data = new scalar[_r * _c];
    _own_data=true;
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    for(int i = 0; i < _r * _c; ++i) _data[i] = other._data[i];
  fullMatrix() : _own_data(false),_r(0), _c(0), _data(0) {}
  ~fullMatrix() { if(_data && _own_data) delete [] _data; }
  bool resize(int r, int c) // data will be owned (same as constructor)
  {
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    if ((r * c > _r * _c) || !_own_data){
      _r = r;
      _c = c;
      if (_own_data && _data) delete[] _data;
      _data = new scalar[_r * _c];
      _own_data = true;
      return true;
    }
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    else{
      _r = r;
      _c = c;
    return false; // no reallocation
  }
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  void setAsProxy(fullMatrix<scalar> &original, int c_start, int c)
  {
    if(_data && _own_data)
      delete [] _data;
    _c = c;
    _r = original._r;
    _own_data = false;
    _data = original._data + c_start * _r;
  }
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  inline int size1() const { return _r; }
  inline int size2() const { return _c; }
  fullMatrix<scalar> & operator = (const fullMatrix<scalar> &other)
    if(this != &other){
Christophe Geuzaine's avatar
Christophe Geuzaine committed
      _r = other._r; 
      _c = other._c;
      if (_data && _own_data) delete[] _data;
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
      if ((_r == 0) || (_c == 0))
        _data=0;
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
      else{
        _data = new scalar[_r * _c];
        for(int i = 0; i < _r * _c; ++i) _data[i] = other._data[i];
      }
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  inline scalar operator () (int i, int j) const
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    return _data[i + _r * j];
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  inline scalar & operator () (int i, int j)
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    return _data[i + _r * j];
  void copy(const fullMatrix<scalar> &a, int i0, int ni, int j0, int nj, 
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
            int desti0, int destj0)
  {
    for(int i = i0, desti = desti0; i < i0 + ni; i++, desti++)
      for(int j = j0, destj = destj0; j < j0 + nj; j++, destj++)
        (*this)(desti, destj) = a(i, j);
  }
Jonathan Lambrechts's avatar
Jonathan Lambrechts committed
  void mult(const fullMatrix<scalar> &b, fullMatrix<scalar> &c)const
#if !defined(HAVE_BLAS)
  {
    c.scale(0.);
    for(int i = 0; i < _r; i++)
      for(int j = 0; j < b.size2(); j++)
        for(int k = 0; k < _c; k++)
          c._data[i + _r * j] += (*this)(i, k) * b(k, j);
  }
#endif
  ;
  void gemm(const fullMatrix<scalar> &a, const fullMatrix<scalar> &b, 
            scalar alpha=1., scalar beta=1.)
#if !defined(HAVE_BLAS)
  {
    fullMatrix<scalar> temp(a.size1(), b.size2());
    a.mult(b, temp);
    temp.scale(alpha);
    scale(beta);
    add(temp);
  }
#endif
  ;
  inline void setAll(const scalar &m) 
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    for(int i = 0; i < _r * _c; i++) _data[i] = m;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  inline void scale(const double s)
  {
    if(s == 0.)
      for(int i = 0; i < _r * _c; ++i) _data[i] = 0.;
    else
      for(int i = 0; i < _r * _c; ++i) _data[i] *= s;
  }
  inline void add(const double &a) 
  {
    for(int i = 0; i < _r * _c; ++i) _data[i] += a;
  }
  inline void add(const fullMatrix<scalar> &m) 
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  {
    for(int i = 0; i < size1(); i++)
      for(int j = 0; j < size2(); j++)
        (*this)(i, j) += m(i, j);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  }
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  inline void add(const fullMatrix<scalar> &m, const double &a) 
Bruno Seny's avatar
Bruno Seny committed
  {
    for(int i = 0; i < size1(); i++)
      for(int j = 0; j < size2(); j++)
        (*this)(i, j) += a*m(i, j);
  }
  void mult(const fullVector<scalar> &x, fullVector<scalar> &y)
#if !defined(HAVE_BLAS)
  {
    y.scale(0.);
    for(int i = 0; i < _r; i++)
      for(int j = 0; j < _c; j++)
        y._data[i] += (*this)(i, j) * x(j);
  }
#endif
  ;
  inline fullMatrix<scalar> transpose()
    fullMatrix<scalar> T(size2(), size1());
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    for(int i = 0; i < size1(); i++)
      for(int j = 0; j < size2(); j++)
        T(j, i) = (*this)(i, j);
    return T;
  inline void transposeInPlace()
  {
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    if(size1() != size2()){
      Msg::Error("Not a square matrix (size1: %d, size2: %d)", size1(), size2());
    }
    scalar t;
    for(int i = 0; i < size1(); i++)
      for(int j = 0; j < i; j++) {
        t = _data[i + _r * j];
        _data[i + _r * j] = _data[j + _r * i];
        _data[j + _r * i] = t;
      }
  }
  bool luSolve(const fullVector<scalar> &rhs, fullVector<scalar> &result)
#if !defined(HAVE_LAPACK)
  {
    Msg::Error("LU factorization requires LAPACK");
    return false;
  }
#endif
  ;
  bool invertInPlace()
#if !defined(HAVE_LAPACK)
  {
    Msg::Error("Matrix inversion requires LAPACK");
    return false;
  }
#endif
  ;
  bool eig(fullVector<double> &eigenValReal, fullVector<double> &eigenValImag,
           fullMatrix<scalar> &leftEigenVect, fullMatrix<scalar> &rightEigenVect,
           bool sortRealPart=false)
#if !defined(HAVE_LAPACK)
  {
    Msg::Error("Eigenvalue computations requires LAPACK");
    return false;
  }
Christophe Geuzaine's avatar
Christophe Geuzaine committed
#endif
  ;
  bool invert(fullMatrix<scalar> &result)
Christophe Geuzaine's avatar
Christophe Geuzaine committed
#if !defined(HAVE_LAPACK)
  {
    Msg::Error("LU factorization requires LAPACK");
    return false;
  }
  fullMatrix<scalar> cofactor(int i, int j) const 
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  {
    int ni = size1();
    int nj = size2();
    fullMatrix<scalar> cof(ni - 1, nj - 1);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    for(int I = 0; I < ni; I++){
      for(int J = 0; J < nj; J++){
        if(J != j && I != i)
          cof(I < i ? I : I - 1, J < j ? J : J - 1) = (*this)(I, J);
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
      }
Christophe Geuzaine's avatar
Christophe Geuzaine committed
    return cof;
  }
  scalar determinant() const
#if !defined(HAVE_LAPACK)
  {
    Msg::Error("Determinant computation requires LAPACK");
    return 0.;
  }
#endif
  ;
  bool svd(fullMatrix<scalar> &V, fullVector<scalar> &S)
#if !defined(HAVE_LAPACK)
  {
    Msg::Error("Singular value decomposition requires LAPACK");
    return false;
  }
#endif
  ;
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
  void print(const char *name="") const 
Christophe Geuzaine's avatar
Christophe Geuzaine committed
  {
Christophe Geuzaine's avatar
pp  
Christophe Geuzaine committed
    printf("Printing matrix %s:\n", name);
    int ni = size1();
    int nj = size2();
    for(int I = 0; I < ni; I++){
      printf("  ");
      for(int J = 0; J < nj; J++){
Christophe Geuzaine's avatar
Christophe Geuzaine committed
        printf("%12.5E ", (*this)(I, J));
  static void registerBindings(binding *b);
Jean-François Remacle's avatar
Jean-François Remacle committed
#endif