]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Implement swap for vectors and block vectors.
authorWolfgang Bangerth <bangerth@math.tamu.edu>
Tue, 2 May 2000 08:59:26 +0000 (08:59 +0000)
committerWolfgang Bangerth <bangerth@math.tamu.edu>
Tue, 2 May 2000 08:59:26 +0000 (08:59 +0000)
git-svn-id: https://svn.dealii.org/trunk@2778 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/news/2000/c-3-0.html
deal.II/lac/include/lac/block_vector.h
deal.II/lac/include/lac/block_vector.templates.h
deal.II/lac/include/lac/solver_minres.h
deal.II/lac/include/lac/vector.h
deal.II/lac/include/lac/vector.templates.h

index 92f71e8668448e0f52822ac69a169cbcbd6a8b13..b38c17af0f7aefa32f755ba51f1061880df02fdb 100644 (file)
        </p>
 
   <li> <p>
-       New: <code class="class">Solver*</code>: There is a virtual function
+       New: <code class="class">SolverXX</code>: There is a virtual function
        <code>print_vectors</code> called in every step. It is void in the
        solver itself but can be used to print intermediate iteration
        vectors.
        </p>
+
+  <li> <p>
+       New: there are now functions <code class="member">Vector::swap</code> 
+       and <code class="member">BlockVector::swap</code>, as well as
+       global functions <code class="member">swap(u,v)</code> that
+       exchange the data of two vectors without needing a temporary
+       vector and without copying around data. Their run-time is
+       therefore independent of the length of the vectors.
+       </p>
 </ol>
 
 
index d192382e2dad6ad3986cd6c497e4273dca7fd881..30d81f8bbfd858a6f0d49983638e0c311ba64f7a 100644 (file)
@@ -77,14 +77,36 @@ class BlockVector
     ~BlockVector ();
 
                                     /**
-                                     * Access to a single block.
-                                     */
-    Vector<Number>& block(unsigned int i);
+                                     * Change the dimension of the vector to
+                                     * #N#. The reserved memory for this vector
+                                     * remains unchanged if possible, to make
+                                     * things faster, but this may waste some
+                                     * memory, so take this in the back of your
+                                     * head.
+                                     * However, if #N==0# all memory is freed,
+                                     * i.e. if you want to resize the vector
+                                     * and release the memory not needed, you
+                                     * have to first call #reinit(0)# and then
+                                     * #reinit(N)#. This cited behaviour is
+                                     * analogous to that of the STL containers.
+                                     *
+                                     * On #fast==false#, the vector is filled by
+                                     * zeros.
+                                     */ 
+    void reinit (const vector<unsigned int>& N,
+                const bool         fast=false);
     
                                     /**
-                                     * Read-only access to a single block.
+                                     * Change the dimension to that of the
+                                     * vector #V#. The same applies as for
+                                     * the other #reinit# function.
+                                     *
+                                     * The elements of #V# are not copied, i.e.
+                                     * this function is the same as calling
+                                     * #reinit (V.size(), fast)#.
                                      */
-    const Vector<Number>& block(unsigned int i) const;
+    void reinit (const BlockVector<n_blocks,Number> &V,
+                const bool            fast=false);
     
                                     /**
                                      * Set all entries to zero. Equivalent to
@@ -95,6 +117,41 @@ class BlockVector
                                      */
     void clear ();
     
