OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
Vector.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45/**
46 * @file Vector.hpp
47 * @author Teng Lin
48 * @date 09/14/2004
49 * @version 1.0
50 */
51
52#ifndef MATH_VECTOR_HPP
53#define MATH_VECTOR_HPP
54
55#include <config.h>
56
57#include <cassert>
58#include <cmath>
59#include <iostream>
60
61namespace OpenMD {
62
63 static constexpr RealType epsilon = 0.000001;
64
65 template<typename T>
66 inline bool equal(T e1, T e2) {
67 if constexpr (std::is_same_v<T, RealType>)
68 return std::fabs(e1 - e2) < epsilon;
69 else
70 return e1 == e2;
71 }
72
73 /**
74 * @class Vector Vector.hpp "math/Vector.hpp"
75 * @brief Fix length vector class
76 */
77 template<typename Real, unsigned int Dim>
78 class Vector {
79 public:
80 using ElemType = Real;
81 using ElemPoinerType = Real*;
82
83 /** default constructor */
84 inline Vector() {
85 for (unsigned int i = 0; i < Dim; i++)
86 this->data_[i] = 0;
87 }
88
89 /** Constructs and initializes a Vector from a vector */
90 inline Vector(const Vector<Real, Dim>& v) { *this = v; }
91
92 /** copy assignment operator */
94 if (this == &v) return *this;
95
96 for (unsigned int i = 0; i < Dim; i++)
97 this->data_[i] = v[i];
98
99 return *this;
100 }
101
102 /** array assignment operator */
103 inline Vector<Real, Dim>& operator=(const Real* v) {
104 for (unsigned int i = 0; i < Dim; i++)
105 this->data_[i] = v[i];
106
107 return *this;
108 }
109
110 // template<typename T>
111 // inline Vector(const T& s){
112 inline Vector(const Real& s) {
113 for (unsigned int i = 0; i < Dim; i++)
114 this->data_[i] = s;
115 }
116
117 /** Constructs and initializes a Vector from an array */
118 inline Vector(Real* v) {
119 for (unsigned int i = 0; i < Dim; i++)
120 this->data_[i] = v[i];
121 }
122
123 /**
124 * Returns reference of ith element.
125 * @return reference of ith element
126 * @param i index
127 */
128 inline Real& operator[](unsigned int i) {
129 assert(i < Dim);
130 return this->data_[i];
131 }
132
133 /**
134 * Returns reference of ith element.
135 * @return reference of ith element
136 * @param i index
137 */
138 inline Real& operator()(unsigned int i) {
139 assert(i < Dim);
140 return this->data_[i];
141 }
142
143 /**
144 * Returns constant reference of ith element.
145 * @return reference of ith element
146 * @param i index
147 */
148 inline const Real& operator[](unsigned int i) const {
149 assert(i < Dim);
150 return this->data_[i];
151 }
152
153 /**
154 * Returns constant reference of ith element.
155 * @return reference of ith element
156 * @param i index
157 */
158 inline const Real& operator()(unsigned int i) const {
159 assert(i < Dim);
160 return this->data_[i];
161 }
162
163 /** Copy the internal data to an array*/
164 void getArray(Real* array) {
165 for (unsigned int i = 0; i < Dim; i++) {
166 array[i] = this->data_[i];
167 }
168 }
169
170 /** Returns the pointer of internal array */
171 Real* getArrayPointer() { return this->data_; }
172
173 /**
174 * Tests if this vetor is equal to other vector
175 * @return true if equal, otherwise return false
176 * @param v vector to be compared
177 */
178 inline bool operator==(const Vector<Real, Dim>& v) {
179 for (unsigned int i = 0; i < Dim; i++) {
180 if (!equal(this->data_[i], v[i])) { return false; }
181 }
182
183 return true;
184 }
185
186 /**
187 * Tests if this vetor is not equal to other vector
188 * @return true if equal, otherwise return false
189 * @param v vector to be compared
190 */
191 inline bool operator!=(const Vector<Real, Dim>& v) { return !(*this == v); }
192
193 /** Zeros out the values in this vector in place */
194 inline void zero() {
195 for (unsigned int i = 0; i < Dim; i++)
196 this->data_[i] = 0;
197 }
198
199 /** Negates the value of this vector in place. */
200 inline void negate() {
201 for (unsigned int i = 0; i < Dim; i++)
202 this->data_[i] = -this->data_[i];
203 }
204
205 /**
206 * Sets the value of this vector to the negation of vector v1.
207 * @param v1 the source vector
208 */
209 inline void negate(const Vector<Real, Dim>& v1) {
210 for (unsigned int i = 0; i < Dim; i++)
211 this->data_[i] = -v1.data_[i];
212 }
213
214 /**
215 * Sets the value of this vector to the sum of itself and v1 (*this += v1).
216 * @param v1 the other vector
217 */
218 inline void add(const Vector<Real, Dim>& v1) {
219 for (unsigned int i = 0; i < Dim; i++)
220 this->data_[i] += v1.data_[i];
221 }
222
223 /**
224 * Sets the value of this vector to the sum of v1 and v2 (*this = v1 + v2).
225 * @param v1 the first vector
226 * @param v2 the second vector
227 */
228 inline void add(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
229 for (unsigned int i = 0; i < Dim; i++)
230 this->data_[i] = v1.data_[i] + v2.data_[i];
231 }
232
233 /**
234 * Sets the value of this vector to the difference of itself and v1 (*this
235 * -= v1).
236 * @param v1 the other vector
237 */
238 inline void sub(const Vector<Real, Dim>& v1) {
239 for (unsigned int i = 0; i < Dim; i++)
240 this->data_[i] -= v1.data_[i];
241 }
242
243 /**
244 * Sets the value of this vector to the difference of vector v1 and v2
245 * (*this = v1 - v2).
246 * @param v1 the first vector
247 * @param v2 the second vector
248 */
249 inline void sub(const Vector<Real, Dim>& v1, const Vector& v2) {
250 for (unsigned int i = 0; i < Dim; i++)
251 this->data_[i] = v1.data_[i] - v2.data_[i];
252 }
253
254 /**
255 * Sets the value of this vector to the scalar multiplication of itself
256 * (*this *= s).
257 * @param s the scalar value
258 */
259 inline void mul(Real s) {
260 for (unsigned int i = 0; i < Dim; i++)
261 this->data_[i] *= s;
262 }
263
264 /**
265 * Sets the value of this vector to the scalar multiplication of vector v1
266 * (*this = s * v1).
267 * @param v1 the vector
268 * @param s the scalar value
269 */
270 inline void mul(const Vector<Real, Dim>& v1, Real s) {
271 for (unsigned int i = 0; i < Dim; i++)
272 this->data_[i] = s * v1.data_[i];
273 }
274
275 /**
276 * Sets the elements of this vector to the multiplication of
277 * elements of two other vectors. Not to be confused with scalar
278 * multiplication (mul) or dot products.
279 *
280 * (*this.data_[i] = v1.data_[i] * v2.data_[i]).
281 * @param v1 the first vector
282 * @param v2 the second vector
283 */
284 inline void Vmul(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
285 for (unsigned int i = 0; i < Dim; i++)
286 this->data_[i] = v1.data_[i] * v2.data_[i];
287 }
288
289 /* replaces the elements with the absolute values of those elements */
290 inline Vector<Real, Dim>& abs() {
291 for (unsigned int i = 0; i < Dim; i++) {
292 this->data_[i] = std::abs(this->data_[i]);
293 }
294 return *this;
295 }
296
297 /* returns the maximum value in this vector */
298 inline Real max() {
299 Real val = this->data_[0];
300 for (unsigned int i = 0; i < Dim; i++) {
301 if (this->data_[i] > val) val = this->data_[i];
302 }
303 return val;
304 }
305
306 /**
307 * Sets the value of this vector to the scalar division of itself (*this /=
308 * s ).
309 * @param s the scalar value
310 */
311 inline void div(Real s) {
312 for (unsigned int i = 0; i < Dim; i++)
313 this->data_[i] /= s;
314 }
315
316 /**
317 * Sets the value of this vector to the scalar division of vector v1 (*this
318 * = v1 / s ).
319 * @param v1 the source vector
320 * @param s the scalar value
321 */
322 inline void div(const Vector<Real, Dim>& v1, Real s) {
323 for (unsigned int i = 0; i < Dim; i++)
324 this->data_[i] = v1.data_[i] / s;
325 }
326
327 /**
328 * Sets the elements of this vector to the division of
329 * elements of two other vectors. Not to be confused with scalar
330 * division (div)
331 *
332 * (*this.data_[i] = v1.data_[i] / v2.data_[i]).
333 * @param v1 the first vector
334 * @param v2 the second vector
335 */
336 inline void Vdiv(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
337 for (unsigned int i = 0; i < Dim; i++)
338 this->data_[i] = v1.data_[i] / v2.data_[i];
339 }
340
341 /** @see #add */
343 add(v1);
344 return *this;
345 }
346
347 /** @see #sub */
349 sub(v1);
350 return *this;
351 }
352
353 /** @see #mul */
355 mul(s);
356 return *this;
357 }
358
359 /** @see #div */
361 div(s);
362 return *this;
363 }
364
365 /**
366 * Returns the sum of all elements of this vector.
367 * @return the sum of all elements of this vector
368 */
369 inline Real sum() {
370 Real tmp;
371 tmp = 0;
372 for (unsigned int i = 0; i < Dim; i++)
373 tmp += this->data_[i];
374 return tmp;
375 }
376
377 /**
378 * Returns the product of all elements of this vector.
379 * @return the product of all elements of this vector
380 */
381 inline Real componentProduct() {
382 Real tmp;
383 tmp = 1;
384 for (unsigned int i = 0; i < Dim; i++)
385 tmp *= this->data_[i];
386 return tmp;
387 }
388
389 /**
390 * Returns the length of this vector.
391 * @return the length of this vector
392 */
393 inline Real length() { return sqrt(lengthSquare()); }
394
395 /**
396 * Returns the squared length of this vector.
397 * @return the squared length of this vector
398 */
399 inline Real lengthSquare() { return dot(*this, *this); }
400
401 /** Normalizes this vector in place */
402 inline void normalize() {
403 Real len;
404
405 len = length();
406
407 // if (len < OpenMD::Constants::epsilon)
408 // throw();
409
410 *this /= len;
411 }
412
413 /**
414 * Tests if this vector is normalized
415 * @return true if this vector is normalized, otherwise return false
416 */
417 inline bool isNormalized() { return equal(lengthSquare(), (RealType)1); }
418
419 unsigned int size() const { return Dim; }
420
421 protected:
422 Real data_[Dim] {};
423 };
424
425 /** unary minus*/
426 template<typename Real, unsigned int Dim>
428 Vector<Real, Dim> tmp(v1);
429 tmp.negate();
430 return tmp;
431 }
432
433 /**
434 * Return the sum of two vectors (v1 - v2).
435 * @return the sum of two vectors
436 * @param v1 the first vector
437 * @param v2 the second vector
438 */
439 template<typename Real, unsigned int Dim>
440 inline Vector<Real, Dim> operator+(const Vector<Real, Dim>& v1,
441 const Vector<Real, Dim>& v2) {
442 Vector<Real, Dim> result;
443
444 result.add(v1, v2);
445 return result;
446 }
447
448 /**
449 * Return the difference of two vectors (v1 - v2).
450 * @return the difference of two vectors
451 * @param v1 the first vector
452 * @param v2 the second vector
453 */
454 template<typename Real, unsigned int Dim>
456 const Vector<Real, Dim>& v2) {
457 Vector<Real, Dim> result;
458 result.sub(v1, v2);
459 return result;
460 }
461
462 /**
463 * Returns the vaule of scalar multiplication of this vector v1 (v1 * r).
464 * @return the vaule of scalar multiplication of this vector
465 * @param v1 the source vector
466 * @param s the scalar value
467 */
468 template<typename Real, unsigned int Dim>
470 Vector<Real, Dim> result;
471 result.mul(v1, s);
472 return result;
473 }
474
475 /**
476 * Returns the vaule of scalar multiplication of this vector v1 (v1 * r).
477 * @return the vaule of scalar multiplication of this vector
478 * @param s the scalar value
479 * @param v1 the source vector
480 */
481 template<typename Real, unsigned int Dim>
483 Vector<Real, Dim> result;
484 result.mul(v1, s);
485 return result;
486 }
487
488 /**
489 * Returns the value of division of a vector by a scalar.
490 * @return the vaule of scalar division of this vector
491 * @param v1 the source vector
492 * @param s the scalar value
493 */
494 template<typename Real, unsigned int Dim>
496 Vector<Real, Dim> result;
497 result.div(v1, s);
498 return result;
499 }
500
501 /**
502 * Returns the dot product of two Vectors
503 * @param v1 first vector
504 * @param v2 second vector
505 * @return the dot product of v1 and v2
506 */
507 template<typename Real, unsigned int Dim>
508 inline Real dot(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
509 Real tmp;
510 tmp = 0;
511
512 for (unsigned int i = 0; i < Dim; i++)
513 tmp += v1[i] * v2[i];
514
515 return tmp;
516 }
517
518 /**
519 * Returns the wide dot product of three Vectors. Compare with
520 * Rapaport's VWDot function.
521 *
522 * @param v1 first vector
523 * @param v2 second vector
524 * @param v3 third vector
525 * @return the wide dot product of v1, v2, and v3.
526 */
527 template<typename Real, unsigned int Dim>
528 inline Real dot(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2,
529 const Vector<Real, Dim>& v3) {
530 Real tmp;
531 tmp = 0;
532
533 for (unsigned int i = 0; i < Dim; i++)
534 tmp += v1[i] * v2[i] * v3[i];
535
536 return tmp;
537 }
538
539 /**
540 * Returns the distance between two Vectors
541 * @param v1 first vector
542 * @param v2 second vector
543 * @return the distance between v1 and v2
544 */
545 template<typename Real, unsigned int Dim>
546 inline Real distance(const Vector<Real, Dim>& v1,
547 const Vector<Real, Dim>& v2) {
548 Vector<Real, Dim> tempVector = v1 - v2;
549 return tempVector.length();
550 }
551
552 /**
553 * Returns the squared distance between two Vectors
554 * @param v1 first vector
555 * @param v2 second vector
556 * @return the squared distance between v1 and v2
557 */
558 template<typename Real, unsigned int Dim>
559 inline Real distanceSquare(const Vector<Real, Dim>& v1,
560 const Vector<Real, Dim>& v2) {
561 Vector<Real, Dim> tempVector = v1 - v2;
562 return tempVector.lengthSquare();
563 }
564
565 /**
566 * Write to an output stream
567 */
568 template<typename Real, unsigned int Dim>
569 std::ostream& operator<<(std::ostream& o, const Vector<Real, Dim>& v) {
570 o << "[ ";
571
572 for (unsigned int i = 0; i < Dim; i++) {
573 o << v[i];
574
575 if (i != Dim - 1) { o << ", "; }
576 }
577
578 o << " ]";
579 return o;
580 }
581
582} // namespace OpenMD
583
584#endif
Fix length vector class.
Definition Vector.hpp:78
Vector< Real, Dim > & operator=(const Vector< Real, Dim > &v)
copy assignment operator
Definition Vector.hpp:93
Vector< Real, Dim > & operator=(const Real *v)
array assignment operator
Definition Vector.hpp:103
void div(const Vector< Real, Dim > &v1, Real s)
Sets the value of this vector to the scalar division of vector v1 (*this = v1 / s ).
Definition Vector.hpp:322
const Real & operator()(unsigned int i) const
Returns constant reference of ith element.
Definition Vector.hpp:158
void div(Real s)
Sets the value of this vector to the scalar division of itself (*this /= s ).
Definition Vector.hpp:311
void zero()
Zeros out the values in this vector in place.
Definition Vector.hpp:194
Real length()
Returns the length of this vector.
Definition Vector.hpp:393
void getArray(Real *array)
Copy the internal data to an array.
Definition Vector.hpp:164
void normalize()
Normalizes this vector in place.
Definition Vector.hpp:402
Real & operator()(unsigned int i)
Returns reference of ith element.
Definition Vector.hpp:138
Real componentProduct()
Returns the product of all elements of this vector.
Definition Vector.hpp:381
void mul(Real s)
Sets the value of this vector to the scalar multiplication of itself (*this *= s).
Definition Vector.hpp:259
Vector(const Vector< Real, Dim > &v)
Constructs and initializes a Vector from a vector.
Definition Vector.hpp:90
bool operator!=(const Vector< Real, Dim > &v)
Tests if this vetor is not equal to other vector.
Definition Vector.hpp:191
Real sum()
Returns the sum of all elements of this vector.
Definition Vector.hpp:369
void sub(const Vector< Real, Dim > &v1)
Sets the value of this vector to the difference of itself and v1 (*this -= v1).
Definition Vector.hpp:238
void Vmul(const Vector< Real, Dim > &v1, const Vector< Real, Dim > &v2)
Sets the elements of this vector to the multiplication of elements of two other vectors.
Definition Vector.hpp:284
Vector< Real, Dim > & operator*=(Real s)
Definition Vector.hpp:354
Real * getArrayPointer()
Returns the pointer of internal array.
Definition Vector.hpp:171
bool isNormalized()
Tests if this vector is normalized.
Definition Vector.hpp:417
void sub(const Vector< Real, Dim > &v1, const Vector &v2)
Sets the value of this vector to the difference of vector v1 and v2 (*this = v1 - v2).
Definition Vector.hpp:249
Real lengthSquare()
Returns the squared length of this vector.
Definition Vector.hpp:399
void negate(const Vector< Real, Dim > &v1)
Sets the value of this vector to the negation of vector v1.
Definition Vector.hpp:209
Real & operator[](unsigned int i)
Returns reference of ith element.
Definition Vector.hpp:128
const Real & operator[](unsigned int i) const
Returns constant reference of ith element.
Definition Vector.hpp:148
bool operator==(const Vector< Real, Dim > &v)
Tests if this vetor is equal to other vector.
Definition Vector.hpp:178
Vector< Real, Dim > & operator-=(const Vector< Real, Dim > &v1)
Definition Vector.hpp:348
void add(const Vector< Real, Dim > &v1, const Vector< Real, Dim > &v2)
Sets the value of this vector to the sum of v1 and v2 (*this = v1 + v2).
Definition Vector.hpp:228
void mul(const Vector< Real, Dim > &v1, Real s)
Sets the value of this vector to the scalar multiplication of vector v1 (*this = s * v1).
Definition Vector.hpp:270
void negate()
Negates the value of this vector in place.
Definition Vector.hpp:200
void Vdiv(const Vector< Real, Dim > &v1, const Vector< Real, Dim > &v2)
Sets the elements of this vector to the division of elements of two other vectors.
Definition Vector.hpp:336
void add(const Vector< Real, Dim > &v1)
Sets the value of this vector to the sum of itself and v1 (*this += v1).
Definition Vector.hpp:218
Vector< Real, Dim > & operator/=(Real s)
Definition Vector.hpp:360
Vector(Real *v)
Constructs and initializes a Vector from an array.
Definition Vector.hpp:118
Vector()
default constructor
Definition Vector.hpp:84
Vector< Real, Dim > & operator+=(const Vector< Real, Dim > &v1)
Definition Vector.hpp:342
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
DynamicRectMatrix< Real > operator-(const DynamicRectMatrix< Real > &m)
Negate the value of every element of this matrix.
bool equal(const Polynomial< Real > &p1, const Polynomial< Real > &p2)
Tests if two polynomial have the same exponents.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
DynamicRectMatrix< Real > operator*(const DynamicRectMatrix< Real > &m, Real s)
Return the multiplication of scalar and matrix (m * s).
Real distanceSquare(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the squared distance between two DynamicVectors.
Real distance(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the distance between two DynamicVectors.
DynamicRectMatrix< Real > operator/(const DynamicRectMatrix< Real > &m, Real s)
Return the scalar division of matrix (m / s).