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