+                                    /**
+                                     * Swap the contents of this
+                                     * vector and the other vector
+                                     * #v#. One could do this
+                                     * operation with a temporary
+                                     * variable and copying over the
+                                     * data elements, but this
+                                     * function is significantly more
+                                     * efficient since it only swaps
+                                     * the pointers to the data of
+                                     * the two vectors and therefore
+                                     * does not need to allocate
+                                     * temporary storage and move
+                                     * data around.
+                                     *
+                                     * This function is analog to the
+                                     * the #swap# function of all C++
+                                     * standard containers. Also,
+                                     * there is a global function
+                                     * #swap(u,v)# that simply calls
+                                     * #u.swap(v)#, again in analogy
+                                     * to standard functions.
+                                     */
+    void swap (BlockVector<n_blocks,Number> &v);
+    
+                                    /**
+                                     * Access to a single block.
+                                     */
+    Vector<Number>& block(unsigned int i);
+    
+                                    /**
+                                     * Read-only access to a single block.
+                                     */
+    const Vector<Number>& block(unsigned int i) const;
+    
                                     /**
                                      * $U(0-N) = s$: fill all components.
                                      */
@@ -150,38 +207,6 @@ class BlockVector
     Number linfty_norm () const;
 
 
-                                    /**
-                                     * Change the dimension of the vector to
-                                     * #N#. The reserved memory for this vector
-                                     * remains unchanged if possible, to make
-                                     * things faster, but this may waste some
-                                     * memory, so take this in the back of your
-                                     * head.
-                                     * However, if #N==0# all memory is freed,
-                                     * i.e. if you want to resize the vector
-                                     * and release the memory not needed, you
-                                     * have to first call #reinit(0)# and then
-                                     * #reinit(N)#. This cited behaviour is
-                                     * analogous to that of the STL containers.
-                                     *
-                                     * On #fast==false#, the vector is filled by
-                                     * zeros.
-                                     */ 
-    void reinit (const vector<unsigned int>& N,
-                const bool         fast=false);
-    
-                                    /**
-                                     * Change the dimension to that of the
-                                     * vector #V#. The same applies as for
-                                     * the other #reinit# function.
-                                     *
-                                     * The elements of #V# are not copied, i.e.
-                                     * this function is the same as calling
-                                     * #reinit (V.size(), fast)#.
-                                     */
-    void reinit (const BlockVector<n_blocks,Number> &V,
-                const bool            fast=false);
-    
                                     /**
                                      * Return dimension of the vector. This is the
                                      * sum of the dimensions of all components.
@@ -525,4 +550,21 @@ BlockVector<n_blocks,Number>::block(unsigned int i) const
 }
 
 
+/**
+ * Global function #swap# which overloads the default implementation
+ * of the C++ standard library which uses a temporary object. The
+ * function simply exchanges the data of the two vectors.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+template <int n_blocks, typename Number>
+inline
+void swap (BlockVector<n_blocks,Number> &u, BlockVector<n_blocks,Number> &v)
+{
+  u.swap (v);
+};
+
+
+
+
 #endif
index 6d54d753bfa7dcc282cc1caf38d9514d83fb0e77..e7c262d854c9d67d370a99bda609ed1d943bc34c 100644 (file)
@@ -104,12 +104,27 @@ void BlockVector<n_blocks,Number>::reinit (const BlockVector<n_blocks,Number>& v
 }
 
 
+
 template <int n_blocks, typename Number>
 BlockVector<n_blocks,Number>::~BlockVector ()
 {
 }
 
 
+
+template <int n_blocks, typename Number>
+void BlockVector<n_blocks,Number>::swap (BlockVector<n_blocks,Number> &v)
+{
+  for (unsigned int i=0; i<n_blocks; ++i)
+    {
+      swap (components[i], v.components[i]);
+      swap (start[i],      v.start[i]);
+    };
+  swap (start[n_blocks], v.start[n_blocks]);
+};
+
+
+
 template <int n_blocks, typename Number>
 void BlockVector<n_blocks,Number>::clear ()
 {
index 6bf5e26a356b576d42010512266f72ce3d53e9e0..bff486943c8dd96cbcf9b8ae8c1c5c52f9bee7c5 100644 (file)
@@ -208,9 +208,9 @@ SolverMinRes<VECTOR>::solve (const MATRIX &A,
   v.reinit(VS,true);
 
                                   // some values needed
-  vector<double> delta(3);
-  vector<double> f(2);
-  vector<double> e(2)
+  double delta[3];
+  double f[2];
+  double e[2]
 
   double r_l2 = 0;
   double r0   = 0;
@@ -222,7 +222,7 @@ SolverMinRes<VECTOR>::solve (const MATRIX &A,
   double d = 0;  
 
                                   // The iteration step.
-  int j = 1;
+  unsigned int j = 1;
   
 
                                   // Start of the solution process
@@ -314,11 +314,24 @@ SolverMinRes<VECTOR>::solve (const MATRIX &A,
                                       // All vectors have to be shifted
                                       // one iteration step.
                                       // This should be changed one time.
-      m[2] = m[1];
-      m[1] = m[0];
-
-      u[0] = u[1];
-      u[1] = u[2];
+                                      //
+                                      // the previous code was like this:
+                                      //   m[2] = m[1];
+                                      //   m[1] = m[0];
+                                      // but it can be made more efficient,
+                                      // since the value of m[0] is no more
+                                      // needed in the next iteration
+      swap (m[2], m[1]);
+      swap (m[1], m[0]);
+      
+                                      // likewise, but reverse direction:
+                                      //   u[0] = u[1];
+                                      //   u[1] = u[2];
+      swap (u[0], u[1]);
+      swap (u[1], u[2]);
+
+                                      // these are scalars, so need
+                                      // to bother
       f[0] = f[1];
       e[0] = e[1];
       delta[0] = delta[1];
index 6e39eaa79dc042c4a7a4efd8b63e37e56f511b37..76d7c140b091506be588462a474dd1fcffb636be 100644 (file)
@@ -104,7 +104,64 @@ class Vector {
                                      * the size of the vector, unlike the
                                      * STL's #vector<>::clear# function.
                                      */
