OpenMD 3.2
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 following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48/**
49 * @file Vector.hpp
50 * @author Teng Lin
51 * @date 09/14/2004
52 * @version 1.0
53 */
54
55#ifndef MATH_VECTOR_HPP
56#define MATH_VECTOR_HPP
57
58#include <config.h>
59
60#include <cassert>
61#include <cmath>
62#include <iostream>
63
64namespace OpenMD {
65
66 static constexpr RealType epsilon = 0.000001;
67
68 template<typename T>
69 inline bool equal(T e1, T e2) {
70 if constexpr (std::is_same_v<T, RealType>)
71 return std::fabs(e1 - e2) < epsilon;
72 else
73 return e1 == e2;
74 }
75
76 /**
77 * @class Vector Vector.hpp "math/Vector.hpp"
78 * @brief Fix length vector class
79 */
80 template<typename Real, unsigned int Dim>
81 class Vector {
82 public:
83 using ElemType = Real;
84 using ElemPoinerType = Real*;
85
86 /** default constructor */
87 inline Vector() {
88 for (unsigned int i = 0; i < Dim; i++)
89 this->data_[i] = 0;
90 }
91
92 /** Constructs and initializes a Vector from a vector */
93 inline Vector(const Vector<Real, Dim>& v) { *this = v; }
94
95 /** copy assignment operator */
97 if (this == &v) return *this;
98
99 for (unsigned int i = 0; i < Dim; i++)
100 this->data_[i] = v[i];
101
102 return *this;
103 }
104
105 /** array assignment operator */
106 inline Vector<Real, Dim>& operator=(const Real* v) {
107 for (unsigned int i = 0; i < Dim; i++)
108 this->data_[i] = v[i];
109
110 return *this;
111 }
112
113 // template<typename T>
114 // inline Vector(const T& s){
115 inline Vector(const Real& s) {
116 for (unsigned int i = 0; i < Dim; i++)
117 this->data_[i] = s;
118 }
119
120 /** Constructs and initializes a Vector from an array */
121 inline Vector(Real* v) {
122 for (unsigned int i = 0; i < Dim; i++)
123 this->data_[i] = v[i];
124 }
125
126 /**
127 * Returns reference of ith element.
128 * @return reference of ith element
129 * @param i index
130 */
131 inline Real& operator[](unsigned int i) {
132 assert(i < Dim);
133 return this->data_[i];
134 }
135
136 /**
137 * Returns reference of ith element.
138 * @return reference of ith element
139 * @param i index
140 */
141 inline Real& operator()(unsigned int i) {
142 assert(i < Dim);
143 return this->data_[i];
144 }
145
146 /**
147 * Returns constant reference of ith element.
148 * @return reference of ith element
149 * @param i index
150 */
151 inline const Real& operator[](unsigned int i) const {
152 assert(i < Dim);
153 return this->data_[i];
154 }
155
156 /**
157 * Returns constant reference of ith element.
158 * @return reference of ith element
159 * @param i index
160 */
161 inline const Real& operator()(unsigned int i) const {
162 assert(i < Dim);
163 return this->data_[i];
164 }
165
166 /** Copy the internal data to an array*/
167 void getArray(Real* array) const {
168 for (unsigned int i = 0; i < Dim; i++) {
169 array[i] = this->data_[i];
170 }
171 }
172
173 /** Returns the pointer of internal array */
174 const Real* getArrayPointer() const { return this->data_; }
175 Real* getArrayPointer() { return this->data_; }
176
177 /**
178 * Tests if this vetor is equal to other vector
179 * @return true if equal, otherwise return false
180 * @param v vector to be compared
181 */
182 inline bool operator==(const Vector<Real, Dim>& v) {
183 for (unsigned int i = 0; i < Dim; i++) {
184 if (!equal(this->data_[i], v[i])) { return false; }
185 }
186
187 return true;
188 }
189
190 /**
191 * Tests if this vetor is not equal to other vector
192 * @return true if equal, otherwise return false
193 * @param v vector to be compared
194 */
195 inline bool operator!=(const Vector<Real, Dim>& v) { return !(*this == v); }
196
197 /** Zeros out the values in this vector in place */
198 inline void zero() {
199 for (unsigned int i = 0; i < Dim; i++)
200 this->data_[i] = 0;
201 }
202
203 /** Negates the value of this vector in place. */
204 inline void negate() {
205 for (unsigned int i = 0; i < Dim; i++)
206 this->data_[i] = -this->data_[i];
207 }
208
209 /**
210 * Sets the value of this vector to the negation of vector v1.
211 * @param v1 the source vector
212 */
213 inline void negate(const Vector<Real, Dim>& v1) {
214 for (unsigned int i = 0; i < Dim; i++)
215 this->data_[i] = -v1.data_[i];
216 }
217
218 /**
219 * Sets the value of this vector to the sum of itself and v1 (*this += v1).
220 * @param v1 the other vector
221 */
222 inline void add(const Vector<Real, Dim>& v1) {
223 for (unsigned int i = 0; i < Dim; i++)
224 this->data_[i] += v1.data_[i];
225 }
226
227 /**
228 * Sets the value of this vector to the sum of v1 and v2 (*this = v1 + v2).
229 * @param v1 the first vector
230 * @param v2 the second vector
231 */
232 inline void add(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
233 for (unsigned int i = 0; i < Dim; i++)
234 this->data_[i] = v1.data_[i] + v2.data_[i];
235 }
236
237 /**
238 * Sets the value of this vector to the difference of itself and v1 (*this
239 * -= v1).
240 * @param v1 the other vector
241 */
242 inline void sub(const Vector<Real, Dim>& v1) {
243 for (unsigned int i = 0; i < Dim; i++)
244 this->data_[i] -= v1.data_[i];
245 }
246
247 /**
248 * Sets the value of this vector to the difference of vector v1 and v2
249 * (*this = v1 - v2).
250 * @param v1 the first vector
251 * @param v2 the second vector
252 */
253 inline void sub(const Vector<Real, Dim>& v1, const Vector& v2) {
254 for (unsigned int i = 0; i < Dim; i++)
255 this->data_[i] = v1.data_[i] - v2.data_[i];
256 }
257
258 /**
259 * Sets the value of this vector to the scalar multiplication of itself
260 * (*this *= s).
261 * @param s the scalar value
262 */
263 inline void mul(Real s) {
264 for (unsigned int i = 0; i < Dim; i++)
265 this->data_[i] *= s;
266 }
267
268 /**
269 * Sets the value of this vector to the scalar multiplication of vector v1
270 * (*this = s * v1).
271 * @param v1 the vector
272 * @param s the scalar value
273 */
274 inline void mul(const Vector<Real, Dim>& v1, Real s) {
275 for (unsigned int i = 0; i < Dim; i++)
276 this->data_[i] = s * v1.data_[i];
277 }
278
279 /**
280 * Sets the elements of this vector to the multiplication of
281 * elements of two other vectors. Not to be confused with scalar
282 * multiplication (mul) or dot products.
283 *
284 * (*this.data_[i] = v1.data_[i] * v2.data_[i]).
285 * @param v1 the first vector
286 * @param v2 the second vector
287 */
288 inline void Vmul(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
289 for (unsigned int i = 0; i < Dim; i++)
290 this->data_[i] = v1.data_[i] * v2.data_[i];
291 }
292
293 /* replaces the elements with the absolute values of those elements */
294 inline Vector<Real, Dim>& abs() {
295 for (unsigned int i = 0; i < Dim; i++) {
296 this->data_[i] = std::abs(this->data_[i]);
297 }
298 return *this;
299 }
300
301 /* returns the maximum value in this vector */
302 inline Real max() const {
303 Real val = this->data_[0];
304 for (unsigned int i = 0; i < Dim; i++) {
305 if (this->data_[i] > val) val = this->data_[i];
306 }
307 return val;
308 }
309
310 /**
311 * Sets the value of this vector to the scalar division of itself (*this /=
312 * s ).
313 * @param s the scalar value
314 */
315 inline void div(Real s) {
316 for (unsigned int i = 0; i < Dim; i++)
317 this->data_[i] /= s;
318 }
319
320 /**
321 * Sets the value of this vector to the scalar division of vector v1 (*this
322 * = v1 / s ).
323 * @param v1 the source vector
324 * @param s the scalar value
325 */
326 inline void div(const Vector<Real, Dim>& v1, Real s) {
327 for (unsigned int i = 0; i < Dim; i++)
328 this->data_[i] = v1.data_[i] / s;
329 }
330
331 /**
332 * Sets the elements of this vector to the division of
333 * elements of two other vectors. Not to be confused with scalar
334 * division (div)
335 *
336 * (*this.data_[i] = v1.data_[i] / v2.data_[i]).
337 * @param v1 the first vector
338 * @param v2 the second vector
339 */
340 inline void Vdiv(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
341 for (unsigned int i = 0; i < Dim; i++)
342 this->data_[i] = v1.data_[i] / v2.data_[i];
343 }
344
345 /** @see #add */
347 add(v1);
348 return *this;
349 }
350
351 /** @see #sub */
353 sub(v1);
354 return *this;
355 }
356
357 /** @see #mul */
359 mul(s);
360 return *this;
361 }
362
363 /** @see #div */
365 div(s);
366 return *this;
367 }
368
369 /**
370 * Returns the sum of all elements of this vector.
371 * @return the sum of all elements of this vector
372 */
373 inline Real sum() const {
374 Real tmp;
375 tmp = 0;
376 for (unsigned int i = 0; i < Dim; i++)
377 tmp += this->data_[i];
378 return tmp;
379 }
380
381 /**
382 * Returns the product of all elements of this vector.
383 * @return the product of all elements of this vector
384 */
385 inline Real componentProduct() const {
386 Real tmp;
387 tmp = 1;
388 for (unsigned int i = 0; i < Dim; i++)
389 tmp *= this->data_[i];
390 return tmp;
391 }
392
393 /**
394 * Returns the length of this vector.
395 * @return the length of this vector
396 */
397 inline Real length() const { return sqrt(lengthSquare()); }
398
399 /**
400 * Returns the squared length of this vector.
401 * @return the squared length of this vector
402 */
403 inline Real lengthSquare() const { return dot(*this, *this); }
404
405 /** Normalizes this vector in place */
406 inline void normalize() {
407 Real len;
408
409 len = length();
410
411 *this /= len;
412 }
413
414 /**
415 * Tests if this vector is normalized
416 * @return true if this vector is normalized, otherwise return false
417 */
418 inline bool isNormalized() const { return equal(lengthSquare(), (RealType)1); }
419
420 unsigned int size() const { return Dim; }
421
422 protected:
423 Real data_[Dim] {};
424 };
425
426 /** unary minus*/
427 template<typename Real, unsigned int Dim>
429 Vector<Real, Dim> tmp(v1);
430 tmp.negate();
431 return tmp;
432 }
433
434 /**
435 * Return the sum of two vectors (v1 - v2).
436 * @return the sum of two vectors
437 * @param v1 the first vector
438 * @param v2 the second vector
439 */
440 template<typename Real, unsigned int Dim>
441 inline Vector<Real, Dim> operator+(const Vector<Real, Dim>& v1,
442 const Vector<Real, Dim>& v2) {
443 Vector<Real, Dim> result;
444
445 result.add(v1, v2);
446 return result;
447 }
448
449 /**
450 * Return the difference of two vectors (v1 - v2).
451 * @return the difference of two vectors
452 * @param v1 the first vector
453 * @param v2 the second vector
454 */
455 template<typename Real, unsigned int Dim>
457 const Vector<Real, Dim>& v2) {
458 Vector<Real, Dim> result;
459 result.sub(v1, v2);
460 return result;
461 }
462
463 /**
464 * Returns the vaule of scalar multiplication of this vector v1 (v1 * r).
465 * @return the vaule of scalar multiplication of this vector
466 * @param v1 the source vector
467 * @param s the scalar value
468 */
469 template<typename Real, unsigned int Dim>
471 Vector<Real, Dim> result;
472 result.mul(v1, s);
473 return result;
474 }
475
476 /**
477 * Returns the vaule of scalar multiplication of this vector v1 (v1 * r).
478 * @return the vaule of scalar multiplication of this vector
479 * @param s the scalar value
480 * @param v1 the source vector
481 */
482 template<typename Real, unsigned int Dim>
484 Vector<Real, Dim> result;
485 result.mul(v1, s);
486 return result;
487 }
488
489 /**
490 * Returns the value of division of a vector by a scalar.
491 * @return the vaule of scalar division of this vector
492 * @param v1 the source vector
493 * @param s the scalar value
494 */
495 template<typename Real, unsigned int Dim>
497 Vector<Real, Dim> result;
498 result.div(v1, s);
499 return result;
500 }
501
502 /**
503 * Returns the dot product of two Vectors
504 * @param v1 first vector
505 * @param v2 second vector
506 * @return the dot product of v1 and v2
507 */
508 template<typename Real, unsigned int Dim>
509 inline Real dot(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2) {
510 Real tmp;
511 tmp = 0;
512
513 for (unsigned int i = 0; i < Dim; i++)
514 tmp += v1[i] * v2[i];
515
516 return tmp;
517 }
518
519 /**
520 * Returns the wide dot product of three Vectors. Compare with
521 * Rapaport's VWDot function.
522 *
523 * @param v1 first vector
524 * @param v2 second vector
525 * @param v3 third vector
526 * @return the wide dot product of v1, v2, and v3.
527 */
528 template<typename Real, unsigned int Dim>
529 inline Real dot(const Vector<Real, Dim>& v1, const Vector<Real, Dim>& v2,
530 const Vector<Real, Dim>& v3) {
531 Real tmp;
532 tmp = 0;
533
534 for (unsigned int i = 0; i < Dim; i++)
535 tmp += v1[i] * v2[i] * v3[i];
536
537 return tmp;
538 }
539
540 /**
541 * Returns the distance between two Vectors
542 * @param v1 first vector
543 * @param v2 second vector
544 * @return the distance between v1 and v2
545 */
546 template<typename Real, unsigned int Dim>
547 inline Real distance(const Vector<Real, Dim>& v1,
548 const Vector<Real, Dim>& v2) {
549 Vector<Real, Dim> tempVector = v1 - v2;
550 return tempVector.length();
551 }
552
553 /**
554 * Returns the squared distance between two Vectors
555 * @param v1 first vector
556 * @param v2 second vector
557 * @return the squared distance between v1 and v2
558 */
559 template<typename Real, unsigned int Dim>
560 inline Real distanceSquare(const Vector<Real, Dim>& v1,
561 const Vector<Real, Dim>& v2) {
562 Vector<Real, Dim> tempVector = v1 - v2;
563 return tempVector.lengthSquare();
564 }
565
566 /**
567 * Write to an output stream
568 */
569 template<typename Real, unsigned int Dim>
570 std::ostream& operator<<(std::ostream& o, const Vector<Real, Dim>& v) {
571 o << "[ ";
572
573 for (unsigned int i = 0; i < Dim; i++) {
574 o << v[i];
575
576 if (i != Dim - 1) { o << ", "; }
577 }
578
579 o << " ]";
580 return o;
581 }
582
583} // namespace OpenMD
584
585#endif
Fix length vector class.
Definition Vector.hpp:81
Vector< Real, Dim > & operator=(const Vector< Real, Dim > &v)
copy assignment operator
Definition Vector.hpp:96
Vector< Real, Dim > & operator=(const Real *v)
array assignment operator
Definition Vector.hpp:106
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:326
const Real & operator()(unsigned int i) const
Returns constant reference of ith element.
Definition Vector.hpp:161
void div(Real s)
Sets the value of this vector to the scalar division of itself (*this /= s ).
Definition Vector.hpp:315
void zero()
Zeros out the values in this vector in place.
Definition Vector.hpp:198
const Real * getArrayPointer() const
Returns the pointer of internal array.
Definition Vector.hpp:174
void normalize()
Normalizes this vector in place.
Definition Vector.hpp:406
Real & operator()(unsigned int i)
Returns reference of ith element.
Definition Vector.hpp:141
void mul(Real s)
Sets the value of this vector to the scalar multiplication of itself (*this *= s).
Definition Vector.hpp:263
Vector(const Vector< Real, Dim > &v)
Constructs and initializes a Vector from a vector.
Definition Vector.hpp:93
Real sum() const
Returns the sum of all elements of this vector.
Definition Vector.hpp:373
bool operator!=(const Vector< Real, Dim > &v)
Tests if this vetor is not equal to other vector.
Definition Vector.hpp:195
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:242
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:288
Vector< Real, Dim > & operator*=(Real s)
Definition Vector.hpp:358
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:253
Real length() const
Returns the length of this vector.
Definition Vector.hpp:397
void getArray(Real *array) const
Copy the internal data to an array.
Definition Vector.hpp:167
void negate(const Vector< Real, Dim > &v1)
Sets the value of this vector to the negation of vector v1.
Definition Vector.hpp:213
Real & operator[](unsigned int i)
Returns reference of ith element.
Definition Vector.hpp:131
const Real & operator[](unsigned int i) const
Returns constant reference of ith element.
Definition Vector.hpp:151
bool operator==(const Vector< Real, Dim > &v)
Tests if this vetor is equal to other vector.
Definition Vector.hpp:182
Vector< Real, Dim > & operator-=(const Vector< Real, Dim > &v1)
Definition Vector.hpp:352
Real lengthSquare() const
Returns the squared length of this vector.
Definition Vector.hpp:403
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:232
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:274
void negate()
Negates the value of this vector in place.
Definition Vector.hpp:204
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:340
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:222
Vector< Real, Dim > & operator/=(Real s)
Definition Vector.hpp:364
Real componentProduct() const
Returns the product of all elements of this vector.
Definition Vector.hpp:385
Vector(Real *v)
Constructs and initializes a Vector from an array.
Definition Vector.hpp:121
Vector()
default constructor
Definition Vector.hpp:87
Vector< Real, Dim > & operator+=(const Vector< Real, Dim > &v1)
Definition Vector.hpp:346
bool isNormalized() const
Tests if this vector is normalized.
Definition Vector.hpp:418
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).