Collective Variables Module - Developer Documentation
Loading...
Searching...
No Matches
colvartypes.h
1// -*- c++ -*-
2
3// This file is part of the Collective Variables module (Colvars).
4// The original version of Colvars and its updates are located at:
5// https://github.com/Colvars/colvars
6// Please update all Colvars source files before making any changes.
7// If you wish to distribute your changes, please submit them to the
8// Colvars repository at GitHub.
9
10#ifndef COLVARTYPES_H
11#define COLVARTYPES_H
12
13#include <sstream> // TODO specialize templates and replace this with iosfwd
14#include <vector>
15#include <array>
16
17#ifdef COLVARS_LAMMPS
18// Use open-source Jacobi implementation
19#include "math_eigen_impl.h"
20#endif
21
22#include "colvarmodule.h"
23
24// ----------------------------------------------------------------------
27// ----------------------------------------------------------------------
28
29
33template <class T> class colvarmodule::vector1d
34{
35protected:
36
37 std::vector<T> data;
38
39public:
40
42 inline vector1d(size_t const n = 0)
43 {
44 data.resize(n);
45 reset();
46 }
47
49 inline vector1d(size_t const n, T const *t)
50 {
51 data.resize(n);
52 reset();
53 size_t i;
54 for (i = 0; i < size(); i++) {
55 data[i] = t[i];
56 }
57 }
58
60 inline vector1d(const vector1d&) = default;
61
63 inline vector1d& operator=(const vector1d&) = default;
64
66 inline T * c_array()
67 {
68 if (data.size() > 0) {
69 return &(data[0]);
70 } else {
71 return NULL;
72 }
73 }
74
76 inline std::vector<T> &data_array()
77 {
78 return data;
79 }
80
82 inline std::vector<T> const &data_array() const
83 {
84 return data;
85 }
86
87 inline ~vector1d()
88 {
89 data.clear();
90 }
91
93 inline void reset()
94 {
95 data.assign(data.size(), T(0.0));
96 }
97
98 inline size_t size() const
99 {
100 return data.size();
101 }
102
103 inline void resize(size_t const n)
104 {
105 data.resize(n);
106 }
107
108 inline void clear()
109 {
110 data.clear();
111 }
112
113 inline T & operator [] (size_t const i) {
114 return data[i];
115 }
116
117 inline T const & operator [] (size_t const i) const {
118 return data[i];
119 }
120
121 inline static void check_sizes(vector1d<T> const &v1, vector1d<T> const &v2)
122 {
123 if (v1.size() != v2.size()) {
124 cvm::error("Error: trying to perform an operation between vectors of different sizes, "+
125 cvm::to_str(v1.size())+" and "+cvm::to_str(v2.size())+".\n");
126 }
127 }
128
129 inline void operator += (vector1d<T> const &v)
130 {
131 check_sizes(*this, v);
132 size_t i;
133 for (i = 0; i < this->size(); i++) {
134 (*this)[i] += v[i];
135 }
136 }
137
138 inline void operator -= (vector1d<T> const &v)
139 {
140 check_sizes(*this, v);
141 size_t i;
142 for (i = 0; i < this->size(); i++) {
143 (*this)[i] -= v[i];
144 }
145 }
146
147 inline void operator *= (cvm::real a)
148 {
149 size_t i;
150 for (i = 0; i < this->size(); i++) {
151 (*this)[i] *= a;
152 }
153 }
154
155 inline void operator /= (cvm::real a)
156 {
157 size_t i;
158 for (i = 0; i < this->size(); i++) {
159 (*this)[i] /= a;
160 }
161 }
162
163 inline friend vector1d<T> operator + (vector1d<T> const &v1,
164 vector1d<T> const &v2)
165 {
166 check_sizes(v1.size(), v2.size());
167 vector1d<T> result(v1.size());
168 size_t i;
169 for (i = 0; i < v1.size(); i++) {
170 result[i] = v1[i] + v2[i];
171 }
172 return result;
173 }
174
175 inline friend vector1d<T> operator - (vector1d<T> const &v1,
176 vector1d<T> const &v2)
177 {
178 check_sizes(v1.size(), v2.size());
179 vector1d<T> result(v1.size());
180 size_t i;
181 for (i = 0; i < v1.size(); i++) {
182 result[i] = v1[i] - v2[i];
183 }
184 return result;
185 }
186
187 inline friend vector1d<T> operator * (vector1d<T> const &v, cvm::real a)
188 {
189 vector1d<T> result(v.size());
190 size_t i;
191 for (i = 0; i < v.size(); i++) {
192 result[i] = v[i] * a;
193 }
194 return result;
195 }
196
197 inline friend vector1d<T> operator * (cvm::real a, vector1d<T> const &v)
198 {
199 return v * a;
200 }
201
202 inline friend vector1d<T> operator / (vector1d<T> const &v, cvm::real a)
203 {
204 vector1d<T> result(v.size());
205 size_t i;
206 for (i = 0; i < v.size(); i++) {
207 result[i] = v[i] / a;
208 }
209 return result;
210 }
211
213 inline friend T operator * (vector1d<T> const &v1, vector1d<T> const &v2)
214 {
215 check_sizes(v1.size(), v2.size());
216 T prod(0.0);
217 size_t i;
218 for (i = 0; i < v1.size(); i++) {
219 prod += v1[i] * v2[i];
220 }
221 return prod;
222 }
223
225 inline cvm::real norm2() const
226 {
227 cvm::real result = 0.0;
228 size_t i;
229 for (i = 0; i < this->size(); i++) {
230 result += (*this)[i] * (*this)[i];
231 }
232 return result;
233 }
234
235 inline cvm::real norm() const
236 {
237 return cvm::sqrt(this->norm2());
238 }
239
240 inline cvm::real sum() const
241 {
242 cvm::real result = 0.0;
243 size_t i;
244 for (i = 0; i < this->size(); i++) {
245 result += (*this)[i];
246 }
247 return result;
248 }
249
251 inline vector1d<T> const slice(size_t const i1, size_t const i2) const
252 {
253 if ((i2 < i1) || (i2 >= this->size())) {
254 cvm::error("Error: trying to slice a vector using incorrect boundaries.\n");
255 }
256 vector1d<T> result(i2 - i1);
257 size_t i;
258 for (i = 0; i < (i2 - i1); i++) {
259 result[i] = (*this)[i1+i];
260 }
261 return result;
262 }
263
265 inline void sliceassign(size_t const i1, size_t const i2,
266 vector1d<T> const &v)
267 {
268 if ((i2 < i1) || (i2 >= this->size())) {
269 cvm::error("Error: trying to slice a vector using incorrect boundaries.\n");
270 }
271 size_t i;
272 for (i = 0; i < (i2 - i1); i++) {
273 (*this)[i1+i] = v[i];
274 }
275 }
276
278
279 inline size_t output_width(size_t real_width) const
280 {
281 return real_width*(this->size()) + 3*(this->size()-1) + 4;
282 }
283
284 inline friend std::istream & operator >> (std::istream &is,
286 {
287 if (v.size() == 0) return is;
288 std::streampos const start_pos = is.tellg();
289 char sep;
290 if ( !(is >> sep) || !(sep == '(') ) {
291 is.clear();
292 is.seekg(start_pos, std::ios::beg);
293 is.setstate(std::ios::failbit);
294 return is;
295 }
296 size_t count = 0;
297 while ( (is >> v[count]) &&
298 (count < (v.size()-1) ? ((is >> sep) && (sep == ',')) : true) ) {
299 if (++count == v.size()) break;
300 }
301 if (count < v.size()) {
302 is.clear();
303 is.seekg(start_pos, std::ios::beg);
304 is.setstate(std::ios::failbit);
305 }
306 return is;
307 }
308
309 inline friend std::ostream & operator << (std::ostream &os,
310 cvm::vector1d<T> const &v)
311 {
312 std::streamsize const w = os.width();
313 std::streamsize const p = os.precision();
314
315 os.width(2);
316 os << "( ";
317 size_t i;
318 for (i = 0; i < v.size()-1; i++) {
319 os.width(w); os.precision(p);
320 os << v[i] << " , ";
321 }
322 os.width(w); os.precision(p);
323 os << v[v.size()-1] << " )";
324 return os;
325 }
326
327 inline std::string to_simple_string() const
328 {
329 if (this->size() == 0) return std::string("");
330 std::ostringstream os;
331 os.setf(std::ios::scientific, std::ios::floatfield);
332 os.precision(cvm::cv_prec);
333 os << (*this)[0];
334 size_t i;
335 for (i = 1; i < this->size(); i++) {
336 os << " " << (*this)[i];
337 }
338 return os.str();
339 }
340
341 inline int from_simple_string(std::string const &s)
342 {
343 std::stringstream stream(s);
344 size_t i = 0;
345 if (this->size()) {
346 while ((stream >> (*this)[i]) && (i < this->size())) {
347 i++;
348 }
349 if (i < this->size()) {
350 return COLVARS_ERROR;
351 }
352 } else {
353 T input;
354 while (stream >> input) {
355 if ((i % 100) == 0) {
356 data.reserve(data.size()+100);
357 }
358 data.resize(data.size()+1);
359 data[i] = input;
360 i++;
361 }
362 }
363 return COLVARS_OK;
364 }
365
366};
367
368
372template <class T> class colvarmodule::matrix2d
373{
374public:
375
376 friend class row;
377 size_t outer_length;
378 size_t inner_length;
379
380protected:
381
382 class row {
383 public:
384 T * data;
385 size_t length;
386 inline row(T * const row_data, size_t const inner_length)
387 : data(row_data), length(inner_length)
388 {}
389 inline T & operator [] (size_t const j) {
390 return *(data+j);
391 }
392 inline T const & operator [] (size_t const j) const {
393 return *(data+j);
394 }
395 inline operator vector1d<T>() const
396 {
397 return vector1d<T>(length, data);
398 }
399 inline int set(cvm::vector1d<T> const &v) const
400 {
401 if (v.size() != length) {
402 return cvm::error("Error: setting a matrix row from a vector of "
403 "incompatible size.\n", COLVARS_BUG_ERROR);
404 }
405 for (size_t i = 0; i < length; i++) data[i] = v[i];
406 return COLVARS_OK;
407 }
408 };
409
410 std::vector<T> data;
411 std::vector<row> rows;
412 std::vector<T *> pointers;
413
414public:
415
417 inline void resize(size_t const ol, size_t const il)
418 {
419 if ((ol > 0) && (il > 0)) {
420
421 if (data.size() > 0) {
422 // copy previous data
423 size_t i, j;
424 std::vector<T> new_data(ol * il);
425 for (i = 0; i < outer_length; i++) {
426 for (j = 0; j < inner_length; j++) {
427 new_data[il*i+j] = data[inner_length*i+j];
428 }
429 }
430 data.resize(ol * il);
431 // copy them back
432 data = new_data;
433 } else {
434 data.resize(ol * il);
435 }
436
437 outer_length = ol;
438 inner_length = il;
439
440 if (data.size() > 0) {
441 // rebuild rows
442 size_t i;
443 rows.clear();
444 rows.reserve(outer_length);
445 pointers.clear();
446 pointers.reserve(outer_length);
447 for (i = 0; i < outer_length; i++) {
448 rows.push_back(row(&(data[0])+inner_length*i, inner_length));
449 pointers.push_back(&(data[0])+inner_length*i);
450 }
451 }
452 } else {
453 // zero size
454 data.clear();
455 rows.clear();
456 }
457 }
458
460 inline void clear() {
461 rows.clear();
462 data.clear();
463 }
464
466 inline void reset()
467 {
468 data.assign(data.size(), T(0.0));
469 }
470
471 inline size_t size() const
472 {
473 return data.size();
474 }
475
477 inline matrix2d()
478 : outer_length(0), inner_length(0)
479 {
480 this->resize(0, 0);
481 }
482
483 inline matrix2d(size_t const ol, size_t const il)
484 : outer_length(ol), inner_length(il)
485 {
486 this->resize(outer_length, inner_length);
487 reset();
488 }
489
491 inline matrix2d(matrix2d<T> const &m)
492 : outer_length(m.outer_length), inner_length(m.inner_length)
493 {
494 // reinitialize data and rows arrays
495 this->resize(outer_length, inner_length);
496 // copy data
497 data = m.data;
498 }
499
501 inline ~matrix2d() {
502 this->clear();
503 }
504
506 inline std::vector<T> &data_array()
507 {
508 return data;
509 }
510
512 inline std::vector<T> const &data_array() const
513 {
514 return data;
515 }
516
517 inline row & operator [] (size_t const i)
518 {
519 return rows[i];
520 }
521 inline row const & operator [] (size_t const i) const
522 {
523 return rows[i];
524 }
525
528 {
529 if ((outer_length != m.outer_length) || (inner_length != m.inner_length)){
530 this->clear();
531 outer_length = m.outer_length;
532 inner_length = m.inner_length;
533 this->resize(outer_length, inner_length);
534 }
535 data = m.data;
536 return *this;
537 }
538
540 inline T ** c_array() {
541 if (rows.size() > 0) {
542 return &(pointers[0]);
543 } else {
544 return NULL;
545 }
546 }
547
548 inline static void check_sizes(matrix2d<T> const &m1, matrix2d<T> const &m2)
549 {
550 if ((m1.outer_length != m2.outer_length) ||
551 (m1.inner_length != m2.inner_length)) {
552 cvm::error("Error: trying to perform an operation between "
553 "matrices of different sizes, "+
554 cvm::to_str(m1.outer_length)+"x"+
555 cvm::to_str(m1.inner_length)+" and "+
556 cvm::to_str(m2.outer_length)+"x"+
557 cvm::to_str(m2.inner_length)+".\n");
558 }
559 }
560
561 inline void operator += (matrix2d<T> const &m)
562 {
563 check_sizes(*this, m);
564 size_t i;
565 for (i = 0; i < data.size(); i++) {
566 data[i] += m.data[i];
567 }
568 }
569
570 inline void operator -= (matrix2d<T> const &m)
571 {
572 check_sizes(*this, m);
573 size_t i;
574 for (i = 0; i < data.size(); i++) {
575 data[i] -= m.data[i];
576 }
577 }
578
579 inline void operator *= (cvm::real a)
580 {
581 size_t i;
582 for (i = 0; i < data.size(); i++) {
583 data[i] *= a;
584 }
585 }
586
587 inline void operator /= (cvm::real a)
588 {
589 size_t i;
590 for (i = 0; i < data.size(); i++) {
591 data[i] /= a;
592 }
593 }
594
595 inline friend matrix2d<T> operator + (matrix2d<T> const &m1,
596 matrix2d<T> const &m2)
597 {
598 check_sizes(m1, m2);
599 matrix2d<T> result(m1.outer_length, m1.inner_length);
600 size_t i;
601 for (i = 0; i < m1.data.size(); i++) {
602 result.data[i] = m1.data[i] + m2.data[i];
603 }
604 return result;
605 }
606
607 inline friend matrix2d<T> operator - (matrix2d<T> const &m1,
608 matrix2d<T> const &m2)
609 {
610 check_sizes(m1, m2);
611 matrix2d<T> result(m1.outer_length, m1.inner_length);
612 size_t i;
613 for (i = 0; i < m1.data.size(); i++) {
614 result.data[i] = m1.data[i] - m1.data[i];
615 }
616 return result;
617 }
618
619 inline friend matrix2d<T> operator * (matrix2d<T> const &m, cvm::real a)
620 {
621 matrix2d<T> result(m.outer_length, m.inner_length);
622 size_t i;
623 for (i = 0; i < m.data.size(); i++) {
624 result.data[i] = m.data[i] * a;
625 }
626 return result;
627 }
628
629 inline friend matrix2d<T> operator * (cvm::real a, matrix2d<T> const &m)
630 {
631 return m * a;
632 }
633
634 inline friend matrix2d<T> operator / (matrix2d<T> const &m, cvm::real a)
635 {
636 matrix2d<T> result(m.outer_length, m.inner_length);
637 size_t i;
638 for (i = 0; i < m.data.size(); i++) {
639 result.data[i] = m.data[i] * a;
640 }
641 return result;
642 }
643
645 inline friend vector1d<T> operator * (vector1d<T> const &v,
646 matrix2d<T> const &m)
647 {
648 vector1d<T> result(m.inner_length);
649 if (m.outer_length != v.size()) {
650 cvm::error("Error: trying to multiply a vector and a matrix "
651 "of incompatible sizes, "+
652 cvm::to_str(v.size()) + " and " +
653 cvm::to_str(m.outer_length)+"x"+cvm::to_str(m.inner_length) +
654 ".\n");
655 } else {
656 size_t i, k;
657 for (i = 0; i < m.inner_length; i++) {
658 for (k = 0; k < m.outer_length; k++) {
659 result[i] += m[k][i] * v[k];
660 }
661 }
662 }
663 return result;
664 }
665
667 friend std::ostream & operator << (std::ostream &os,
668 matrix2d<T> const &m)
669 {
670 std::streamsize const w = os.width();
671 std::streamsize const p = os.precision();
672
673 os.width(2);
674 os << "( ";
675 size_t i;
676 for (i = 0; i < m.outer_length; i++) {
677 os << " ( ";
678 size_t j;
679 for (j = 0; j < m.inner_length-1; j++) {
680 os.width(w);
681 os.precision(p);
682 os << m[i][j] << " , ";
683 }
684 os.width(w);
685 os.precision(p);
686 os << m[i][m.inner_length-1] << " )";
687 }
688
689 os << " )";
690 return os;
691 }
692
693 inline std::string to_simple_string() const
694 {
695 if (this->size() == 0) return std::string("");
696 std::ostringstream os;
697 os.setf(std::ios::scientific, std::ios::floatfield);
698 os.precision(cvm::cv_prec);
699 os << (*this)[0];
700 size_t i;
701 for (i = 1; i < data.size(); i++) {
702 os << " " << data[i];
703 }
704 return os.str();
705 }
706
707 inline int from_simple_string(std::string const &s)
708 {
709 std::stringstream stream(s);
710 size_t i = 0;
711 while ((i < data.size()) && (stream >> data[i])) {
712 i++;
713 }
714 if (i < data.size()) {
715 return COLVARS_ERROR;
716 }
717 return COLVARS_OK;
718 }
719
720};
721
722
725
726public:
727
728 cvm::real x, y, z;
729
730 inline rvector()
731 {
732 reset();
733 }
734
736 inline void reset()
737 {
738 set(0.0);
739 }
740
741 inline rvector(cvm::real x_i, cvm::real y_i, cvm::real z_i)
742 {
743 set(x_i, y_i, z_i);
744 }
745
746 inline rvector(cvm::vector1d<cvm::real> const &v)
747 {
748 set(v[0], v[1], v[2]);
749 }
750
751 inline rvector(cvm::real t)
752 {
753 set(t);
754 }
755
757 inline void set(cvm::real value)
758 {
759 x = y = z = value;
760 }
761
763 inline void set(cvm::real x_i, cvm::real y_i, cvm::real z_i)
764 {
765 x = x_i;
766 y = y_i;
767 z = z_i;
768 }
769
771 inline cvm::real & operator [] (int i) {
772 return (i == 0) ? x : (i == 1) ? y : (i == 2) ? z : x;
773 }
774
776 inline cvm::real operator [] (int i) const {
777 return (i == 0) ? x : (i == 1) ? y : (i == 2) ? z : x;
778 }
779
780 inline cvm::vector1d<cvm::real> const as_vector() const
781 {
782 cvm::vector1d<cvm::real> result(3);
783 result[0] = this->x;
784 result[1] = this->y;
785 result[2] = this->z;
786 return result;
787 }
788
789 inline void operator += (cvm::rvector const &v)
790 {
791 x += v.x;
792 y += v.y;
793 z += v.z;
794 }
795
796 inline void operator -= (cvm::rvector const &v)
797 {
798 x -= v.x;
799 y -= v.y;
800 z -= v.z;
801 }
802
803 inline void operator *= (cvm::real v)
804 {
805 x *= v;
806 y *= v;
807 z *= v;
808 }
809
810 inline void operator /= (cvm::real const& v)
811 {
812 x /= v;
813 y /= v;
814 z /= v;
815 }
816
817 inline cvm::real norm2() const
818 {
819 return (x*x + y*y + z*z);
820 }
821
822 inline cvm::real norm() const
823 {
824 return cvm::sqrt(this->norm2());
825 }
826
827 inline cvm::rvector unit() const
828 {
829 const cvm::real n = this->norm();
830 return (n > 0. ? cvm::rvector(x, y, z)/n : cvm::rvector(1., 0., 0.));
831 }
832
833 static inline size_t output_width(size_t real_width)
834 {
835 return 3*real_width + 10;
836 }
837
838
839 static inline cvm::rvector outer(cvm::rvector const &v1,
840 cvm::rvector const &v2)
841 {
842 return cvm::rvector( v1.y*v2.z - v2.y*v1.z,
843 -v1.x*v2.z + v2.x*v1.z,
844 v1.x*v2.y - v2.x*v1.y);
845 }
846
847 friend inline cvm::rvector operator - (cvm::rvector const &v)
848 {
849 return cvm::rvector(-v.x, -v.y, -v.z);
850 }
851
852 friend inline cvm::rvector operator + (cvm::rvector const &v1,
853 cvm::rvector const &v2)
854 {
855 return cvm::rvector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
856 }
857 friend inline cvm::rvector operator - (cvm::rvector const &v1,
858 cvm::rvector const &v2)
859 {
860 return cvm::rvector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
861 }
862
864 friend inline cvm::real operator * (cvm::rvector const &v1,
865 cvm::rvector const &v2)
866 {
867 return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
868 }
869
870 friend inline cvm::rvector operator * (cvm::real a, cvm::rvector const &v)
871 {
872 return cvm::rvector(a*v.x, a*v.y, a*v.z);
873 }
874
875 friend inline cvm::rvector operator * (cvm::rvector const &v, cvm::real a)
876 {
877 return cvm::rvector(a*v.x, a*v.y, a*v.z);
878 }
879
880 friend inline cvm::rvector operator / (cvm::rvector const &v, cvm::real a)
881 {
882 return cvm::rvector(v.x/a, v.y/a, v.z/a);
883 }
884
885 std::string to_simple_string() const;
886 int from_simple_string(std::string const &s);
887};
888
889
893
894public:
895
896 cvm::real xx, xy, xz, yx, yy, yz, zx, zy, zz;
897
899 inline rmatrix()
900 {
901 reset();
902 }
903
905 inline rmatrix(cvm::real xxi, cvm::real xyi, cvm::real xzi,
906 cvm::real yxi, cvm::real yyi, cvm::real yzi,
907 cvm::real zxi, cvm::real zyi, cvm::real zzi)
908 {
909 xx = xxi;
910 xy = xyi;
911 xz = xzi;
912 yx = yxi;
913 yy = yyi;
914 yz = yzi;
915 zx = zxi;
916 zy = zyi;
917 zz = zzi;
918 }
919
920
921 inline void reset()
922 {
923 xx = xy = xz = yx = yy = yz = zx = zy = zz = 0.0;
924 }
925
927 inline cvm::real determinant() const
928 {
929 return
930 ( xx * (yy*zz - zy*yz))
931 - (yx * (xy*zz - zy*xz))
932 + (zx * (xy*yz - yy*xz));
933 }
934
935 inline cvm::rmatrix transpose() const
936 {
937 return cvm::rmatrix(xx, yx, zx,
938 xy, yy, zy,
939 xz, yz, zz);
940 }
941
942 inline friend cvm::rvector operator * (cvm::rmatrix const &m,
943 cvm::rvector const &r)
944 {
945 return cvm::rvector(m.xx*r.x + m.xy*r.y + m.xz*r.z,
946 m.yx*r.x + m.yy*r.y + m.yz*r.z,
947 m.zx*r.x + m.zy*r.y + m.zz*r.z);
948 }
949};
950
951
952
956
957public:
958
959 cvm::real q0, q1, q2, q3;
960
962 inline quaternion(cvm::real const qv[4])
963 : q0(qv[0]), q1(qv[1]), q2(qv[2]), q3(qv[3])
964 {}
965
968 cvm::real q1i,
969 cvm::real q2i,
970 cvm::real q3i)
971 : q0(q0i), q1(q1i), q2(q2i), q3(q3i)
972 {}
973
974 inline quaternion(cvm::vector1d<cvm::real> const &v)
975 : q0(v[0]), q1(v[1]), q2(v[2]), q3(v[3])
976 {}
977
979 inline quaternion()
980 {
981 reset();
982 }
983
985 inline void reset()
986 {
987 q0 = q1 = q2 = q3 = 0.0;
988 }
989
991 static inline size_t output_width(size_t real_width)
992 {
993 return 4*real_width + 13;
994 }
995
996 std::string to_simple_string() const;
997 int from_simple_string(std::string const &s);
998
1000 friend std::ostream & operator << (std::ostream &os, cvm::quaternion const &q);
1002 friend std::istream & operator >> (std::istream &is, cvm::quaternion &q);
1003
1005 inline cvm::real & operator [] (int i) {
1006 switch (i) {
1007 case 0:
1008 return this->q0;
1009 case 1:
1010 return this->q1;
1011 case 2:
1012 return this->q2;
1013 case 3:
1014 return this->q3;
1015 default:
1016 cvm::error("Error: incorrect quaternion component.\n");
1017 return q0;
1018 }
1019 }
1020
1022 inline cvm::real operator [] (int i) const {
1023 switch (i) {
1024 case 0:
1025 return this->q0;
1026 case 1:
1027 return this->q1;
1028 case 2:
1029 return this->q2;
1030 case 3:
1031 return this->q3;
1032 default:
1033 cvm::error("Error: trying to access a quaternion "
1034 "component which is not between 0 and 3.\n");
1035 return 0.0;
1036 }
1037 }
1038
1039 inline cvm::vector1d<cvm::real> const as_vector() const
1040 {
1041 cvm::vector1d<cvm::real> result(4);
1042 result[0] = q0;
1043 result[1] = q1;
1044 result[2] = q2;
1045 result[3] = q3;
1046 return result;
1047 }
1048
1050 inline cvm::real norm2() const
1051 {
1052 return q0*q0 + q1*q1 + q2*q2 + q3*q3;
1053 }
1054
1056 inline cvm::real norm() const
1057 {
1058 return cvm::sqrt(this->norm2());
1059 }
1060
1063 {
1064 return cvm::quaternion(q0, -q1, -q2, -q3);
1065 }
1066
1067 inline void operator *= (cvm::real a)
1068 {
1069 q0 *= a; q1 *= a; q2 *= a; q3 *= a;
1070 }
1071
1072 inline void operator /= (cvm::real a)
1073 {
1074 q0 /= a; q1 /= a; q2 /= a; q3 /= a;
1075 }
1076
1077 inline void set_positive()
1078 {
1079 if (q0 > 0.0) return;
1080 q0 = -q0;
1081 q1 = -q1;
1082 q2 = -q2;
1083 q3 = -q3;
1084 }
1085
1086 inline void operator += (cvm::quaternion const &h)
1087 {
1088 q0+=h.q0; q1+=h.q1; q2+=h.q2; q3+=h.q3;
1089 }
1090 inline void operator -= (cvm::quaternion const &h)
1091 {
1092 q0-=h.q0; q1-=h.q1; q2-=h.q2; q3-=h.q3;
1093 }
1094
1097 {
1098 return cvm::rvector(q1, q2, q3);
1099 }
1100
1101
1102 friend inline cvm::quaternion operator + (cvm::quaternion const &h,
1103 cvm::quaternion const &q)
1104 {
1105 return cvm::quaternion(h.q0+q.q0, h.q1+q.q1, h.q2+q.q2, h.q3+q.q3);
1106 }
1107
1108 friend inline cvm::quaternion operator - (cvm::quaternion const &h,
1109 cvm::quaternion const &q)
1110 {
1111 return cvm::quaternion(h.q0-q.q0, h.q1-q.q1, h.q2-q.q2, h.q3-q.q3);
1112 }
1113
1117 cvm::quaternion const &q)
1118 {
1119 return cvm::quaternion(h.q0*q.q0 - h.q1*q.q1 - h.q2*q.q2 - h.q3*q.q3,
1120 h.q0*q.q1 + h.q1*q.q0 + h.q2*q.q3 - h.q3*q.q2,
1121 h.q0*q.q2 + h.q2*q.q0 + h.q3*q.q1 - h.q1*q.q3,
1122 h.q0*q.q3 + h.q3*q.q0 + h.q1*q.q2 - h.q2*q.q1);
1123 }
1124
1125 friend inline cvm::quaternion operator * (cvm::real c,
1126 cvm::quaternion const &q)
1127 {
1128 return cvm::quaternion(c*q.q0, c*q.q1, c*q.q2, c*q.q3);
1129 }
1130 friend inline cvm::quaternion operator * (cvm::quaternion const &q,
1131 cvm::real c)
1132 {
1133 return cvm::quaternion(q.q0*c, q.q1*c, q.q2*c, q.q3*c);
1134 }
1135 friend inline cvm::quaternion operator / (cvm::quaternion const &q,
1136 cvm::real c)
1137 {
1138 return cvm::quaternion(q.q0/c, q.q1/c, q.q2/c, q.q3/c);
1139 }
1140
1141
1144 inline cvm::rvector rotate(cvm::rvector const &v) const
1145 {
1146 return ( (*this) * cvm::quaternion(0.0, v.x, v.y, v.z) *
1147 this->conjugate() ).get_vector();
1148 }
1149
1153 {
1154 cvm::rvector const vq_rot = this->rotate(Q2.get_vector());
1155 return cvm::quaternion(Q2.q0, vq_rot.x, vq_rot.y, vq_rot.z);
1156 }
1157
1160 {
1161 cvm::rmatrix R;
1162
1163 R.xx = q0*q0 + q1*q1 - q2*q2 - q3*q3;
1164 R.yy = q0*q0 - q1*q1 + q2*q2 - q3*q3;
1165 R.zz = q0*q0 - q1*q1 - q2*q2 + q3*q3;
1166
1167 R.xy = 2.0 * (q1*q2 - q0*q3);
1168 R.xz = 2.0 * (q0*q2 + q1*q3);
1169
1170 R.yx = 2.0 * (q0*q3 + q1*q2);
1171 R.yz = 2.0 * (q2*q3 - q0*q1);
1172
1173 R.zx = 2.0 * (q1*q3 - q0*q2);
1174 R.zy = 2.0 * (q0*q1 + q2*q3);
1175
1176 return R;
1177 }
1178
1210 inline std::array<cvm::real, 4> derivative_element_wise_product_sum(const cvm::real (&C)[3][3]) const {
1211 return std::array<cvm::real, 4>{{
1212 2.0 * ( q0 * C[0][0] - q3 * C[0][1] + q2 * C[0][2] +
1213 q3 * C[1][0] + q0 * C[1][1] - q1 * C[1][2] +
1214 -q2 * C[2][0] + q1 * C[2][1] + q0 * C[2][2]),
1215 2.0 * ( q1 * C[0][0] + q2 * C[0][1] + q3 * C[0][2] +
1216 q2 * C[1][0] - q1 * C[1][1] - q0 * C[1][2] +
1217 q3 * C[2][0] + q0 * C[2][1] - q1 * C[2][2]),
1218 2.0 * (-q2 * C[0][0] + q1 * C[0][1] + q0 * C[0][2] +
1219 q1 * C[1][0] + q2 * C[1][1] + q3 * C[1][2] +
1220 -q0 * C[2][0] + q3 * C[2][1] - q2 * C[2][2]),
1221 2.0 * (-q3 * C[0][0] - q0 * C[0][1] + q1 * C[0][2] +
1222 q0 * C[1][0] - q3 * C[1][1] + q2 * C[1][2] +
1223 q1 * C[2][0] + q2 * C[2][1] + q3 * C[2][2])
1224 }};
1225 }
1226
1229 inline cvm::real cosine(cvm::quaternion const &q) const
1230 {
1231 cvm::real const iprod = this->inner(q);
1232 return 2.0*iprod*iprod - 1.0;
1233 }
1234
1238 inline cvm::real dist2(cvm::quaternion const &Q2) const
1239 {
1240 cvm::real const cos_omega = this->q0*Q2.q0 + this->q1*Q2.q1 +
1241 this->q2*Q2.q2 + this->q3*Q2.q3;
1242
1243 cvm::real const omega = cvm::acos( (cos_omega > 1.0) ? 1.0 :
1244 ( (cos_omega < -1.0) ? -1.0 : cos_omega) );
1245
1246 // get the minimum distance: x and -x are the same quaternion
1247 if (cos_omega > 0.0)
1248 return omega * omega;
1249 else
1250 return (PI-omega) * (PI-omega);
1251 }
1252
1256 {
1257 cvm::real const cos_omega = this->q0*Q2.q0 + this->q1*Q2.q1 + this->q2*Q2.q2 + this->q3*Q2.q3;
1258 cvm::real const omega = cvm::acos( (cos_omega > 1.0) ? 1.0 :
1259 ( (cos_omega < -1.0) ? -1.0 : cos_omega) );
1260 cvm::real const sin_omega = cvm::sin(omega);
1261
1262 if (cvm::fabs(sin_omega) < 1.0E-14) {
1263 // return a null 4d vector
1264 return cvm::quaternion(0.0, 0.0, 0.0, 0.0);
1265 }
1266
1267 cvm::quaternion const
1268 grad1((-1.0)*sin_omega*Q2.q0 + cos_omega*(this->q0-cos_omega*Q2.q0)/sin_omega,
1269 (-1.0)*sin_omega*Q2.q1 + cos_omega*(this->q1-cos_omega*Q2.q1)/sin_omega,
1270 (-1.0)*sin_omega*Q2.q2 + cos_omega*(this->q2-cos_omega*Q2.q2)/sin_omega,
1271 (-1.0)*sin_omega*Q2.q3 + cos_omega*(this->q3-cos_omega*Q2.q3)/sin_omega);
1272
1273 if (cos_omega > 0.0) {
1274 return 2.0*omega*grad1;
1275 } else {
1276 return -2.0*(PI-omega)*grad1;
1277 }
1278 }
1279
1282 inline void match(cvm::quaternion &Q2) const
1283 {
1284 cvm::real const cos_omega = this->q0*Q2.q0 + this->q1*Q2.q1 +
1285 this->q2*Q2.q2 + this->q3*Q2.q3;
1286 if (cos_omega < 0.0) Q2 *= -1.0;
1287 }
1288
1291 inline cvm::real inner(cvm::quaternion const &Q2) const
1292 {
1293 cvm::real const prod = this->q0*Q2.q0 + this->q1*Q2.q1 +
1294 this->q2*Q2.q2 + this->q3*Q2.q3;
1295 return prod;
1296 }
1297
1298
1299};
1300
1301#ifndef COLVARS_LAMMPS
1302namespace NR {
1303int diagonalize_matrix(cvm::real m[4][4],
1304 cvm::real eigval[4],
1305 cvm::real eigvec[4][4]);
1306}
1307#endif
1308
1309
1313{
1314private:
1317
1320
1323
1326
1329
1330public:
1333
1335 cvm::quaternion q{1.0, 0.0, 0.0, 0.0};
1336
1337 friend struct rotation_derivative;
1338
1345 void debug_gradients(
1346 cvm::rotation &rot,
1347 const std::vector<cvm::real> &pos1,
1348 const std::vector<cvm::real> &pos2,
1349 const size_t num_atoms_pos1,
1350 const size_t num_atoms_pos2);
1351
1362 void calc_optimal_rotation(std::vector<atom_pos> const &pos1,
1363 std::vector<atom_pos> const &pos2);
1364 void calc_optimal_rotation_soa(
1365 std::vector<cvm::real> const &pos1,
1366 std::vector<cvm::real> const &pos2,
1367 const size_t num_atoms_pos1,
1368 const size_t num_atoms_pos2);
1369
1371 int init();
1372
1374 rotation();
1375
1377 rotation(cvm::quaternion const &qi);
1378
1380 rotation(cvm::real angle, cvm::rvector const &axis);
1381
1383 ~rotation();
1384
1386 inline cvm::rvector rotate(cvm::rvector const &v) const
1387 {
1388 return q.rotate(v);
1389 }
1390
1392 inline cvm::rotation inverse() const
1393 {
1394 return cvm::rotation(this->q.conjugate());
1395 }
1396
1398 inline cvm::rmatrix matrix() const
1399 {
1400 return q.rotation_matrix();
1401 }
1402
1405 inline cvm::real spin_angle(cvm::rvector const &axis) const
1406 {
1407 cvm::rvector const q_vec = q.get_vector();
1408 cvm::real alpha = (180.0/PI) * 2.0 * cvm::atan2(axis * q_vec, q.q0);
1409 while (alpha > 180.0) alpha -= 360;
1410 while (alpha < -180.0) alpha += 360;
1411 return alpha;
1412 }
1413
1417 {
1418 cvm::rvector const q_vec = q.get_vector();
1419 cvm::real const iprod = axis * q_vec;
1420
1421 if (q.q0 != 0.0) {
1422
1423 cvm::real const dspindx =
1424 (180.0/PI) * 2.0 * (1.0 / (1.0 + (iprod*iprod)/(q.q0*q.q0)));
1425
1426 return cvm::quaternion( dspindx * (iprod * (-1.0) / (q.q0*q.q0)),
1427 dspindx * ((1.0/q.q0) * axis.x),
1428 dspindx * ((1.0/q.q0) * axis.y),
1429 dspindx * ((1.0/q.q0) * axis.z));
1430 } else {
1431 // (1/(1+x^2)) ~ (1/x)^2
1432 // The documentation of spinAngle discourages its use when q_vec and
1433 // axis are not close
1434 return cvm::quaternion((180.0/PI) * 2.0 * ((-1.0)/iprod), 0.0, 0.0, 0.0);
1435 }
1436 }
1437
1440 inline cvm::real cos_theta(cvm::rvector const &axis) const
1441 {
1442 cvm::rvector const q_vec = q.get_vector();
1443 cvm::real const alpha =
1444 (180.0/PI) * 2.0 * cvm::atan2(axis * q_vec, q.q0);
1445
1446 cvm::real const cos_spin_2 = cvm::cos(alpha * (PI/180.0) * 0.5);
1447 cvm::real const cos_theta_2 = ( (cos_spin_2 != 0.0) ?
1448 (q.q0 / cos_spin_2) :
1449 (0.0) );
1450 // cos(2t) = 2*cos(t)^2 - 1
1451 return 2.0 * (cos_theta_2*cos_theta_2) - 1.0;
1452 }
1453
1456 {
1457 cvm::rvector const q_vec = q.get_vector();
1458 cvm::real const iprod = axis * q_vec;
1459
1460 cvm::real const cos_spin_2 = cvm::cos(cvm::atan2(iprod, q.q0));
1461
1462 if (q.q0 != 0.0) {
1463
1464 cvm::real const d_cos_theta_dq0 =
1465 (4.0 * q.q0 / (cos_spin_2*cos_spin_2)) *
1466 (1.0 - (iprod*iprod)/(q.q0*q.q0) / (1.0 + (iprod*iprod)/(q.q0*q.q0)));
1467
1468 cvm::real const d_cos_theta_dqn =
1469 (4.0 * q.q0 / (cos_spin_2*cos_spin_2) *
1470 (iprod/q.q0) / (1.0 + (iprod*iprod)/(q.q0*q.q0)));
1471
1472 return cvm::quaternion(d_cos_theta_dq0,
1473 d_cos_theta_dqn * axis.x,
1474 d_cos_theta_dqn * axis.y,
1475 d_cos_theta_dqn * axis.z);
1476 } else {
1477
1478 cvm::real const d_cos_theta_dqn =
1479 (4.0 / (cos_spin_2*cos_spin_2 * iprod));
1480
1481 return cvm::quaternion(0.0,
1482 d_cos_theta_dqn * axis.x,
1483 d_cos_theta_dqn * axis.y,
1484 d_cos_theta_dqn * axis.z);
1485 }
1486 }
1487
1492
1493protected:
1494
1499
1501 void build_correlation_matrix(std::vector<cvm::atom_pos> const &pos1,
1502 std::vector<cvm::atom_pos> const &pos2);
1503
1506
1509
1511 void *jacobi;
1512};
1513
1514
1515#endif
Definition: colvartypes.h:382
Arbitrary size array (two dimensions) suitable for linear algebra operations (i.e....
Definition: colvartypes.h:373
matrix2d(matrix2d< T > const &m)
Copy constructor.
Definition: colvartypes.h:491
T ** c_array()
Return the 2-d C array.
Definition: colvartypes.h:540
void clear()
Deallocation routine.
Definition: colvartypes.h:460
~matrix2d()
Destructor.
Definition: colvartypes.h:501
std::vector< T > const & data_array() const
Return a reference to the data.
Definition: colvartypes.h:512
matrix2d< T > & operator=(matrix2d< T > const &m)
Assignment.
Definition: colvartypes.h:527
matrix2d()
Default constructor.
Definition: colvartypes.h:477
std::vector< T > & data_array()
Return a reference to the data.
Definition: colvartypes.h:506
void resize(size_t const ol, size_t const il)
Allocation routine, used by all constructors.
Definition: colvartypes.h:417
friend std::ostream & operator<<(std::ostream &os, matrix2d< T > const &m)
Formatted output.
Definition: colvartypes.h:667
void reset()
Set all elements to zero.
Definition: colvartypes.h:466
1-dimensional vector of real numbers with four components and a quaternion algebra
Definition: colvartypes.h:955
cvm::real & operator[](int i)
Access the quaternion as a 4-d array (return a reference)
Definition: colvartypes.h:1005
cvm::real cosine(cvm::quaternion const &q) const
Return the cosine between the orientation frame associated to this quaternion and another.
Definition: colvartypes.h:1229
cvm::rvector get_vector() const
Return the vector component.
Definition: colvartypes.h:1096
friend std::istream & operator>>(std::istream &is, cvm::quaternion &q)
Formatted input operator.
Definition: colvartypes.cpp:123
cvm::quaternion rotate(cvm::quaternion const &Q2) const
Rotate Q2 through this quaternion (put it in the rotated reference frame)
Definition: colvartypes.h:1152
cvm::real norm() const
Norm of the quaternion.
Definition: colvartypes.h:1056
quaternion(cvm::real const qv[4])
Constructor component by component.
Definition: colvartypes.h:962
std::array< cvm::real, 4 > derivative_element_wise_product_sum(const cvm::real(&C)[3][3]) const
Calculate the sums of element-wise products of a given matrix with respect to dR/dq0,...
Definition: colvartypes.h:1210
quaternion()
Default constructor.
Definition: colvartypes.h:979
void reset()
Set all components to zero (null quaternion)
Definition: colvartypes.h:985
friend std::ostream & operator<<(std::ostream &os, cvm::quaternion const &q)
Formatted output operator.
Definition: colvartypes.cpp:104
cvm::rvector rotate(cvm::rvector const &v) const
Rotate v through this quaternion (put it in the rotated reference frame)
Definition: colvartypes.h:1144
cvm::quaternion dist2_grad(cvm::quaternion const &Q2) const
Definition: colvartypes.h:1255
void match(cvm::quaternion &Q2) const
Choose the closest between Q2 and -Q2 and save it back. Not required for dist2() and dist2_grad()
Definition: colvartypes.h:1282
static size_t output_width(size_t real_width)
Tell the number of characters required to print a quaternion, given that of a real number.
Definition: colvartypes.h:991
cvm::real norm2() const
Square norm of the quaternion.
Definition: colvartypes.h:1050
cvm::rmatrix rotation_matrix() const
Return the 3x3 matrix associated to this quaternion.
Definition: colvartypes.h:1159
cvm::quaternion conjugate() const
Return the conjugate quaternion.
Definition: colvartypes.h:1062
cvm::real inner(cvm::quaternion const &Q2) const
Inner product (as a 4-d vector) with Q2; requires match() if the largest overlap is looked for.
Definition: colvartypes.h:1291
quaternion(cvm::real q0i, cvm::real q1i, cvm::real q2i, cvm::real q3i)
Constructor component by component.
Definition: colvartypes.h:967
friend cvm::quaternion operator*(cvm::quaternion const &h, cvm::quaternion const &q)
Provides the quaternion product. NOTE: for the inner product use: h.inner (q);
Definition: colvartypes.h:1116
cvm::real dist2(cvm::quaternion const &Q2) const
Square distance from another quaternion on the 4-dimensional unit sphere: returns the square of the a...
Definition: colvartypes.h:1238
2-dimensional array of real numbers with three components along each dimension (works with colvarmodu...
Definition: colvartypes.h:892
rmatrix(cvm::real xxi, cvm::real xyi, cvm::real xzi, cvm::real yxi, cvm::real yyi, cvm::real yzi, cvm::real zxi, cvm::real zyi, cvm::real zzi)
Constructor component by component.
Definition: colvartypes.h:905
cvm::real determinant() const
Return the determinant.
Definition: colvartypes.h:927
rmatrix()
Default constructor.
Definition: colvartypes.h:899
A rotation between two sets of coordinates (for the moment a wrapper for colvarmodule::quaternion)
Definition: colvartypes.h:1313
~rotation()
Destructor.
Definition: colvartypes.cpp:198
cvm::rmatrix C
Correlation matrix C (3, 3)
Definition: colvartypes.h:1316
rotation()
Default constructor.
Definition: colvartypes.cpp:160
cvm::real cos_theta(cvm::rvector const &axis) const
Return the projection of the orientation vector onto a predefined axis.
Definition: colvartypes.h:1440
cvm::real S_eigval[4]
Eigenvalues of S.
Definition: colvartypes.h:1322
cvm::real S_backup[4][4]
Used for debugging gradients.
Definition: colvartypes.h:1328
cvm::rvector rotate(cvm::rvector const &v) const
Return the rotated vector.
Definition: colvartypes.h:1386
int init()
Initialize member data.
Definition: colvartypes.cpp:151
cvm::real S[4][4]
Overlap matrix S (4, 4)
Definition: colvartypes.h:1319
cvm::quaternion dspin_angle_dq(cvm::rvector const &axis) const
Return the derivative of the spin angle with respect to the quaternion.
Definition: colvartypes.h:1416
cvm::quaternion dcos_theta_dq(cvm::rvector const &axis) const
Return the derivative of the tilt wrt the quaternion.
Definition: colvartypes.h:1455
cvm::real spin_angle(cvm::rvector const &axis) const
Return the spin angle (in degrees) with respect to the provided axis (which MUST be normalized)
Definition: colvartypes.h:1405
cvm::real S_eigvec[4][4]
Eigenvectors of S.
Definition: colvartypes.h:1325
void calc_optimal_rotation(std::vector< atom_pos > const &pos1, std::vector< atom_pos > const &pos2)
Calculate the optimal rotation and store the corresponding eigenvalue and eigenvector in the argument...
Definition: colvartypes.cpp:379
static cvm::real crossing_threshold
Threshold for the eigenvalue crossing test.
Definition: colvartypes.h:1491
cvm::quaternion q_old
Previous value of the rotation (used to warn the user when the structure changes too much,...
Definition: colvartypes.h:1498
static bool monitor_crossings
Whether to test for eigenvalue crossing.
Definition: colvartypes.h:1489
bool b_debug_gradients
Perform gradient tests.
Definition: colvartypes.h:1332
void build_correlation_matrix(std::vector< cvm::atom_pos > const &pos1, std::vector< cvm::atom_pos > const &pos2)
Build the correlation matrix C (used by calc_optimal_rotation())
Definition: colvartypes.cpp:209
cvm::rmatrix matrix() const
Return the associated 3x3 matrix.
Definition: colvartypes.h:1398
void * jacobi
Pointer to instance of Jacobi solver.
Definition: colvartypes.h:1511
void compute_overlap_matrix()
Compute the overlap matrix S (used by calc_optimal_rotation())
Definition: colvartypes.cpp:229
void debug_gradients(cvm::rotation &rot, const std::vector< cvm::real > &pos1, const std::vector< cvm::real > &pos2, const size_t num_atoms_pos1, const size_t num_atoms_pos2)
Function for debugging gradients.
Definition: colvartypes.cpp:291
void calc_optimal_rotation_impl()
Actual implementation of calc_optimal_rotation (and called by it)
Definition: colvartypes.cpp:429
cvm::rotation inverse() const
Return the inverse of this rotation.
Definition: colvartypes.h:1392
cvm::quaternion q
The rotation itself (implemented as a quaternion)
Definition: colvartypes.h:1335
vector of real numbers with three components
Definition: colvartypes.h:724
cvm::real & operator[](int i)
Access cartesian components by index.
Definition: colvartypes.h:771
void set(cvm::real x_i, cvm::real y_i, cvm::real z_i)
Assign all components.
Definition: colvartypes.h:763
void reset()
Set all components to zero.
Definition: colvartypes.h:736
void set(cvm::real value)
Set all components to a scalar.
Definition: colvartypes.h:757
friend cvm::real operator*(cvm::rvector const &v1, cvm::rvector const &v2)
Inner (dot) product.
Definition: colvartypes.h:864
Arbitrary size array (one dimensions) suitable for linear algebra operations (i.e....
Definition: colvartypes.h:34
void reset()
Set all elements to zero.
Definition: colvartypes.h:93
size_t output_width(size_t real_width) const
Formatted output.
Definition: colvartypes.h:279
cvm::real norm2() const
Squared norm.
Definition: colvartypes.h:225
void sliceassign(size_t const i1, size_t const i2, vector1d< T > const &v)
Assign a vector to a slice of this vector.
Definition: colvartypes.h:265
std::vector< T > & data_array()
Return a reference to the data.
Definition: colvartypes.h:76
vector1d & operator=(const vector1d &)=default
Explicit Copy assignement.
vector1d(const vector1d &)=default
Explicit Copy constructor.
vector1d(size_t const n, T const *t)
Constructor from C array.
Definition: colvartypes.h:49
vector1d(size_t const n=0)
Default constructor.
Definition: colvartypes.h:42
T * c_array()
Return a pointer to the data location.
Definition: colvartypes.h:66
vector1d< T > const slice(size_t const i1, size_t const i2) const
Slicing.
Definition: colvartypes.h:251
std::vector< T > const & data_array() const
Return a reference to the data.
Definition: colvartypes.h:82
double real
Defining an abstract real number allows to switch precision.
Definition: colvarmodule.h:139
static real cos(real const &x)
Reimplemented to work around MS compiler issues.
Definition: colvarmodule.h:189
static int error(std::string const &message, int code=-1)
Print a message to the main log and set global error code.
Definition: colvarmodule.cpp:2096
static real atan2(real const &x, real const &y)
Reimplemented to work around MS compiler issues.
Definition: colvarmodule.h:234
static size_t const cv_prec
Number of digits to represent a collective variables value(s)
Definition: colvarmodule.h:744
static real sqrt(real const &x)
Reimplemented to work around MS compiler issues.
Definition: colvarmodule.h:177
static real acos(real const &x)
Reimplemented to work around compiler issues; return hard-coded values for boundary conditions.
Definition: colvarmodule.h:218
static real fabs(real const &x)
Reimplemented to work around MS compiler issues.
Definition: colvarmodule.h:171
static real sin(real const &x)
Reimplemented to work around MS compiler issues.
Definition: colvarmodule.h:183
static std::string to_str(char const *s)
Convert to string for output purposes.
Definition: colvarmodule.cpp:2446
Collective variables main module.
Helper class for calculating the derivative of rotation.
Definition: colvar_rotation_derivative.h:41