-    void clear ();
+    void clear ();    
+
+                                    /**
+                                     * Change the dimension of the vector to
+                                     * #N#. The reserved memory for this vector
+                                     * remains unchanged if possible, to make
+                                     * things faster, but this may waste some
+                                     * memory, so take this in the back of your
+                                     * head.
+                                     * However, if #N==0# all memory is freed,
+                                     * i.e. if you want to resize the vector
+                                     * and release the memory not needed, you
+                                     * have to first call #reinit(0)# and then
+                                     * #reinit(N)#. This cited behaviour is
+                                     * analogous to that of the STL containers.
+                                     *
+                                     * On #fast==false#, the vector is filled by
+                                     * zeros.
+                                     */ 
+    void reinit (const unsigned int N,
+                const bool         fast=false);
+    
+                                    /**
+                                     * Change the dimension to that of the
+                                     * vector #V#. The same applies as for
+                                     * the other #reinit# function.
+                                     *
+                                     * The elements of #V# are not copied, i.e.
+                                     * this function is the same as calling
+                                     * #reinit (V.size(), fast)#.
+                                     */
+    void reinit (const Vector<Number> &V,
+                const bool            fast=false);
+
+                                    /**
+                                     * Swap the contents of this
+                                     * vector and the other vector
+                                     * #v#. One could do this
+                                     * operation with a temporary
+                                     * variable and copying over the
+                                     * data elements, but this
+                                     * function is significantly more
+                                     * efficient since it only swaps
+                                     * the pointers to the data of
+                                     * the two vectors and therefore
+                                     * does not need to allocate
+                                     * temporary storage and move
+                                     * data around.
+                                     *
+                                     * This function is analog to the
+                                     * the #swap# function of all C++
+                                     * standard containers. Also,
+                                     * there is a global function
+                                     * #swap(u,v)# that simply calls
+                                     * #u.swap(v)#, again in analogy
+                                     * to standard functions.
+                                     */
+    void swap (Vector<Number> &v);
     
                                     /**
                                      * $U(0-N) = s$: fill all components.
@@ -158,39 +215,6 @@ class Vector {
                                      */
     Number linfty_norm () const;
 
