vector_matrix.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision: 1097 $
7 //LIC//
8 //LIC// $LastChangedDate: 2015-12-17 11:53:17 +0000 (Thu, 17 Dec 2015) $
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 #ifndef OOMPH_VECTOR_MATRIX_HEADER
31 #define OOMPH_VECTOR_MATRIX_HEADER
32 
33 
34 // Config header generated by autoconfig
35 #ifdef HAVE_CONFIG_H
36  #include <oomph-lib-config.h>
37 #endif
38 
39 
40 #ifdef OOMPH_HAS_MPI
41 #include "mpi.h"
42 #endif
43 
44 //oomph-lib headers
45 #include "Vector.h"
46 #include "oomph_utilities.h"
47 
48 namespace oomph
49 {
50 //================================================================
51 /// VectorMatrix is a generalised, STL-map-based, matrix based on a Vector
52 /// of Vectors.
53 ///
54 /// Example of usage:
55 /// \code
56 ///
57 /// // Assume we have a Vector of pointers to objects:
58 /// VectorMatrix<int> vector_matrix(4,5,-1);
59 ///
60 /// // This is a 4 by 5 matrix with all entries set to -1.
61 ///
62 /// std::cout << vector_matrix[3][3] << " "
63 // << vector_matrix.nrow() << " "
64 // << vector_matrix.col() << std::endl;
65 ///
66 /// // Output:
67 /// // -1 4 5
68 ///
69 /// vector_matrix[3][3] = 42;
70 ///
71 /// std::cout << vector_matrix[3][3] << " "
72 /// << vector_matrix.nrow() << " "
73 /// << vector_matrix.col() << std::endl;
74 ///
75 /// // Output:
76 /// // 42 4 5
77 ///
78 /// \endcode
79 ///
80 //================================================================
81 template<class VALUE_TYPE>
83 {
84 
85 public:
86 
87  /// \short Default constructor - constructs an empty matrix.
89  {
90  Vector_matrix.resize(0);
91  }
92 
93  /// \short Constructor - constructs an n by m matrix with value val.
94  VectorMatrix(const unsigned& n, const unsigned& m, const VALUE_TYPE& val)
95  {
96  this->build_vectors_and_value(n,m,val);
97  }
98 
99  /// \short Constructor - constructs an n by m matrix, the value is defined by
100  /// the default initialisation of VALUE_TYPE.
101  VectorMatrix(const unsigned& n, const unsigned& m)
102  {
103  this->build_vectors(n,m);
104  }
105 
106  /// \short Default virtual destructor
107  virtual ~VectorMatrix()
108  {
109  this->clear();
110  }
111 
112  /// \short returns the number of rows. This is the outer Vector size.
113  const unsigned nrow() const
114  {
115 #ifdef PARANOID
116  // Inner vector size consistency check: All inner vectors must be the same
117  // size. Although the size of the inner vectors are not directly used to
118  // calculate the nrow(), we perform this check here in case the user has
119  // done something dodgy.
120 
121  const unsigned para_nrow = Vector_matrix.size();
122 
123  if(para_nrow > 0)
124  {
125  // There is at least one inner vector
126  unsigned inner_vector0_size = Vector_matrix[0].size();
127 
128  for (unsigned row_i = 0; row_i < para_nrow; row_i++)
129  {
130  unsigned current_inner_vector_size = Vector_matrix[row_i].size();
131  if(current_inner_vector_size != inner_vector0_size)
132  {
133  std::ostringstream err_msg;
134  err_msg << "The size of the inner vectors are not consistent.\n"
135  << "Vector_matrix[0].size() is " << inner_vector0_size <<"\n"
136  << "Vector_matrix[" <<row_i <<"] is "
137  << current_inner_vector_size << "\n";
138  throw OomphLibError(
139  err_msg.str(),
140  OOMPH_CURRENT_FUNCTION,
141  OOMPH_EXCEPTION_LOCATION);
142  }
143  }
144  }
145 #endif
146 
147  return Vector_matrix.size();
148  }
149 
150  /// \short return the number of columns. This is the size of the first inner
151  /// vectors, or returns 0 if the outer vector is of size 0
152  /// (this->nrow() is 0).
153  const unsigned ncol() const
154  {
155 #ifdef PARANOID
156  // Inner vector size consistency check: All inner vectors must be the same
157  // size.
158 
159  const unsigned para_nrow = this->nrow();
160  if(para_nrow > 0)
161  {
162  // There is at least one inner vector
163  unsigned inner_vector0_size = Vector_matrix[0].size();
164 
165  for (unsigned row_i = 0; row_i < para_nrow; row_i++)
166  {
167  unsigned current_inner_vector_size = Vector_matrix[row_i].size();
168  if(current_inner_vector_size != inner_vector0_size)
169  {
170  std::ostringstream err_msg;
171  err_msg << "The size of the inner vectors are not consistent.\n"
172  << "Vector_matrix[0].size() is " << inner_vector0_size <<"\n"
173  << "Vector_matrix[" <<row_i <<"] is "
174  << current_inner_vector_size << "\n";
175  throw OomphLibError(
176  err_msg.str(),
177  OOMPH_CURRENT_FUNCTION,
178  OOMPH_EXCEPTION_LOCATION);
179  }
180  }
181  }
182 #endif
183 
184  if(this->nrow() == 0)
185  {
186  return 0;
187  }
188  else
189  {
190  return Vector_matrix[0].size();
191  }
192  }
193 
194  /// \short [] access function to the i-th inner vector.
196  {
197  return Vector_matrix[i];
198  }
199 
200  /// \short [] access function to the i-th inner vector const version
201  const Vector<VALUE_TYPE>& operator[] (const size_t i) const
202  {
203  return Vector_matrix[i];
204  }
205 
206 
207  /// \short Clears the outer vector. Calling Vector::clear() will invoke the
208  /// destructor of all the inner Vectors.
209  void clear()
210  {
211  Vector_matrix.clear();
212  }
213 
214  /// \short Resize the existing VectorMatrix.
215  /// WARNING: This invokes the resize function in std::vector, as such, only
216  /// new values are assigned, old values as kept.
217  /// e.g. if vec = [2,2,2], then vec.resize(5,3) gives
218  /// vec = [2, 2, 2, 3, 3].
219  void resize(const size_t& n, const size_t& m,
220  VALUE_TYPE val = VALUE_TYPE())
221  {
222  Vector_matrix.resize(n);
223  for (unsigned i = 0; i < n ; i++)
224  {
225  Vector_matrix[i].resize(m,val);
226  }
227  }
228 
229  /// \short Any elements held in the container before the call are destroyed
230  /// and replaced by newly constructed elements (no assignments of elements
231  /// take place).
232  /// This causes an automatic reallocation of the allocated storage space if
233  /// -and only if- the new vector size surpasses the current vector capacity.
234  /// This invokes std::assign on both the outer vector and the inner vectors.
235  void assign(const size_t & n, const size_t& m,
236  const VALUE_TYPE& val)
237  {
238  Vector_matrix.assign(n,Vector<VALUE_TYPE>(m,val));
239  }
240 
241 
242 protected:
243 
244  /// \short Builds an n by m VectorMatrix with default VALUE_TYPE.
245  void build_vectors(const unsigned& n, const unsigned& m)
246  {
247  Vector_matrix.resize(n,Vector<VALUE_TYPE>(m));
248  }
249 
250  /// \short Build an m by n VectorMatrix with VALUE_TYPE val.
251  void build_vectors_and_value(const unsigned& n,
252  const unsigned& m,
253  const VALUE_TYPE& val)
254  {
255  Vector_matrix.resize(n, Vector<VALUE_TYPE>(m,val));
256  }
257 
258  /// Here's the generalised matrix structure: A Vector of Vector to
259  /// templated by VALUE_TYPE.
261 
262 };
263 
264 } // End of oomph namespace
265 
266 #endif
void clear()
Clears the outer vector. Calling Vector::clear() will invoke the destructor of all the inner Vectors...
void build_vectors_and_value(const unsigned &n, const unsigned &m, const VALUE_TYPE &val)
Build an m by n VectorMatrix with VALUE_TYPE val.
cstr elem_len * i
Definition: cfortran.h:607
VectorMatrix(const unsigned &n, const unsigned &m, const VALUE_TYPE &val)
Constructor - constructs an n by m matrix with value val.
Definition: vector_matrix.h:94
const unsigned ncol() const
return the number of columns. This is the size of the first inner vectors, or returns 0 if the outer ...
void assign(const size_t &n, const size_t &m, const VALUE_TYPE &val)
Any elements held in the container before the call are destroyed and replaced by newly constructed el...
const unsigned nrow() const
returns the number of rows. This is the outer Vector size.
Vector< VALUE_TYPE > & operator[](const size_t i)
[] access function to the i-th inner vector.
Vector< Vector< VALUE_TYPE > > Vector_matrix
VectorMatrix()
Default constructor - constructs an empty matrix.
Definition: vector_matrix.h:88
void build_vectors(const unsigned &n, const unsigned &m)
Builds an n by m VectorMatrix with default VALUE_TYPE.
VectorMatrix(const unsigned &n, const unsigned &m)
Constructor - constructs an n by m matrix, the value is defined by the default initialisation of VALU...
virtual ~VectorMatrix()
Default virtual destructor.
void resize(const size_t &n, const size_t &m, VALUE_TYPE val=VALUE_TYPE())
Resize the existing VectorMatrix. WARNING: This invokes the resize function in std::vector, as such, only new values are assigned, old values as kept. e.g. if vec = [2,2,2], then vec.resize(5,3) gives vec = [2, 2, 2, 3, 3].