matrix_set.hpp
Go to the documentation of this file.
1 /*!
2  * \brief Implements a set of matrices
3  *
4  * \author O. Krause
5  * \date 2013
6  *
7  *
8  * \par Copyright 1995-2015 Shark Development Team
9  *
10  * <BR><HR>
11  * This file is part of Shark.
12  * <http://image.diku.dk/shark/>
13  *
14  * Shark is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License as published
16  * by the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * Shark is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28 #ifndef SHARK_LINALG_BLAS_MATRIX_SET_HPP
29 #define SHARK_LINALG_BLAS_MATRIX_SET_HPP
30 
31 #include "matrix_expression.hpp"
32 
33 #include <boost/serialization/vector.hpp>
34 
35 namespace shark {
36 namespace blas {
37 
38 template<class element_type>
39 class matrix_set:
40  //todo: mpl decision on whether this is a matrix or vector set.
41  public matrix_set_expression<matrix_set<element_type> > {
43  typedef std::vector<element_type> array_type;
44 public:
45  typedef typename array_type::size_type size_type;
46  typedef typename array_type::difference_type difference_type;
47  typedef typename array_type::value_type value_type;
48  typedef typename element_type::scalar_type scalar_type;
49  typedef typename array_type::const_reference const_reference;
50  typedef typename array_type::reference reference;
51  typedef value_type const* const_pointer;
52  typedef value_type* pointer;
53 
54  typedef typename element_type::index_type index_type;
55  typedef typename element_type::const_index_pointer const_index_pointer;
56  typedef typename element_type::index_pointer index_pointer;
57 
58  //~ typedef const matrix_reference<const self_type> const_closure_type;
59  //~ typedef matrix_reference<self_type> closure_type;
60  typedef typename element_type::storage_category storage_category;
61  typedef typename element_type::orientation orientation;
62 
63  // Construction and destruction
64 
65  /// Default matrix_set constructor. Make a dense matrix_set of size (0,0)
67 
68  /** matrix_set constructor with defined size
69  * \param size number of element matrices
70  */
71  matrix_set(size_type size):m_data(size){}
72 
73  /** matrix_set constructor with defined size
74  * \param size number of element matrices
75  * \param init initial value for matrices
76  */
77  matrix_set(size_type size, value_type const& init):m_data(size, init) {}
78 
79  /** Copy-constructor of a dense matrix_set from a matrix_set expression
80  * \param e is a matrix_set expression
81  */
82  template<class E>
83  matrix_set(matrix_set_expression<E> const& e):m_data(e.size()) {
84  assign(e);
85  }
86 
87  matrix_set(size_type size, size_type size1, size_type size2)
88  :m_data(size,element_type(size1,size2)){}
89  // --------------
90  // Sizes
91  // --------------
92 
93  ///\brief Returns the number of matrices in the set
94  size_type size() const {
95  return m_data.size();
96  }
97 
98  ///\brief Returns the first dimension of the matrices in the set
99  size_type size1() const {
100  return m_data.empty()?0:m_data[0].size1();
101  }
102 
103  ///\brief Returns the second dimension of the matrices in the set
104  size_type size2() const {
105  return m_data.empty()?0:m_data[0].size2();
106  }
107 
108  // Resizing
109  /** Resize a matrix_set to new dimensions. If resizing is performed, the data is not preserved.
110  * \param size the new number of elements
111  */
112  void resize(size_type size) {
113  m_data.resize(size);
114  }
115 
116  // --------------
117  // Element access
118  // --------------
119 
120  /// \brief Return a const reference to the element \f$i\f$
121  const_reference operator()(index_type i) const {
122  return m_data[i];
123  }
124 
125  /// \brief Return a reference to the element \f$i\f$
126  reference operator()(index_type i) {
127  return m_data[i];
128  }
129 
130  /// \brief Return a const reference to the element \f$i\f$
131  const_reference operator [](index_type i) const {
132  return (*this)(i);
133  }
134 
135  /// \brief Return a reference to the element \f$i\f$
136  reference operator [](index_type i) {
137  return (*this)(i);
138  }
139 
140  ///\brief Returns the first element of the vector
141  reference front(){
142  return m_data[0];
143  }
144  ///\brief Returns the first element of the vector
145  const_reference front()const{
146  return m_data[0];
147  }
148  ///\brief Returns the last element of the vector
149  reference back(){
150  return m_data[size()-1];
151  }
152  ///\brief Returns the last element of the vector
153  const_reference back()const{
154  return m_data[size()-1];
155  }
156 
157  // Iterators
158 
159  // Iterator types
160  typedef typename array_type::iterator iterator;
161  typedef typename array_type::const_iterator const_iterator;
162 
163  /// \brief return a const iterator on the first element of the vector
164  const_iterator cbegin() const {
165  return m_data.begin();
166  }
167 
168  /// \brief return a const iterator after the last element of the vector
169  const_iterator cend() const {
170  return m_data.end();
171  }
172 
173  /// \brief return an iterator on the first element of the vector
174  const_iterator begin() const {
175  return m_data.begin();
176  }
177 
178  /// \brief return an iterator after the last element of the vector
179  const_iterator end() const {
180  return m_data.end();
181  }
182 
183  /// \brief Return an iterator on the first element of the vector
184  iterator begin(){
185  return m_data.begin();
186  }
187 
188  /// \brief Return an iterator at the end of the vector
189  iterator end(){
190  return m_data.end();
191  }
192 
193  // Assignment
194 
195  template<class E>
197  SIZE_CHECK(size() == e().size());
198  for(std::size_t i = 0; i != size(); ++i){
199  m_data[i].assign(e[i]);
200  }
201  return *this;
202  }
203  template<class E>
205  SIZE_CHECK(size() == e().size());
206  for(std::size_t i = 0; i != size(); ++i){
207  m_data[i].plus_assign(e[i]);
208  }
209  return *this;
210  }
211  template<class E>
213  SIZE_CHECK(size() == e().size());
214  for(std::size_t i = 0; i != size(); ++i){
215  m_data[i].minus_assign(e[i]);
216  }
217  return *this;
218  }
219 
220  template<class E>
222  SIZE_CHECK(size() == e().size());
223  for(std::size_t i = 0; i != size(); ++i){
224  m_data[i].multiply_assign(e[i]);
225  }
226  return *this;
227  }
228  template<class E>
230  SIZE_CHECK(size() == e().size());
231  for(std::size_t i = 0; i != size(); ++i){
232  m_data[i].divide_assign(e[i]);
233  }
234  return *this;
235  }
236 
237  /*! @note "pass by value" the key idea to enable move semantics */
239  swap(m);
240  return *this;
241  }
242  template<class E>
244  self_type temporary(e);
245  swap(temporary);
246  return *this;
247  }
248  template<class E>
250  SIZE_CHECK(size() == e().size());
251  for(std::size_t i = 0; i != size(); ++i){
252  m_data[i] += e[i];
253  }
254  return *this;
255  }
256 
257  template<class E>
259  SIZE_CHECK(size() == e().size());
260  for(std::size_t i = 0; i != size(); ++i){
261  m_data[i] -= e[i];
262  }
263  return *this;
264  }
265 
266  template<class E>
268  SIZE_CHECK(size() == e().size());
269  for(std::size_t i = 0; i != size(); ++i){
270  m_data[i] *= e[i];
271  }
272  return *this;
273  }
274 
275  template<class E>
277  SIZE_CHECK(size() == e().size());
278  for(std::size_t i = 0; i != size(); ++i){
279  m_data[i] /= e[i];
280  }
281  return *this;
282  }
283 
284  matrix_set& operator *= (scalar_type t) {
285  for(std::size_t i = 0; i != size(); ++i){
286  m_data[i] *= t;
287  }
288  return *this;
289  }
290  matrix_set& operator /= (scalar_type t) {
291  for(std::size_t i = 0; i != size(); ++i){
292  m_data[i] /= t;
293  }
294  return *this;
295  }
296 
297  // Swapping
298  void swap(matrix_set& m) {
299  using std::swap;
300  swap(m_data, m.m_data);
301  }
302 
303  void clear(){
304  for(std::size_t i = 0; i != size(); ++i){
305  m_data[i].clear();
306  }
307  }
308 
309 
310  // Serialization
311  template<class Archive>
312  void serialize(Archive& ar, const unsigned int /* file_version */) {
313  ar& boost::serialization::make_nvp("data",m_data);
314  }
315 
316 private:
317  array_type m_data;
318 };
319 }}
320 
321 #endif