-
-                                    /**
-                                     * Change the dimension of the vector to
-                                     * #N#. The reserved memory for this vector
-                                     * remains unchanged if possible, to make
-                                     * things faster, but this may waste some
-                                     * memory, so take this in the back of your
-                                     * head.
-                                     * However, if #N==0# all memory is freed,
-                                     * i.e. if you want to resize the vector
-                                     * and release the memory not needed, you
-                                     * have to first call #reinit(0)# and then
-                                     * #reinit(N)#. This cited behaviour is
-                                     * analogous to that of the STL containers.
-                                     *
-                                     * On #fast==false#, the vector is filled by
-                                     * zeros.
-                                     */ 
-    void reinit (const unsigned int N,
-                const bool         fast=false);
-    
-                                    /**
-                                     * Change the dimension to that of the
-                                     * vector #V#. The same applies as for
-                                     * the other #reinit# function.
-                                     *
-                                     * The elements of #V# are not copied, i.e.
-                                     * this function is the same as calling
-                                     * #reinit (V.size(), fast)#.
-                                     */
-    void reinit (const Vector<Number> &V,
-                const bool            fast=false);
-    
                                     /**
                                      * Return dimension of the vector. This
                                      * function was formerly called #n()#, but
@@ -204,7 +228,7 @@ class Vector {
                                      * Return whether the vector contains only
                                      * elements with value zero. This function
                                      * is mainly for internal consistency
-                                     * check and should seldomly be used when
+                                     * checks and should seldomly be used when
                                      * not in debug mode since it uses quite
                                      * some time.
                                      */
@@ -524,4 +548,21 @@ Number& Vector<Number>::operator() (const unsigned int i)
 }
 
 
+
+/**
+ * Global function #swap# which overloads the default implementation
+ * of the C++ standard library which uses a temporary object. The
+ * function simply exchanges the data of the two vectors.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+template <typename Number>
+inline
+void swap (Vector<Number> &u, Vector<Number> &v)
+{
+  u.swap (v);
+};
+
+
+
 #endif
index 5d79eb4257131de1cd02742d39a544e05c70920c..c303a580ba8cd598702fd297a999668ee8b8b62d 100644 (file)
@@ -19,6 +19,7 @@
 #include <algorithm>
 
 
+
 template <typename Number>
 static inline Number sqr (const Number x) {
   return x*x;
@@ -76,6 +77,14 @@ Vector<Number>::Vector (const Vector<Number>& v) :
 // }
 
 
+template <typename Number>
+Vector<Number>::~Vector ()
+{
+  if (val) delete[] val;
+}
+
+
+
 template <typename Number>
 void Vector<Number>::reinit (const unsigned int n, const bool fast) {
   if (n==0) 
@@ -100,27 +109,35 @@ void Vector<Number>::reinit (const unsigned int n, const bool fast) {
 
 
 template <typename Number>
-void Vector<Number>::reinit (const Vector<Number>& v, const bool fast) {
+void Vector<Number>::reinit (const Vector<Number>& v, const bool fast)
+{
   reinit (v.size(), fast);
 };
 
 
 template <typename Number>
-Vector<Number>::~Vector ()
+void Vector<Number>::clear ()
 {
-  if (val) delete[] val;
+  if (dim>0)
+    fill (begin(), end(), 0.);
 }
 
 
+
 template <typename Number>
-void Vector<Number>::clear () {
-  if (dim>0)
-    fill (begin(), end(), 0.);
-}
+void
+Vector<Number>::swap (Vector<Number> &v)
+{
+  std::swap (dim,    v.dim);
+  std::swap (maxdim, v.maxdim);
+  std::swap (val,    v.val);
+};
+
 
 
 template <typename Number>
-bool Vector<Number>::all_zero () const {
+bool Vector<Number>::all_zero () const
+{
   Assert (dim!=0, ExcEmptyVector());
   
   const_iterator p = begin(),

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.