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$
7 //LIC//
8 //LIC// $LastChangedDate$
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
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...
Vector< VALUE_TYPE > & operator[](const size_t i)
[] access function to the i-th inner vector.
Vector< Vector< VALUE_TYPE > > Vector_matrix
const unsigned nrow() const
returns the number of rows. This is the outer Vector size.
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.
const unsigned ncol() const
return the number of columns. This is the size of the first inner vectors, or returns 0 if the outer ...
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].