Collective Variables Module - Developer Documentation
colvarvalue.h
1 // -*- c++ -*-
2 
3 #ifndef COLVARVALUE_H
4 #define COLVARVALUE_H
5 
6 #include "colvarmodule.h"
7 #include "colvartypes.h"
8 
9 
32 
33 
34 class colvarvalue {
35 
36 public:
37 
43  enum Type {
62  };
63 
66 
69 
72 
75 
78 
81  std::vector<Type> elem_types;
82 
85  std::vector<int> elem_indices;
86 
89  std::vector<int> elem_sizes;
90 
92  static inline bool type_checking()
93  {
94  return true;
95  }
96 
98  static std::string const type_desc(Type t);
99 
101  static std::string const type_keyword(Type t);
102 
104  static size_t num_df(Type t);
105 
107  static size_t num_dimensions(Type t);
108 
110  size_t size() const;
111 
114  inline colvarvalue()
115  : value_type(type_scalar), real_value(0.0)
116  {}
117 
119  inline colvarvalue(Type const &vti)
120  : value_type(vti)
121  {
122  reset();
123  }
124 
126  inline colvarvalue(cvm::real const &x)
127  : value_type(type_scalar), real_value(x)
128  {}
129 
133  inline colvarvalue(cvm::rvector const &v, Type vti = type_3vector)
134  : value_type(vti), rvector_value(v)
135  {}
136 
139  : value_type(vti), quaternion_value(q)
140  {}
141 
144 
146  colvarvalue(colvarvalue const &x);
147 
148 
150  void reset();
151 
156  void apply_constraints();
157 
159  inline Type type() const
160  {
161  return value_type;
162  }
163 
165  void type(Type const &vti);
166 
168  void type(colvarvalue const &x);
169 
172  void is_derivative();
173 
175  cvm::real norm2() const;
176 
178  inline cvm::real norm() const
179  {
180  return std::sqrt(this->norm2());
181  }
182 
184  cvm::real dist2(colvarvalue const &x2) const;
185 
187  colvarvalue dist2_grad(colvarvalue const &x2) const;
188 
191  static colvarvalue const interpolate(colvarvalue const &x1,
192  colvarvalue const &x2,
193  cvm::real const lambda = 0.5);
194 
196  colvarvalue & operator = (colvarvalue const &x);
197 
198  void operator += (colvarvalue const &x);
199  void operator -= (colvarvalue const &x);
200  void operator *= (cvm::real const &a);
201  void operator /= (cvm::real const &a);
202 
203  // Binary operators (return values)
204  friend colvarvalue operator + (colvarvalue const &x1, colvarvalue const &x2);
205  friend colvarvalue operator - (colvarvalue const &x1, colvarvalue const &x2);
206  friend colvarvalue operator * (colvarvalue const &x, cvm::real const &a);
207  friend colvarvalue operator * (cvm::real const &a, colvarvalue const &x);
208  friend colvarvalue operator / (colvarvalue const &x, cvm::real const &a);
209 
211  friend cvm::real operator * (colvarvalue const &x1, colvarvalue const &x2);
212 
213  // Cast to scalar
214  inline operator cvm::real() const
215  {
216  if (value_type != type_scalar) {
217  cvm::error("Error: trying to use a variable of type \""+
218  type_desc(value_type)+"\" as one of type \""+
219  type_desc(type_scalar)+"\".\n");
220  }
221  return real_value;
222  }
223 
224  // Cast to 3-vector
225  inline operator cvm::rvector() const
226  {
227  if ((value_type != type_3vector) &&
228  (value_type != type_unit3vector) &&
229  (value_type != type_unit3vectorderiv)) {
230  cvm::error("Error: trying to use a variable of type \""+
231  type_desc(value_type)+"\" as one of type \""+
232  type_desc(type_3vector)+"\".\n");
233  }
234  return rvector_value;
235  }
236 
237  // Cast to quaternion
238  inline operator cvm::quaternion() const
239  {
240  if ((value_type != type_quaternion) &&
241  (value_type != type_quaternionderiv)) {
242  cvm::error("Error: trying to use a variable of type \""+
243  type_desc(value_type)+"\" as one of type \""+
244  type_desc(type_quaternion)+"\".\n");
245  }
246  return quaternion_value;
247  }
248 
249  // Create a n-dimensional vector from one of the basic types, or return the existing vector
250  cvm::vector1d<cvm::real> const as_vector() const;
251 
252 
254  inline bool is_scalar() const
255  {
256  return (value_type == type_scalar);
257  }
258 
259 
263  void add_elem(colvarvalue const &x);
264 
266  colvarvalue const get_elem(int const i_begin, int const i_end, Type const vt) const;
267 
269  void set_elem(int const i_begin, int const i_end, colvarvalue const &x);
270 
272  void set_random();
273 
275  colvarvalue const get_elem(int const icv) const;
276 
278  void set_elem(int const icv, colvarvalue const &x);
279 
281  cvm::real operator [] (int const i) const;
282 
284  cvm::real & operator [] (int const i);
285 
287  static int check_types(colvarvalue const &x1, colvarvalue const &x2);
288 
290  static int check_types_assign(Type const &vt1, Type const &vt2);
291 
293  void undef_op() const;
294 
295 
297  friend std::ostream & operator << (std::ostream &os, colvarvalue const &q);
298 
300  friend std::istream & operator >> (std::istream &is, colvarvalue &q);
301 
305  size_t output_width(size_t const &real_width) const;
306 
308  std::string to_simple_string() const;
309 
311  int from_simple_string(std::string const &s);
312 
313 
314  // optimized routines for operations on arrays of colvar values;
315  // xv and result are assumed to have the same number of elements
316 
319  static void inner_opt(colvarvalue const &x,
320  std::vector<colvarvalue>::iterator &xv,
321  std::vector<colvarvalue>::iterator const &xv_end,
322  std::vector<cvm::real>::iterator &result);
323 
326  static void inner_opt(colvarvalue const &x,
327  std::list<colvarvalue>::iterator &xv,
328  std::list<colvarvalue>::iterator const &xv_end,
329  std::vector<cvm::real>::iterator &result);
330 
334  static void p2leg_opt(colvarvalue const &x,
335  std::vector<colvarvalue>::iterator &xv,
336  std::vector<colvarvalue>::iterator const &xv_end,
337  std::vector<cvm::real>::iterator &result);
338 
341  static void p2leg_opt(colvarvalue const &x,
342  std::list<colvarvalue>::iterator &xv,
343  std::list<colvarvalue>::iterator const &xv_end,
344  std::vector<cvm::real>::iterator &result);
345 
346 };
347 
348 
349 inline size_t colvarvalue::size() const
350 {
351  switch (value_type) {
353  default:
354  return 0; break;
356  return 1; break;
360  return 3; break;
363  return 4; break;
365  return vector1d_value.size(); break;
366  }
367 }
368 
369 
370 inline cvm::real colvarvalue::operator [] (int const i) const
371 {
372  switch (value_type) {
374  default:
375  cvm::error("Error: trying to access a colvar value "
376  "that is not initialized.\n", BUG_ERROR);
377  return 0.0; break;
379  return real_value; break;
383  return rvector_value[i]; break;
386  return quaternion_value[i]; break;
388  return vector1d_value[i]; break;
389  }
390 }
391 
392 
394 {
395  switch (value_type) {
397  default:
398  cvm::error("Error: trying to access a colvar value "
399  "that is not initialized.\n", BUG_ERROR);
400  return real_value; break;
402  return real_value; break;
406  return rvector_value[i]; break;
409  return quaternion_value[i]; break;
411  return vector1d_value[i]; break;
412  }
413 }
414 
415 
417  colvarvalue const &x2)
418 {
420  return COLVARS_OK;
421  }
422 
423  if (x1.type() != x2.type()) {
424  if (((x1.type() == type_unit3vector) &&
425  (x2.type() == type_unit3vectorderiv)) ||
426  ((x2.type() == type_unit3vector) &&
427  (x1.type() == type_unit3vectorderiv)) ||
428  ((x1.type() == type_quaternion) &&
429  (x2.type() == type_quaternionderiv)) ||
430  ((x2.type() == type_quaternion) &&
431  (x1.type() == type_quaternionderiv))) {
432  return COLVARS_OK;
433  } else {
434  cvm::error("Trying to perform an operation between two colvar "
435  "values with different types, \""+
437  "\" and \""+
439  "\".\n");
440  return COLVARS_ERROR;
441  }
442  }
443 
444  if (x1.type() == type_vector) {
445  if (x1.vector1d_value.size() != x2.vector1d_value.size()) {
446  cvm::error("Trying to perform an operation between two vector colvar "
447  "values with different sizes, "+
448  cvm::to_str(x1.vector1d_value.size())+
449  " and "+
450  cvm::to_str(x2.vector1d_value.size())+
451  ".\n");
452  return COLVARS_ERROR;
453  }
454  }
455  return COLVARS_OK;
456 }
457 
458 
460  colvarvalue::Type const &vt2)
461 {
463  return COLVARS_OK;
464  }
465 
466  if (vt1 != type_notset) {
467  if (((vt1 == type_unit3vector) &&
468  (vt2 == type_unit3vectorderiv)) ||
469  ((vt2 == type_unit3vector) &&
470  (vt1 == type_unit3vectorderiv)) ||
471  ((vt1 == type_quaternion) &&
472  (vt2 == type_quaternionderiv)) ||
473  ((vt2 == type_quaternion) &&
474  (vt1 == type_quaternionderiv))) {
475  return COLVARS_OK;
476  } else {
477  if (vt1 != vt2) {
478  cvm::error("Trying to assign a colvar value with type \""+
479  type_desc(vt2)+"\" to one with type \""+
480  type_desc(vt1)+"\".\n");
481  return COLVARS_ERROR;
482  }
483  }
484  }
485  return COLVARS_OK;
486 }
487 
488 
490 {
491  check_types_assign(this->type(), x.type());
492  value_type = x.type();
493 
494  switch (this->type()) {
496  this->real_value = x.real_value;
497  break;
501  this->rvector_value = x.rvector_value;
502  break;
506  break;
512  break;
514  default:
515  undef_op();
516  break;
517  }
518  return *this;
519 }
520 
521 
522 inline void colvarvalue::operator += (colvarvalue const &x)
523 {
524  colvarvalue::check_types(*this, x);
525 
526  switch (this->type()) {
528  this->real_value += x.real_value;
529  break;
533  this->rvector_value += x.rvector_value;
534  break;
538  break;
540  this->vector1d_value += x.vector1d_value;
541  break;
543  default:
544  undef_op();
545  }
546 }
547 
548 
549 inline void colvarvalue::operator -= (colvarvalue const &x)
550 {
551  colvarvalue::check_types(*this, x);
552 
553  switch (value_type) {
555  real_value -= x.real_value;
556  break;
561  break;
565  break;
567  this->vector1d_value -= x.vector1d_value;
568  break;
570  default:
571  undef_op();
572  }
573 }
574 
575 
576 inline void colvarvalue::operator *= (cvm::real const &a)
577 {
578  switch (value_type) {
580  real_value *= a;
581  break;
584  rvector_value *= a;
585  break;
588  quaternion_value *= a;
589  break;
591  this->vector1d_value *= a;
592  break;
594  default:
595  undef_op();
596  }
597 }
598 
599 
600 inline void colvarvalue::operator /= (cvm::real const &a)
601 {
602  switch (value_type) {
604  real_value /= a; break;
608  rvector_value /= a; break;
611  quaternion_value /= a; break;
613  this->vector1d_value /= a;
614  break;
616  default:
617  undef_op();
618  }
619 }
620 
621 
622 inline cvm::vector1d<cvm::real> const colvarvalue::as_vector() const
623 {
624  switch (value_type) {
626  {
628  v[0] = real_value;
629  return v;
630  }
634  return rvector_value.as_vector();
637  return quaternion_value.as_vector();
639  return vector1d_value;
641  default:
642  return cvm::vector1d<cvm::real>(0);
643  }
644 }
645 
646 
648 {
649  switch (value_type) {
651  return (this->real_value)*(this->real_value);
655  return (this->rvector_value).norm2();
658  return (this->quaternion_value).norm2();
660  if (elem_types.size() > 0) {
661  // if we have information about non-scalar types, use it
662  cvm::real result = 0.0;
663  size_t i;
664  for (i = 0; i < elem_types.size(); i++) {
665  result += (this->get_elem(i)).norm2();
666  }
667  return result;
668  } else {
669  return vector1d_value.norm2();
670  }
671  break;
673  default:
674  return 0.0;
675  }
676 }
677 
678 
679 inline cvm::real colvarvalue::dist2(colvarvalue const &x2) const
680 {
681  colvarvalue::check_types(*this, x2);
682 
683  switch (this->type()) {
685  return (this->real_value - x2.real_value)*(this->real_value - x2.real_value);
687  return (this->rvector_value - x2.rvector_value).norm2();
690  // angle between (*this) and x2 is the distance
691  return std::acos(this->rvector_value * x2.rvector_value) * std::acos(this->rvector_value * x2.rvector_value);
694  // angle between (*this) and x2 is the distance, the quaternion
695  // object has it implemented internally
696  return this->quaternion_value.dist2(x2.quaternion_value);
698  return (this->vector1d_value - x2.vector1d_value).norm2();
700  default:
701  this->undef_op();
702  return 0.0;
703  };
704 }
705 
706 
707 #endif
colvarvalue const get_elem(int const i_begin, int const i_end, Type const vt) const
Get a single colvarvalue out of elements of the vector.
Definition: colvarvalue.cpp:296
Scalar number, implemented as colvarmodule::real (default)
Definition: colvarvalue.h:47
void apply_constraints()
If the variable has constraints (e.g. unitvector or quaternion), transform it to satisfy them; this f...
Definition: colvarvalue.cpp:131
size_t output_width(size_t const &real_width) const
Definition: colvarvalue.cpp:739
1-dimensional vector of real numbers with four components and a quaternion algebra ...
Definition: colvartypes.h:1020
colvarvalue()
Default constructor: this class defaults to a scalar number and always behaves like it unless you cha...
Definition: colvarvalue.h:114
Undefined type.
Definition: colvarvalue.h:45
static std::string const type_desc(Type t)
Runtime description of value types.
Definition: colvarvalue.cpp:12
static void inner_opt(colvarvalue const &x, std::vector< colvarvalue >::iterator &xv, std::vector< colvarvalue >::iterator const &xv_end, std::vector< cvm::real >::iterator &result)
Optimized routine for the inner product of one collective variable with an array. ...
Definition: colvarvalue.cpp:761
Type type() const
Get the current type.
Definition: colvarvalue.h:159
cvm::real norm2() const
Square norm of this colvarvalue.
Definition: colvarvalue.h:647
static void p2leg_opt(colvarvalue const &x, std::vector< colvarvalue >::iterator &xv, std::vector< colvarvalue >::iterator const &xv_end, std::vector< cvm::real >::iterator &result)
Optimized routine for the second order Legendre polynomial, (3cos^2(w)-1)/2, of one collective variab...
Definition: colvarvalue.cpp:843
3-dimensional vector that is a derivative of a unitvector
Definition: colvarvalue.h:53
cvm::real real_value
Real data member.
Definition: colvarvalue.h:68
static int check_types_assign(Type const &vt1, Type const &vt2)
Ensure that the two types are the same within an assignment, or that the left side is type_notset...
Definition: colvarvalue.h:459
cvm::real dist2(colvarvalue const &x2) const
Square distance between this colvarvalue and another.
Definition: colvarvalue.h:679
colvarvalue(Type const &vti)
Constructor from a type specification.
Definition: colvarvalue.h:119
4-dimensional unit vector representing a rotation, implemented as colvarmodule::quaternion ...
Definition: colvarvalue.h:55
cvm::real operator[](int const i) const
Get a scalar number out of an element of the vector.
Definition: colvarvalue.h:370
std::vector< Type > elem_types
If vector1d_value is a concatenation of colvarvalues, keep track of the individual types...
Definition: colvarvalue.h:81
int from_simple_string(std::string const &s)
Parses value from a script-friendly string (space separated list)
Definition: colvarvalue.cpp:637
vector of real numbers with three components
Definition: colvartypes.h:714
friend std::istream & operator>>(std::istream &is, colvarvalue &q)
Formatted input operator.
Definition: colvarvalue.cpp:701
3-dimensional unit vector, implemented as colvarmodule::rvector
Definition: colvarvalue.h:51
void add_elem(colvarvalue const &x)
Definition: colvarvalue.cpp:280
size_t size() const
Number of dimensions of this variable.
Definition: colvarvalue.h:349
void set_random()
Make each element a random number in N(0,1)
Definition: colvarvalue.cpp:341
std::vector< int > elem_indices
If vector1d_value is a concatenation of colvarvalues, these mark the initial components of each colva...
Definition: colvarvalue.h:85
Needed to iterate through enum.
Definition: colvarvalue.h:61
Collective variables main module.
double real
Defining an abstract real number allows to switch precision.
Definition: colvarmodule.h:76
static int error(std::string const &message, int code=COLVARS_ERROR)
Print a message to the main log and set global error code.
Definition: colvarmodule.cpp:1587
cvm::real norm2() const
Squared norm.
Definition: colvartypes.h:202
static std::string const type_keyword(Type t)
User keywords for specifying value types in the configuration.
Definition: colvarvalue.cpp:37
colvarvalue(cvm::rvector const &v, Type vti=type_3vector)
Copy constructor from rvector base type (Note: this sets by default a type type_3vector ...
Definition: colvarvalue.h:133
4-dimensional vector that is a derivative of a quaternion
Definition: colvarvalue.h:57
Value of a collective variable: this is a metatype which can be set at runtime. By default it is set ...
Definition: colvarvalue.h:34
std::string to_simple_string() const
Formats value as a script-friendly string (space separated list)
Definition: colvarvalue.cpp:610
void set_elem(int const i_begin, int const i_end, colvarvalue const &x)
Set elements of the vector from a single colvarvalue.
Definition: colvarvalue.cpp:308
static int check_types(colvarvalue const &x1, colvarvalue const &x2)
Ensure that the two types are the same within a binary operator.
Definition: colvarvalue.h:416
void undef_op() const
Undefined operation.
Definition: colvarvalue.cpp:375
void reset()
Set to the null value for the data type currently defined.
Definition: colvarvalue.cpp:106
static size_t num_dimensions(Type t)
Number of dimensions for each supported type (used to allocate vector1d_value)
Definition: colvarvalue.cpp:84
colvarvalue(cvm::quaternion const &q, Type vti=type_quaternion)
Copy constructor from quaternion base type.
Definition: colvarvalue.h:138
Type value_type
Current type of this colvarvalue object.
Definition: colvarvalue.h:65
cvm::real norm() const
Norm of this colvarvalue.
Definition: colvarvalue.h:178
static size_t num_df(Type t)
Number of degrees of freedom for each supported type.
Definition: colvarvalue.cpp:61
static std::string to_str(T const &x, size_t const &width=0, size_t const &prec=0)
Quick conversion of an object to a string.
Definition: colvarmodule.h:607
void is_derivative()
Definition: colvarvalue.cpp:195
colvarvalue & operator=(colvarvalue const &x)
Assignment operator (type of x is checked)
Definition: colvarvalue.h:489
friend std::ostream & operator<<(std::ostream &os, colvarvalue const &q)
Formatted output operator.
Definition: colvarvalue.cpp:664
static colvarvalue const interpolate(colvarvalue const &x1, colvarvalue const &x2, cvm::real const lambda=0.5)
Definition: colvarvalue.cpp:568
colvarvalue dist2_grad(colvarvalue const &x2) const
Derivative with respect to this colvarvalue of the square distance.
Definition: colvarvalue.cpp:526
cvm::vector1d< cvm::real > vector1d_value
Generic vector data member.
Definition: colvarvalue.h:77
cvm::rvector rvector_value
3-dimensional vector data member
Definition: colvarvalue.h:71
colvarvalue(cvm::real const &x)
Copy constructor from real base type.
Definition: colvarvalue.h:126
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:1302
3-dimensional vector, implemented as colvarmodule::rvector
Definition: colvarvalue.h:49
static bool type_checking()
Whether or not the type check is enforced.
Definition: colvarvalue.h:92
vector (arbitrary dimension)
Definition: colvarvalue.h:59
std::vector< int > elem_sizes
If vector1d_value is a concatenation of colvarvalues, these mark how many components for each colvarv...
Definition: colvarvalue.h:89
cvm::quaternion quaternion_value
Quaternion data member.
Definition: colvarvalue.h:74
Type
Possible types of value.
Definition: colvarvalue.h:43
bool is_scalar() const
Whether this variable is a real number.
Definition: colvarvalue.h:254