yat/utility/MatrixExpression.h

Code
Comments
Other
Rev Date Author Line
3605 27 Jan 17 peter 1 #ifndef _theplu_yat_utility_matrix_expression
3605 27 Jan 17 peter 2 #define _theplu_yat_utility_matrix_expression
3605 27 Jan 17 peter 3
3605 27 Jan 17 peter 4 // $Id$
3605 27 Jan 17 peter 5
3605 27 Jan 17 peter 6 /*
3605 27 Jan 17 peter 7   Copyright (C) 2017 Peter Johansson
3605 27 Jan 17 peter 8
3605 27 Jan 17 peter 9   This file is part of the yat library, http://dev.thep.lu.se/yat
3605 27 Jan 17 peter 10
3605 27 Jan 17 peter 11   The yat library is free software; you can redistribute it and/or
3605 27 Jan 17 peter 12   modify it under the terms of the GNU General Public License as
3605 27 Jan 17 peter 13   published by the Free Software Foundation; either version 3 of the
3605 27 Jan 17 peter 14   License, or (at your option) any later version.
3605 27 Jan 17 peter 15
3605 27 Jan 17 peter 16   The yat library is distributed in the hope that it will be useful,
3605 27 Jan 17 peter 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
3605 27 Jan 17 peter 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3605 27 Jan 17 peter 19   General Public License for more details.
3605 27 Jan 17 peter 20
3605 27 Jan 17 peter 21   You should have received a copy of the GNU General Public License
3605 27 Jan 17 peter 22   along with yat. If not, see <http://www.gnu.org/licenses/>.
3605 27 Jan 17 peter 23 */
3605 27 Jan 17 peter 24
3605 27 Jan 17 peter 25 #include "BasicMatrix.h"
3605 27 Jan 17 peter 26 #include "yat_assert.h"
3605 27 Jan 17 peter 27
3605 27 Jan 17 peter 28 #include <gsl/gsl_matrix.h>
3605 27 Jan 17 peter 29
3605 27 Jan 17 peter 30 #include <cstddef>
3605 27 Jan 17 peter 31 #include <utility>
3605 27 Jan 17 peter 32
3605 27 Jan 17 peter 33 namespace theplu {
3605 27 Jan 17 peter 34 namespace yat {
3605 27 Jan 17 peter 35 namespace utility {
3605 27 Jan 17 peter 36
3605 27 Jan 17 peter 37   /**
3605 27 Jan 17 peter 38      \brief An expression that can be converted to a Matrix.
3605 27 Jan 17 peter 39
3605 27 Jan 17 peter 40      Class is only used as temporary when as part of Matrix
3605 27 Jan 17 peter 41      calculations.
3605 27 Jan 17 peter 42
3605 27 Jan 17 peter 43      \since new in yat 0.15
3605 27 Jan 17 peter 44   */
3605 27 Jan 17 peter 45   template<class Derived>
3605 27 Jan 17 peter 46   class MatrixExpression
3605 27 Jan 17 peter 47     : public BasicMatrix<MatrixExpression<Derived> >
3605 27 Jan 17 peter 48   {
3605 27 Jan 17 peter 49   public:
3605 27 Jan 17 peter 50     /**
3605 27 Jan 17 peter 51        Derived class
3605 27 Jan 17 peter 52      */
3605 27 Jan 17 peter 53     typedef Derived derived_type;
3605 27 Jan 17 peter 54
3605 27 Jan 17 peter 55     /**
3605 27 Jan 17 peter 56        \brief Defaulf constructor
3605 27 Jan 17 peter 57      */
3605 27 Jan 17 peter 58     MatrixExpression(void) : m_(NULL) {}
3605 27 Jan 17 peter 59
3605 27 Jan 17 peter 60     /**
3605 27 Jan 17 peter 61        \brief Destructor
3605 27 Jan 17 peter 62      */
3605 27 Jan 17 peter 63     ~MatrixExpression(void)
3605 27 Jan 17 peter 64     {
3651 28 Jun 17 peter 65       detail::deallocate(m_);
3605 27 Jan 17 peter 66     }
3605 27 Jan 17 peter 67
3605 27 Jan 17 peter 68
3605 27 Jan 17 peter 69     /// Cop constructor
3605 27 Jan 17 peter 70     MatrixExpression(const MatrixExpression& other)
3605 27 Jan 17 peter 71       : m_(NULL)
3605 27 Jan 17 peter 72     {
3651 28 Jun 17 peter 73       detail::copy(m_, other.m_);
3605 27 Jan 17 peter 74     }
3605 27 Jan 17 peter 75
3605 27 Jan 17 peter 76     /// Move constructor
3605 27 Jan 17 peter 77     MatrixExpression(MatrixExpression&& other)
3605 27 Jan 17 peter 78       : m_(NULL)
3605 27 Jan 17 peter 79     {
3605 27 Jan 17 peter 80       std::swap(m_, other.m_);
3605 27 Jan 17 peter 81     }
3605 27 Jan 17 peter 82
3605 27 Jan 17 peter 83     /**
3605 27 Jan 17 peter 84        \return number of rows
3605 27 Jan 17 peter 85      */
3605 27 Jan 17 peter 86     size_t rows(void) const
3605 27 Jan 17 peter 87     {  return static_cast<const Derived*>(this)->rows();  }
3605 27 Jan 17 peter 88
3605 27 Jan 17 peter 89
3605 27 Jan 17 peter 90     /**
3605 27 Jan 17 peter 91        \return number of columns
3605 27 Jan 17 peter 92      */
3605 27 Jan 17 peter 93     size_t columns(void) const
3605 27 Jan 17 peter 94     { return static_cast<const Derived*>(this)->columns();}
3605 27 Jan 17 peter 95
3605 27 Jan 17 peter 96
3605 27 Jan 17 peter 97     /**
3605 27 Jan 17 peter 98        \return element in row \a row and column \a column
3605 27 Jan 17 peter 99      */
3605 27 Jan 17 peter 100     double operator()(size_t row, size_t column) const
3605 27 Jan 17 peter 101     {  return (*static_cast<const Derived*>(this))(row, column);  }
3605 27 Jan 17 peter 102
3605 27 Jan 17 peter 103
3605 27 Jan 17 peter 104     /**
3653 28 Jun 17 peter 105       Assign data in *this into passed \a m
3653 28 Jun 17 peter 106
3653 28 Jun 17 peter 107       If \a m has correct dimensions, data is assigned into \a m;
3653 28 Jun 17 peter 108       otherwise \a m is reallocated before assigning data.
3653 28 Jun 17 peter 109      */
3653 28 Jun 17 peter 110     void get(gsl_matrix*& m) const
3653 28 Jun 17 peter 111     {
3653 28 Jun 17 peter 112       static_cast<const Derived*>(this)->calculate_matrix(m);
3653 28 Jun 17 peter 113     }
3653 28 Jun 17 peter 114
3653 28 Jun 17 peter 115
3653 28 Jun 17 peter 116     /**
3653 28 Jun 17 peter 117       Move data in *this into passed \a m
3653 28 Jun 17 peter 118
3653 28 Jun 17 peter 119       \note Calling this function invalidates data in \c this.
3653 28 Jun 17 peter 120      */
3653 28 Jun 17 peter 121     void move(gsl_matrix*& m)
3653 28 Jun 17 peter 122     {
3653 28 Jun 17 peter 123       // If we already have m_, just steal it.
3653 28 Jun 17 peter 124       if (m_) {
3653 28 Jun 17 peter 125         YAT_ASSERT(m_ != m);
3653 28 Jun 17 peter 126         std::swap(m_, m);
3653 28 Jun 17 peter 127         return;
3653 28 Jun 17 peter 128       }
3653 28 Jun 17 peter 129       // Since *this is not supposed to be used after calling this
3653 28 Jun 17 peter 130       // function, there is no reason to store access matrix in m_.
3653 28 Jun 17 peter 131       get(m);
3653 28 Jun 17 peter 132     }
3653 28 Jun 17 peter 133
3653 28 Jun 17 peter 134
3653 28 Jun 17 peter 135     /**
3605 27 Jan 17 peter 136        \return underlying data structure
3605 27 Jan 17 peter 137      */
3605 27 Jan 17 peter 138     const gsl_matrix* gsl_matrix_p(void) const
3605 27 Jan 17 peter 139     {
3605 27 Jan 17 peter 140       if (!m_)
3653 28 Jun 17 peter 141         this->get(m_);
3605 27 Jan 17 peter 142       return m_;
3605 27 Jan 17 peter 143     }
3605 27 Jan 17 peter 144
3605 27 Jan 17 peter 145
3653 28 Jun 17 peter 146
3605 27 Jan 17 peter 147     /**
3605 27 Jan 17 peter 148        \return underlying data structure
3605 27 Jan 17 peter 149      */
3605 27 Jan 17 peter 150     gsl_matrix* gsl_matrix_p(void)
3605 27 Jan 17 peter 151     {
3605 27 Jan 17 peter 152       if (!m_)
3653 28 Jun 17 peter 153         this->get(m_);
3605 27 Jan 17 peter 154       return m_;
3605 27 Jan 17 peter 155     }
3605 27 Jan 17 peter 156
3605 27 Jan 17 peter 157
3605 27 Jan 17 peter 158   protected:
3605 27 Jan 17 peter 159     /**
3605 27 Jan 17 peter 160        underlying data
3605 27 Jan 17 peter 161      */
3605 27 Jan 17 peter 162     mutable gsl_matrix* m_; // lazy eval
3605 27 Jan 17 peter 163
3606 27 Jan 17 peter 164   private:
3656 13 Jul 17 peter 165     // assignment not allowed
3606 27 Jan 17 peter 166     MatrixExpression& operator=(const MatrixExpression& other);
3605 27 Jan 17 peter 167   };
3605 27 Jan 17 peter 168
3605 27 Jan 17 peter 169 }}} // of namespace utility, yat, and theplu
3605 27 Jan 17 peter 170
3605 27 Jan 17 peter 171 #endif