LCOV - code coverage report
Current view: top level - tools - Vector.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 68 68 100.0 %
Date: 2020-11-18 11:20:57 Functions: 33 33 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2019 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_tools_Vector_h
      23             : #define __PLUMED_tools_Vector_h
      24             : 
      25             : #include <cmath>
      26             : #include <iosfwd>
      27             : #include "LoopUnroller.h"
      28             : 
      29             : #ifdef _GLIBCXX_DEBUG
      30             : #include "Exception.h"
      31             : #endif
      32             : 
      33             : 
      34             : namespace PLMD {
      35             : 
      36             : /**
      37             : \ingroup TOOLBOX
      38             : Class implementing fixed size vectors of doubles
      39             : 
      40             : \tparam n The number of elements of the vector.
      41             : 
      42             : This class implements a vector of doubles with size fixed at
      43             : compile time. It is useful for small fixed size objects (e.g.
      44             : 3d vectors) as it does not waste space to store the vector size.
      45             : Moreover, as the compiler knows the size, it can be completely
      46             : opimized inline.
      47             : All the methods are inlined for better optimization and
      48             : all the loops are explicitly unrolled using PLMD::LoopUnroller class.
      49             : Vector elements are initialized to zero by default. Notice that
      50             : this means that constructor is a bit slow. This point might change
      51             : in future if we find performance issues.
      52             : Accepts both [] and () syntax for access.
      53             : Several functions are declared as friends even if not necessary so as to
      54             : properly appear in Doxygen documentation.
      55             : 
      56             : Aliases are defined to simplify common declarations (Vector, Vector2d, Vector3d, Vector4d).
      57             : Also notice that some operations are only available for 3 dimensional vectors.
      58             : 
      59             : Example of usage
      60             : \verbatim
      61             : #include "Vector.h"
      62             : 
      63             : using namespace PLMD;
      64             : 
      65             : int main(){
      66             :   VectorGeneric<3> v1;
      67             :   v1[0]=3.0;
      68             : // use equivalently () and [] syntax:
      69             :   v1(1)=5.0;
      70             : // initialize with components
      71             :   VectorGeneric<3> v2=VectorGeneric<3>(1.0,2.0,3.0);
      72             :   VectorGeneric<3> v3=crossProduct(v1,v2);
      73             :   double d=dotProduct(v1,v2);
      74             :   v3+=v1;
      75             :   v2=v1+2.0*v3;
      76             : }
      77             : \endverbatim
      78             : 
      79             : */
      80             : 
      81             : 
      82             : template <unsigned n>
      83             : class VectorGeneric {
      84             :   double d[n];
      85             : public:
      86             : /// Create it with preassigned components.
      87             : /// Only available for sizes 2, 3 and 4
      88             :   VectorGeneric(double,double);
      89             :   VectorGeneric(double,double,double);
      90             :   VectorGeneric(double,double,double,double);
      91             : /// create it null
      92             :   VectorGeneric();
      93             : /// set it to zero
      94             :   void zero();
      95             : /// array-like access [i]
      96             :   double & operator[](unsigned i);
      97             : /// array-like access [i]
      98             :   const double & operator[](unsigned i)const;
      99             : /// parenthesis access (i)
     100             :   double & operator()(unsigned i);
     101             : /// parenthesis access (i)
     102             :   const double & operator()(unsigned i)const;
     103             : /// increment
     104             :   VectorGeneric& operator +=(const VectorGeneric& b);
     105             : /// decrement
     106             :   VectorGeneric& operator -=(const VectorGeneric& b);
     107             : /// multiply
     108             :   VectorGeneric& operator *=(double s);
     109             : /// divide
     110             :   VectorGeneric& operator /=(double s);
     111             : /// sign +
     112             :   VectorGeneric operator +()const;
     113             : /// sign -
     114             :   VectorGeneric operator -()const;
     115             : /// return v1+v2
     116             :   template<unsigned m>
     117             :   friend VectorGeneric<m> operator+(const VectorGeneric<m>&,const VectorGeneric<m>&);
     118             : /// return v1-v2
     119             :   template<unsigned m>
     120             :   friend VectorGeneric<m> operator-(const VectorGeneric<m>&,const VectorGeneric<m>&);
     121             : /// return s*v
     122             :   template<unsigned m>
     123             :   friend VectorGeneric<m> operator*(double,const VectorGeneric<m>&);
     124             : /// return v*s
     125             :   template<unsigned m>
     126             :   friend VectorGeneric<m> operator*(const VectorGeneric<m>&,double);
     127             : /// return v/s
     128             :   template<unsigned m>
     129             :   friend VectorGeneric<m> operator/(const VectorGeneric<m>&,double);
     130             : /// return v2-v1
     131             :   template<unsigned m>
     132             :   friend VectorGeneric<m> delta(const VectorGeneric<m>&v1,const VectorGeneric<m>&v2);
     133             : /// return v1 .scalar. v2
     134             :   template<unsigned m>
     135             :   friend double dotProduct(const VectorGeneric<m>&,const VectorGeneric<m>&);
     136             : /// return v1 .vector. v2
     137             : /// Only available for size 3
     138     5371260 :   friend VectorGeneric<3> crossProduct(const VectorGeneric<3>&,const VectorGeneric<3>&);
     139             : /// compute the squared modulo
     140             :   double modulo2()const;
     141             : /// Compute the modulo.
     142             : /// Shortcut for sqrt(v.modulo2())
     143             :   double modulo()const;
     144             : /// friend version of modulo2 (to simplify some syntax)
     145             :   template<unsigned m>
     146             :   friend double modulo2(const VectorGeneric<m>&);
     147             : /// friend version of modulo (to simplify some syntax)
     148             :   template<unsigned m>
     149             :   friend double modulo(const VectorGeneric<m>&);
     150             : /// << operator.
     151             : /// Allows printing vector `v` with `std::cout<<v;`
     152             :   template<unsigned m>
     153             :   friend std::ostream & operator<<(std::ostream &os, const VectorGeneric<m>&);
     154             : };
     155             : 
     156             : template<>
     157             : inline
     158             : VectorGeneric<2>:: VectorGeneric(double x0,double x1) {
     159             :   d[0]=x0;
     160             :   d[1]=x1;
     161             : }
     162             : 
     163             : template<>
     164             : inline
     165    32276449 : VectorGeneric<3>:: VectorGeneric(double x0,double x1,double x2) {
     166    32276449 :   d[0]=x0;
     167    32276449 :   d[1]=x1;
     168    32276449 :   d[2]=x2;
     169             : }
     170             : 
     171             : template<>
     172             : inline
     173      552731 : VectorGeneric<4>:: VectorGeneric(double x0,double x1,double x2,double x3) {
     174      552731 :   d[0]=x0;
     175      552731 :   d[1]=x1;
     176      552731 :   d[2]=x2;
     177      552731 :   d[3]=x3;
     178             : }
     179             : 
     180             : template <unsigned n>
     181     7650587 : void VectorGeneric<n>::zero() {
     182     7650587 :   LoopUnroller<n>::_zero(d);
     183     7650587 : }
     184             : 
     185             : template <unsigned n>
     186   674507040 : VectorGeneric<n>::VectorGeneric() {
     187   674507040 :   LoopUnroller<n>::_zero(d);
     188   674507040 : }
     189             : 
     190             : template <unsigned n>
     191  3387633629 : double & VectorGeneric<n>::operator[](unsigned i) {
     192             : #ifdef _GLIBCXX_DEBUG
     193             :   plumed_assert(i<n);
     194             : #endif
     195  3387633629 :   return d[i];
     196             : }
     197             : 
     198             : template <unsigned n>
     199  5560695982 : const double & VectorGeneric<n>::operator[](unsigned i)const {
     200             : #ifdef _GLIBCXX_DEBUG
     201             :   plumed_assert(i<n);
     202             : #endif
     203  5560695982 :   return d[i];
     204             : }
     205             : 
     206             : template <unsigned n>
     207   431354421 : double & VectorGeneric<n>::operator()(unsigned i) {
     208             : #ifdef _GLIBCXX_DEBUG
     209             :   plumed_assert(i<n);
     210             : #endif
     211   431354421 :   return d[i];
     212             : }
     213             : 
     214             : template <unsigned n>
     215   430601667 : const double & VectorGeneric<n>::operator()(unsigned i)const {
     216             : #ifdef _GLIBCXX_DEBUG
     217             :   plumed_assert(i<n);
     218             : #endif
     219   430601667 :   return d[i];
     220             : }
     221             : 
     222             : template <unsigned n>
     223  1374589527 : VectorGeneric<n>& VectorGeneric<n>::operator +=(const VectorGeneric<n>& b) {
     224  1374589527 :   LoopUnroller<n>::_add(d,b.d);
     225  1374589527 :   return *this;
     226             : }
     227             : 
     228             : template <unsigned n>
     229  1172350627 : VectorGeneric<n>& VectorGeneric<n>::operator -=(const VectorGeneric<n>& b) {
     230  1172350627 :   LoopUnroller<n>::_sub(d,b.d);
     231  1172350627 :   return *this;
     232             : }
     233             : 
     234             : template <unsigned n>
     235  1488014117 : VectorGeneric<n>& VectorGeneric<n>::operator *=(double s) {
     236  1488014117 :   LoopUnroller<n>::_mul(d,s);
     237  1488014117 :   return *this;
     238             : }
     239             : 
     240             : template <unsigned n>
     241        8560 : VectorGeneric<n>& VectorGeneric<n>::operator /=(double s) {
     242        8560 :   LoopUnroller<n>::_mul(d,1.0/s);
     243        8560 :   return *this;
     244             : }
     245             : 
     246             : template <unsigned n>
     247             : VectorGeneric<n>  VectorGeneric<n>::operator +()const {
     248             :   return *this;
     249             : }
     250             : 
     251             : template <unsigned n>
     252   110523296 : VectorGeneric<n> VectorGeneric<n>::operator -()const {
     253   110523296 :   VectorGeneric<n> r;
     254   110523296 :   LoopUnroller<n>::_neg(r.d,d);
     255   110523296 :   return r;
     256             : }
     257             : 
     258             : template <unsigned n>
     259  1227620621 : VectorGeneric<n> operator+(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
     260  1227620621 :   VectorGeneric<n> v(v1);
     261  1227620621 :   return v+=v2;
     262             : }
     263             : 
     264             : template <unsigned n>
     265  1163358653 : VectorGeneric<n> operator-(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
     266  1163358653 :   VectorGeneric<n> v(v1);
     267  1163358653 :   return v-=v2;
     268             : }
     269             : 
     270             : template <unsigned n>
     271  1487804112 : VectorGeneric<n> operator*(double s,const VectorGeneric<n>&v) {
     272  1487804112 :   VectorGeneric<n> vv(v);
     273  1487804112 :   return vv*=s;
     274             : }
     275             : 
     276             : template <unsigned n>
     277   115212202 : VectorGeneric<n> operator*(const VectorGeneric<n>&v,double s) {
     278   115212202 :   return s*v;
     279             : }
     280             : 
     281             : template <unsigned n>
     282     6666557 : VectorGeneric<n> operator/(const VectorGeneric<n>&v,double s) {
     283     6666557 :   return v*(1.0/s);
     284             : }
     285             : 
     286             : template <unsigned n>
     287   643989944 : VectorGeneric<n> delta(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
     288   643989944 :   return v2-v1;
     289             : }
     290             : 
     291             : template <unsigned n>
     292   516518289 : double VectorGeneric<n>::modulo2()const {
     293   516518289 :   return LoopUnroller<n>::_sum2(d);
     294             : }
     295             : 
     296             : template <unsigned n>
     297   165000500 : double dotProduct(const VectorGeneric<n>& v1,const VectorGeneric<n>& v2) {
     298   165000500 :   return LoopUnroller<n>::_dot(v1.d,v2.d);
     299             : }
     300             : 
     301             : inline
     302             : VectorGeneric<3> crossProduct(const VectorGeneric<3>& v1,const VectorGeneric<3>& v2) {
     303             :   return VectorGeneric<3>(
     304     5371260 :            v1[1]*v2[2]-v1[2]*v2[1],
     305     5371260 :            v1[2]*v2[0]-v1[0]*v2[2],
     306    21485040 :            v1[0]*v2[1]-v1[1]*v2[0]);
     307             : }
     308             : 
     309             : template<unsigned n>
     310    53183298 : double VectorGeneric<n>::modulo()const {
     311    53183298 :   return sqrt(modulo2());
     312             : }
     313             : 
     314             : template<unsigned n>
     315    20039441 : double modulo2(const VectorGeneric<n>&v) {
     316    20039441 :   return v.modulo2();
     317             : }
     318             : 
     319             : template<unsigned n>
     320         257 : double modulo(const VectorGeneric<n>&v) {
     321         257 :   return v.modulo();
     322             : }
     323             : 
     324             : template<unsigned n>
     325             : std::ostream & operator<<(std::ostream &os, const VectorGeneric<n>& v) {
     326             :   for(unsigned i=0; i<n-1; i++) os<<v(i)<<" ";
     327             :   os<<v(n-1);
     328             :   return os;
     329             : }
     330             : 
     331             : 
     332             : /// \ingroup TOOLBOX
     333             : /// Alias for two dimensional vectors
     334             : typedef VectorGeneric<2> Vector2d;
     335             : /// \ingroup TOOLBOX
     336             : /// Alias for three dimensional vectors
     337             : typedef VectorGeneric<3> Vector3d;
     338             : /// \ingroup TOOLBOX
     339             : /// Alias for four dimensional vectors
     340             : typedef VectorGeneric<4> Vector4d;
     341             : /// \ingroup TOOLBOX
     342             : /// Alias for three dimensional vectors
     343             : typedef Vector3d Vector;
     344             : 
     345             : }
     346             : 
     347             : #endif
     348             : 

Generated by: LCOV version 1.13