Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

colvarvalue.C

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 
00003 // This file is part of the Collective Variables module (Colvars).
00004 // The original version of Colvars and its updates are located at:
00005 // https://github.com/Colvars/colvars
00006 // Please update all Colvars source files before making any changes.
00007 // If you wish to distribute your changes, please submit them to the
00008 // Colvars repository at GitHub.
00009 
00010 #include <vector>
00011 #include <sstream>
00012 #include <iostream>
00013 
00014 #include "colvarmodule.h"
00015 #include "colvarvalue.h"
00016 
00017 
00018 
00019 colvarvalue::colvarvalue()
00020   : value_type(type_scalar), real_value(0.0)
00021 {}
00022 
00023 
00024 colvarvalue::colvarvalue(Type const &vti)
00025   : value_type(vti), real_value(0.0)
00026 {
00027   reset();
00028 }
00029 
00030 colvarvalue::colvarvalue(cvm::real const &x)
00031   : value_type(type_scalar), real_value(x)
00032 {}
00033 
00034 
00035 colvarvalue::colvarvalue(cvm::rvector const &v, colvarvalue::Type vti)
00036   : value_type(vti), real_value(0.0), rvector_value(v)
00037 {}
00038 
00039 
00040 colvarvalue::colvarvalue(cvm::quaternion const &q, colvarvalue::Type vti)
00041   : value_type(vti), real_value(0.0), quaternion_value(q)
00042 {}
00043 
00044 
00045 colvarvalue::colvarvalue(colvarvalue const &x)
00046   : value_type(x.type()), real_value(0.0)
00047 {
00048   switch (x.type()) {
00049   case type_scalar:
00050     real_value = x.real_value;
00051     break;
00052   case type_3vector:
00053   case type_unit3vector:
00054   case type_unit3vectorderiv:
00055     rvector_value = x.rvector_value;
00056     break;
00057   case type_quaternion:
00058   case type_quaternionderiv:
00059     quaternion_value = x.quaternion_value;
00060     break;
00061   case type_vector:
00062     vector1d_value = x.vector1d_value;
00063     elem_types = x.elem_types;
00064     elem_indices = x.elem_indices;
00065     elem_sizes = x.elem_sizes;
00066   case type_notset:
00067   default:
00068     break;
00069   }
00070 }
00071 
00072 
00073 colvarvalue::colvarvalue(cvm::vector1d<cvm::real> const &v,
00074                          colvarvalue::Type vti)
00075   : real_value(0.0)
00076 {
00077   if ((vti != type_vector) && (v.size() != num_dimensions(vti))) {
00078     cvm::error("Error: trying to initialize a variable of type \""+type_desc(vti)+
00079                "\" using a vector of size "+cvm::to_str(v.size())+
00080                ".\n");
00081     value_type = type_notset;
00082   } else {
00083     value_type = vti;
00084     switch (vti) {
00085     case type_scalar:
00086       real_value = v[0];
00087       break;
00088     case type_3vector:
00089     case type_unit3vector:
00090     case type_unit3vectorderiv:
00091       rvector_value = cvm::rvector(v);
00092       break;
00093     case type_quaternion:
00094     case type_quaternionderiv:
00095       quaternion_value = cvm::quaternion(v);
00096       break;
00097     case type_vector:
00098       vector1d_value = v;
00099       break;
00100     case type_notset:
00101     default:
00102       break;
00103     }
00104   }
00105 }
00106 
00107 
00108 std::string const colvarvalue::type_desc(Type t)
00109 {
00110   switch (t) {
00111   case colvarvalue::type_scalar:
00112     return "scalar number"; break;
00113   case colvarvalue::type_3vector:
00114     return "3-dimensional vector"; break;
00115   case colvarvalue::type_unit3vector:
00116     return "3-dimensional unit vector"; break;
00117   case colvarvalue::type_unit3vectorderiv:
00118     return "derivative of a 3-dimensional unit vector"; break;
00119   case colvarvalue::type_quaternion:
00120     return "4-dimensional unit quaternion"; break;
00121   case colvarvalue::type_quaternionderiv:
00122     return "4-dimensional tangent vector"; break;
00123   case colvarvalue::type_vector:
00124     return "n-dimensional vector"; break;
00125   case colvarvalue::type_notset:
00126     // fallthrough
00127   default:
00128     return "not set"; break;
00129   }
00130 }
00131 
00132 
00133 std::string const colvarvalue::type_keyword(Type t)
00134 {
00135   switch (t) {
00136   case colvarvalue::type_notset:
00137   default:
00138     return "not_set"; break;
00139   case colvarvalue::type_scalar:
00140     return "scalar"; break;
00141   case colvarvalue::type_3vector:
00142     return "vector3"; break;
00143   case colvarvalue::type_unit3vector:
00144     return "unit_vector3"; break;
00145   case colvarvalue::type_unit3vectorderiv:
00146     return ""; break;
00147   case colvarvalue::type_quaternion:
00148     return "unit_quaternion"; break;
00149   case colvarvalue::type_quaternionderiv:
00150     return ""; break;
00151   case colvarvalue::type_vector:
00152     return "vector"; break;
00153   }
00154 }
00155 
00156 
00157 size_t colvarvalue::num_df(Type t)
00158 {
00159   switch (t) {
00160   case colvarvalue::type_notset:
00161   default:
00162     return 0; break;
00163   case colvarvalue::type_scalar:
00164     return 1; break;
00165   case colvarvalue::type_3vector:
00166     return 3; break;
00167   case colvarvalue::type_unit3vector:
00168   case colvarvalue::type_unit3vectorderiv:
00169     return 2; break;
00170   case colvarvalue::type_quaternion:
00171   case colvarvalue::type_quaternionderiv:
00172     return 3; break;
00173   case colvarvalue::type_vector:
00174     // the size of a vector is unknown without its object
00175     return 0; break;
00176   }
00177 }
00178 
00179 
00180 size_t colvarvalue::num_dimensions(Type t)
00181 {
00182   switch (t) {
00183   case colvarvalue::type_notset:
00184   default:
00185     return 0; break;
00186   case colvarvalue::type_scalar:
00187     return 1; break;
00188   case colvarvalue::type_3vector:
00189   case colvarvalue::type_unit3vector:
00190   case colvarvalue::type_unit3vectorderiv:
00191     return 3; break;
00192   case colvarvalue::type_quaternion:
00193   case colvarvalue::type_quaternionderiv:
00194     return 4; break;
00195   case colvarvalue::type_vector:
00196     // the size of a vector is unknown without its object
00197     return 0; break;
00198   }
00199 }
00200 
00201 
00202 void colvarvalue::reset()
00203 {
00204   switch (value_type) {
00205   case colvarvalue::type_scalar:
00206     real_value = 0.0;
00207     break;
00208   case colvarvalue::type_3vector:
00209   case colvarvalue::type_unit3vector:
00210   case colvarvalue::type_unit3vectorderiv:
00211     rvector_value.reset();
00212     break;
00213   case colvarvalue::type_quaternion:
00214   case colvarvalue::type_quaternionderiv:
00215     quaternion_value.reset();
00216     break;
00217   case colvarvalue::type_vector:
00218     vector1d_value.reset();
00219     break;
00220   case colvarvalue::type_notset:
00221   default:
00222     break;
00223   }
00224 }
00225 
00226 
00227 void colvarvalue::apply_constraints()
00228 {
00229   switch (value_type) {
00230   case colvarvalue::type_scalar:
00231   case colvarvalue::type_3vector:
00232   case colvarvalue::type_unit3vectorderiv:
00233   case colvarvalue::type_quaternionderiv:
00234     break;
00235   case colvarvalue::type_unit3vector:
00236     rvector_value /= cvm::sqrt(rvector_value.norm2());
00237     break;
00238   case colvarvalue::type_quaternion:
00239     quaternion_value /= cvm::sqrt(quaternion_value.norm2());
00240     break;
00241   case colvarvalue::type_vector:
00242     if (elem_types.size() > 0) {
00243       // if we have information about non-scalar types, use it
00244       size_t i;
00245       for (i = 0; i < elem_types.size(); i++) {
00246         if (elem_sizes[i] == 1) continue; // TODO this can be optimized further
00247         colvarvalue cvtmp(vector1d_value.slice(elem_indices[i],
00248                                                elem_indices[i] + elem_sizes[i]), elem_types[i]);
00249         cvtmp.apply_constraints();
00250         set_elem(i, cvtmp);
00251       }
00252     }
00253     break;
00254   case colvarvalue::type_notset:
00255   default:
00256     break;
00257   }
00258 }
00259 
00260 
00261 void colvarvalue::type(Type const &vti)
00262 {
00263   if (vti != value_type) {
00264     // reset the value based on the previous type
00265     reset();
00266     if ((value_type == type_vector) && (vti != type_vector)) {
00267       vector1d_value.clear();
00268     }
00269     value_type = vti;
00270   }
00271 }
00272 
00273 
00274 void colvarvalue::type(colvarvalue const &x)
00275 {
00276   if (x.type() != value_type) {
00277     // reset the value based on the previous type
00278     reset();
00279     if (value_type == type_vector) {
00280       vector1d_value.clear();
00281     }
00282     value_type = x.type();
00283   }
00284 
00285   if (x.type() == type_vector) {
00286     vector1d_value.resize(x.vector1d_value.size());
00287   }
00288 }
00289 
00290 
00291 void colvarvalue::is_derivative()
00292 {
00293   switch (value_type) {
00294   case colvarvalue::type_scalar:
00295   case colvarvalue::type_3vector:
00296   case colvarvalue::type_unit3vectorderiv:
00297   case colvarvalue::type_quaternionderiv:
00298     break;
00299   case colvarvalue::type_unit3vector:
00300     type(colvarvalue::type_unit3vectorderiv);
00301     break;
00302   case colvarvalue::type_quaternion:
00303     type(colvarvalue::type_quaternionderiv);
00304     break;
00305   case colvarvalue::type_vector:
00306     // TODO
00307     break;
00308   case colvarvalue::type_notset:
00309   default:
00310     break;
00311   }
00312 }
00313 
00314 
00315 void colvarvalue::add_elem(colvarvalue const &x)
00316 {
00317   if (this->value_type != type_vector) {
00318     cvm::error("Error: trying to set an element for a variable that is not set to be a vector.\n");
00319     return;
00320   }
00321   size_t const n = vector1d_value.size();
00322   size_t const nd = num_dimensions(x.value_type);
00323   elem_types.push_back(x.value_type);
00324   elem_indices.push_back(n);
00325   elem_sizes.push_back(nd);
00326   vector1d_value.resize(n + nd);
00327   set_elem(n, x);
00328 }
00329 
00330 
00331 colvarvalue const colvarvalue::get_elem(int const i_begin, int const i_end, Type const vt) const
00332 {
00333   if (vector1d_value.size() > 0) {
00334     cvm::vector1d<cvm::real> const v(vector1d_value.slice(i_begin, i_end));
00335     return colvarvalue(v, vt);
00336   } else {
00337     cvm::error("Error: trying to get an element from a variable that is not a vector.\n");
00338     return colvarvalue(type_notset);
00339   }
00340 }
00341 
00342 
00343 void colvarvalue::set_elem(int const i_begin, int const i_end, colvarvalue const &x)
00344 {
00345   if (vector1d_value.size() > 0) {
00346     vector1d_value.sliceassign(i_begin, i_end, x.as_vector());
00347   } else {
00348     cvm::error("Error: trying to set an element for a variable that is not a vector.\n");
00349   }
00350 }
00351 
00352 
00353 colvarvalue const colvarvalue::get_elem(int const icv) const
00354 {
00355   if (elem_types.size() > 0) {
00356     return get_elem(elem_indices[icv], elem_indices[icv] + elem_sizes[icv],
00357                     elem_types[icv]);
00358   } else {
00359     cvm::error("Error: trying to get a colvarvalue element from a vector colvarvalue that was initialized as a plain array.\n");
00360     return colvarvalue(type_notset);
00361   }
00362 }
00363 
00364 
00365 void colvarvalue::set_elem(int const icv, colvarvalue const &x)
00366 {
00367   if (elem_types.size() > 0) {
00368     check_types_assign(elem_types[icv], x.value_type);
00369     set_elem(elem_indices[icv], elem_indices[icv] + elem_sizes[icv], x);
00370   } else {
00371     cvm::error("Error: trying to set a colvarvalue element for a colvarvalue that was initialized as a plain array.\n");
00372   }
00373 }
00374 
00375 
00376 void colvarvalue::set_random()
00377 {
00378   size_t ic;
00379   switch (this->type()) {
00380   case colvarvalue::type_scalar:
00381     this->real_value = cvm::rand_gaussian();
00382     break;
00383   case colvarvalue::type_3vector:
00384   case colvarvalue::type_unit3vector:
00385   case colvarvalue::type_unit3vectorderiv:
00386     this->rvector_value.x = cvm::rand_gaussian();
00387     this->rvector_value.y = cvm::rand_gaussian();
00388     this->rvector_value.z = cvm::rand_gaussian();
00389     break;
00390   case colvarvalue::type_quaternion:
00391   case colvarvalue::type_quaternionderiv:
00392     this->quaternion_value.q0 = cvm::rand_gaussian();
00393     this->quaternion_value.q1 = cvm::rand_gaussian();
00394     this->quaternion_value.q2 = cvm::rand_gaussian();
00395     this->quaternion_value.q3 = cvm::rand_gaussian();
00396     break;
00397   case colvarvalue::type_vector:
00398     for (ic = 0; ic < this->vector1d_value.size(); ic++) {
00399       this->vector1d_value[ic] = cvm::rand_gaussian();
00400     }
00401     break;
00402   case colvarvalue::type_notset:
00403   default:
00404     undef_op();
00405     break;
00406   }
00407 }
00408 
00409 
00410 void colvarvalue::set_ones(cvm::real assigned_value)
00411 {
00412   size_t ic;
00413   switch (this->type()) {
00414   case colvarvalue::type_scalar:
00415     this->real_value = assigned_value;
00416     break;
00417   case colvarvalue::type_3vector:
00418   case colvarvalue::type_unit3vector:
00419   case colvarvalue::type_unit3vectorderiv:
00420     this->rvector_value.x = assigned_value;
00421     this->rvector_value.y = assigned_value;
00422     this->rvector_value.z = assigned_value;
00423     break;
00424   case colvarvalue::type_quaternion:
00425   case colvarvalue::type_quaternionderiv:
00426     this->quaternion_value.q0 = assigned_value;
00427     this->quaternion_value.q1 = assigned_value;
00428     this->quaternion_value.q2 = assigned_value;
00429     this->quaternion_value.q3 = assigned_value;
00430     break;
00431   case colvarvalue::type_vector:
00432     for (ic = 0; ic < this->vector1d_value.size(); ic++) {
00433       this->vector1d_value[ic] = assigned_value;
00434     }
00435     break;
00436   case colvarvalue::type_notset:
00437   default:
00438     undef_op();
00439     break;
00440   }
00441 }
00442 
00443 
00444 void colvarvalue::undef_op() const
00445 {
00446   cvm::error("Error: Undefined operation on a colvar of type \""+
00447              type_desc(this->type())+"\".\n");
00448 }
00449 
00450 
00451 // binary operations between two colvarvalues
00452 
00453 colvarvalue operator + (colvarvalue const &x1,
00454                         colvarvalue const &x2)
00455 {
00456   colvarvalue::check_types(x1, x2);
00457 
00458   switch (x1.value_type) {
00459   case colvarvalue::type_scalar:
00460     return colvarvalue(x1.real_value + x2.real_value);
00461   case colvarvalue::type_3vector:
00462     return colvarvalue(x1.rvector_value + x2.rvector_value);
00463   case colvarvalue::type_unit3vector:
00464   case colvarvalue::type_unit3vectorderiv:
00465     return colvarvalue(x1.rvector_value + x2.rvector_value,
00466                        colvarvalue::type_unit3vector);
00467   case colvarvalue::type_quaternion:
00468   case colvarvalue::type_quaternionderiv:
00469     return colvarvalue(x1.quaternion_value + x2.quaternion_value);
00470   case colvarvalue::type_vector:
00471     return colvarvalue(x1.vector1d_value + x2.vector1d_value, colvarvalue::type_vector);
00472   case colvarvalue::type_notset:
00473   default:
00474     x1.undef_op();
00475     return colvarvalue(colvarvalue::type_notset);
00476   };
00477 }
00478 
00479 
00480 colvarvalue operator - (colvarvalue const &x1,
00481                         colvarvalue const &x2)
00482 {
00483   colvarvalue::check_types(x1, x2);
00484 
00485   switch (x1.value_type) {
00486   case colvarvalue::type_scalar:
00487     return colvarvalue(x1.real_value - x2.real_value);
00488   case colvarvalue::type_3vector:
00489     return colvarvalue(x1.rvector_value - x2.rvector_value);
00490   case colvarvalue::type_unit3vector:
00491   case colvarvalue::type_unit3vectorderiv:
00492     return colvarvalue(x1.rvector_value - x2.rvector_value,
00493                        colvarvalue::type_unit3vector);
00494   case colvarvalue::type_quaternion:
00495   case colvarvalue::type_quaternionderiv:
00496     return colvarvalue(x1.quaternion_value - x2.quaternion_value);
00497   case colvarvalue::type_vector:
00498     return colvarvalue(x1.vector1d_value - x2.vector1d_value, colvarvalue::type_vector);
00499   case colvarvalue::type_notset:
00500   default:
00501     x1.undef_op();
00502     return colvarvalue(colvarvalue::type_notset);
00503   };
00504 }
00505 
00506 
00507 // binary operations with real numbers
00508 
00509 colvarvalue operator * (cvm::real const &a,
00510                         colvarvalue const &x)
00511 {
00512   switch (x.value_type) {
00513   case colvarvalue::type_scalar:
00514     return colvarvalue(a * x.real_value);
00515   case colvarvalue::type_3vector:
00516     return colvarvalue(a * x.rvector_value);
00517   case colvarvalue::type_unit3vector:
00518   case colvarvalue::type_unit3vectorderiv:
00519     return colvarvalue(a * x.rvector_value,
00520                        colvarvalue::type_unit3vector);
00521   case colvarvalue::type_quaternion:
00522   case colvarvalue::type_quaternionderiv:
00523     return colvarvalue(a * x.quaternion_value);
00524   case colvarvalue::type_vector:
00525     return colvarvalue(x.vector1d_value * a, colvarvalue::type_vector);
00526   case colvarvalue::type_notset:
00527   default:
00528     x.undef_op();
00529     return colvarvalue(colvarvalue::type_notset);
00530   }
00531 }
00532 
00533 
00534 colvarvalue operator * (colvarvalue const &x,
00535                         cvm::real const &a)
00536 {
00537   return a * x;
00538 }
00539 
00540 
00541 colvarvalue operator / (colvarvalue const &x,
00542                         cvm::real const &a)
00543 {
00544   switch (x.value_type) {
00545   case colvarvalue::type_scalar:
00546     return colvarvalue(x.real_value / a);
00547   case colvarvalue::type_3vector:
00548     return colvarvalue(x.rvector_value / a);
00549   case colvarvalue::type_unit3vector:
00550   case colvarvalue::type_unit3vectorderiv:
00551     return colvarvalue(x.rvector_value / a,
00552                        colvarvalue::type_unit3vector);
00553   case colvarvalue::type_quaternion:
00554   case colvarvalue::type_quaternionderiv:
00555     return colvarvalue(x.quaternion_value / a);
00556   case colvarvalue::type_vector:
00557     return colvarvalue(x.vector1d_value / a, colvarvalue::type_vector);
00558   case colvarvalue::type_notset:
00559   default:
00560     x.undef_op();
00561     return colvarvalue(colvarvalue::type_notset);
00562   }
00563 }
00564 
00565 
00566 // inner product between two colvarvalues
00567 
00568 cvm::real operator * (colvarvalue const &x1,
00569                       colvarvalue const &x2)
00570 {
00571   colvarvalue::check_types(x1, x2);
00572 
00573   switch (x1.value_type) {
00574   case colvarvalue::type_scalar:
00575     return (x1.real_value * x2.real_value);
00576   case colvarvalue::type_3vector:
00577   case colvarvalue::type_unit3vector:
00578   case colvarvalue::type_unit3vectorderiv:
00579     return (x1.rvector_value * x2.rvector_value);
00580   case colvarvalue::type_quaternion:
00581   case colvarvalue::type_quaternionderiv:
00582     // the "*" product is the quaternion product, here the inner
00583     // member function is used instead
00584     return (x1.quaternion_value.inner(x2.quaternion_value));
00585   case colvarvalue::type_vector:
00586     return (x1.vector1d_value * x2.vector1d_value);
00587   case colvarvalue::type_notset:
00588   default:
00589     x1.undef_op();
00590     return 0.0;
00591   };
00592 }
00593 
00594 
00595 colvarvalue colvarvalue::dist2_grad(colvarvalue const &x2) const
00596 {
00597   colvarvalue::check_types(*this, x2);
00598 
00599   switch (this->value_type) {
00600   case colvarvalue::type_scalar:
00601     return 2.0 * (this->real_value - x2.real_value);
00602   case colvarvalue::type_3vector:
00603     return 2.0 * (this->rvector_value - x2.rvector_value);
00604   case colvarvalue::type_unit3vector:
00605   case colvarvalue::type_unit3vectorderiv:
00606     {
00607       cvm::rvector const &v1 = this->rvector_value;
00608       cvm::rvector const &v2 = x2.rvector_value;
00609       cvm::real const cos_t = v1 * v2;
00610       return colvarvalue(2.0 * (cos_t * v1 - v2), colvarvalue::type_unit3vectorderiv);
00611     }
00612   case colvarvalue::type_quaternion:
00613   case colvarvalue::type_quaternionderiv:
00614     return this->quaternion_value.dist2_grad(x2.quaternion_value);
00615   case colvarvalue::type_vector:
00616     return colvarvalue(2.0 * (this->vector1d_value - x2.vector1d_value), colvarvalue::type_vector);
00617     break;
00618   case colvarvalue::type_notset:
00619   default:
00620     this->undef_op();
00621     return colvarvalue(colvarvalue::type_notset);
00622   };
00623 }
00624 
00625 
00628 colvarvalue const colvarvalue::interpolate(colvarvalue const &x1,
00629                                            colvarvalue const &x2,
00630                                            cvm::real const lambda)
00631 {
00632   colvarvalue::check_types(x1, x2);
00633 
00634   if ((lambda < 0.0) || (lambda > 1.0)) {
00635     cvm::error("Error: trying to interpolate between two colvarvalues with a "
00636                "lamdba outside [0:1].\n", COLVARS_BUG_ERROR);
00637   }
00638 
00639   colvarvalue interp = ((1.0-lambda)*x1 + lambda*x2);
00640   cvm::real const d2 = x1.dist2(x2);
00641 
00642   switch (x1.type()) {
00643   case colvarvalue::type_scalar:
00644   case colvarvalue::type_3vector:
00645   case colvarvalue::type_vector:
00646   case colvarvalue::type_unit3vectorderiv:
00647   case colvarvalue::type_quaternionderiv:
00648     return interp;
00649     break;
00650   case colvarvalue::type_unit3vector:
00651   case colvarvalue::type_quaternion:
00652     if (interp.norm()/cvm::sqrt(d2) < 1.0e-6) {
00653       cvm::error("Error: interpolation between "+cvm::to_str(x1)+" and "+
00654                  cvm::to_str(x2)+" with lambda = "+cvm::to_str(lambda)+
00655                  " is undefined: result = "+cvm::to_str(interp)+"\n",
00656                  COLVARS_INPUT_ERROR);
00657     }
00658     interp.apply_constraints();
00659     return interp;
00660     break;
00661   case colvarvalue::type_notset:
00662   default:
00663     x1.undef_op();
00664     break;
00665   }
00666   return colvarvalue(colvarvalue::type_notset);
00667 }
00668 
00669 
00670 std::string colvarvalue::to_simple_string() const
00671 {
00672   switch (type()) {
00673   case colvarvalue::type_scalar:
00674     return cvm::to_str(real_value, 0, cvm::cv_prec);
00675     break;
00676   case colvarvalue::type_3vector:
00677   case colvarvalue::type_unit3vector:
00678   case colvarvalue::type_unit3vectorderiv:
00679     return rvector_value.to_simple_string();
00680     break;
00681   case colvarvalue::type_quaternion:
00682   case colvarvalue::type_quaternionderiv:
00683     return quaternion_value.to_simple_string();
00684     break;
00685   case colvarvalue::type_vector:
00686     return vector1d_value.to_simple_string();
00687     break;
00688   case colvarvalue::type_notset:
00689   default:
00690     undef_op();
00691     break;
00692   }
00693   return std::string();
00694 }
00695 
00696 
00697 int colvarvalue::from_simple_string(std::string const &s)
00698 {
00699   switch (type()) {
00700   case colvarvalue::type_scalar:
00701     return ((std::istringstream(s) >> real_value)
00702             ? COLVARS_OK : COLVARS_ERROR);
00703     break;
00704   case colvarvalue::type_3vector:
00705   case colvarvalue::type_unit3vector:
00706   case colvarvalue::type_unit3vectorderiv:
00707     return rvector_value.from_simple_string(s);
00708     break;
00709   case colvarvalue::type_quaternion:
00710   case colvarvalue::type_quaternionderiv:
00711     return quaternion_value.from_simple_string(s);
00712     break;
00713   case colvarvalue::type_vector:
00714     return vector1d_value.from_simple_string(s);
00715     break;
00716   case colvarvalue::type_notset:
00717   default:
00718     undef_op();
00719     break;
00720   }
00721   return COLVARS_ERROR;
00722 }
00723 
00724 std::ostream & operator << (std::ostream &os, colvarvalue const &x)
00725 {
00726   switch (x.type()) {
00727   case colvarvalue::type_scalar:
00728     os << x.real_value;
00729     break;
00730   case colvarvalue::type_3vector:
00731   case colvarvalue::type_unit3vector:
00732   case colvarvalue::type_unit3vectorderiv:
00733     os << x.rvector_value;
00734     break;
00735   case colvarvalue::type_quaternion:
00736   case colvarvalue::type_quaternionderiv:
00737     os << x.quaternion_value;
00738     break;
00739   case colvarvalue::type_vector:
00740     os << x.vector1d_value;
00741     break;
00742   case colvarvalue::type_notset:
00743   default:
00744     os << "not set";
00745     break;
00746   }
00747   return os;
00748 }
00749 
00750 
00751 std::ostream & operator << (std::ostream &os, std::vector<colvarvalue> const &v)
00752 {
00753   size_t i;
00754   for (i = 0; i < v.size(); i++) {
00755     os << v[i];
00756   }
00757   return os;
00758 }
00759 
00760 
00761 std::istream & operator >> (std::istream &is, colvarvalue &x)
00762 {
00763   if (x.type() == colvarvalue::type_notset) {
00764     cvm::error("Trying to read from a stream a colvarvalue, "
00765                "which has not yet been assigned a data type.\n");
00766     return is;
00767   }
00768 
00769   switch (x.type()) {
00770   case colvarvalue::type_scalar:
00771     is >> x.real_value;
00772     break;
00773   case colvarvalue::type_3vector:
00774   case colvarvalue::type_unit3vectorderiv:
00775     is >> x.rvector_value;
00776     break;
00777   case colvarvalue::type_unit3vector:
00778     is >> x.rvector_value;
00779     x.apply_constraints();
00780     break;
00781   case colvarvalue::type_quaternion:
00782     is >> x.quaternion_value;
00783     x.apply_constraints();
00784     break;
00785   case colvarvalue::type_quaternionderiv:
00786     is >> x.quaternion_value;
00787     break;
00788   case colvarvalue::type_vector:
00789     is >> x.vector1d_value;
00790     break;
00791   case colvarvalue::type_notset:
00792   default:
00793     x.undef_op();
00794   }
00795   return is;
00796 }
00797 
00798 
00799 size_t colvarvalue::output_width(size_t const &real_width) const
00800 {
00801   switch (this->value_type) {
00802   case colvarvalue::type_scalar:
00803     return real_width;
00804   case colvarvalue::type_3vector:
00805   case colvarvalue::type_unit3vector:
00806   case colvarvalue::type_unit3vectorderiv:
00807     return cvm::rvector::output_width(real_width);
00808   case colvarvalue::type_quaternion:
00809   case colvarvalue::type_quaternionderiv:
00810     return cvm::quaternion::output_width(real_width);
00811   case colvarvalue::type_vector:
00812     // note how this depends on the vector's size
00813     return vector1d_value.output_width(real_width);
00814   case colvarvalue::type_notset:
00815   default:
00816     return 0;
00817   }
00818 }
00819 
00820 
00821 void colvarvalue::inner_opt(colvarvalue                        const &x,
00822                             std::vector<colvarvalue>::iterator       &xv,
00823                             std::vector<colvarvalue>::iterator const &xv_end,
00824                             std::vector<cvm::real>::iterator         &result)
00825 {
00826   // doing type check only once, here
00827   colvarvalue::check_types(x, *xv);
00828 
00829   std::vector<colvarvalue>::iterator &xvi = xv;
00830   std::vector<cvm::real>::iterator    &ii = result;
00831 
00832   switch (x.value_type) {
00833   case colvarvalue::type_scalar:
00834     while (xvi != xv_end) {
00835       *(ii++) += (xvi++)->real_value * x.real_value;
00836     }
00837     break;
00838   case colvarvalue::type_3vector:
00839   case colvarvalue::type_unit3vector:
00840   case colvarvalue::type_unit3vectorderiv:
00841     while (xvi != xv_end) {
00842       *(ii++) += (xvi++)->rvector_value * x.rvector_value;
00843     }
00844     break;
00845   case colvarvalue::type_quaternion:
00846   case colvarvalue::type_quaternionderiv:
00847     while (xvi != xv_end) {
00848       *(ii++) += ((xvi++)->quaternion_value).cosine(x.quaternion_value);
00849     }
00850     break;
00851   case colvarvalue::type_vector:
00852     while (xvi != xv_end) {
00853       *(ii++) += (xvi++)->vector1d_value * x.vector1d_value;
00854     }
00855     break;
00856   default:
00857     x.undef_op();
00858   };
00859 }
00860 
00861 
00862 void colvarvalue::inner_opt(colvarvalue const                      &x,
00863                             std::list<colvarvalue>::iterator       &xv,
00864                             std::list<colvarvalue>::iterator const &xv_end,
00865                             std::vector<cvm::real>::iterator       &result)
00866 {
00867   // doing type check only once, here
00868   colvarvalue::check_types(x, *xv);
00869 
00870   std::list<colvarvalue>::iterator &xvi = xv;
00871   std::vector<cvm::real>::iterator  &ii = result;
00872 
00873   switch (x.value_type) {
00874   case colvarvalue::type_scalar:
00875     while (xvi != xv_end) {
00876       *(ii++) += (xvi++)->real_value * x.real_value;
00877     }
00878     break;
00879   case colvarvalue::type_3vector:
00880   case colvarvalue::type_unit3vector:
00881   case colvarvalue::type_unit3vectorderiv:
00882     while (xvi != xv_end) {
00883       *(ii++) += (xvi++)->rvector_value * x.rvector_value;
00884     }
00885     break;
00886   case colvarvalue::type_quaternion:
00887   case colvarvalue::type_quaternionderiv:
00888     while (xvi != xv_end) {
00889       *(ii++) += ((xvi++)->quaternion_value).cosine(x.quaternion_value);
00890     }
00891     break;
00892   case colvarvalue::type_vector:
00893     while (xvi != xv_end) {
00894       *(ii++) += (xvi++)->vector1d_value * x.vector1d_value;
00895     }
00896     break;
00897   default:
00898     x.undef_op();
00899   };
00900 }
00901 
00902 
00903 void colvarvalue::p2leg_opt(colvarvalue const                        &x,
00904                             std::vector<colvarvalue>::iterator       &xv,
00905                             std::vector<colvarvalue>::iterator const &xv_end,
00906                             std::vector<cvm::real>::iterator         &result)
00907 {
00908   // doing type check only once, here
00909   colvarvalue::check_types(x, *xv);
00910 
00911   std::vector<colvarvalue>::iterator &xvi = xv;
00912   std::vector<cvm::real>::iterator    &ii = result;
00913 
00914   switch (x.value_type) {
00915   case colvarvalue::type_scalar:
00916     cvm::error("Error: cannot calculate Legendre polynomials "
00917                "for scalar variables.\n");
00918     return;
00919     break;
00920   case colvarvalue::type_3vector:
00921     while (xvi != xv_end) {
00922       cvm::real const cosine =
00923         ((xvi)->rvector_value * x.rvector_value) /
00924         ((xvi)->rvector_value.norm() * x.rvector_value.norm());
00925       xvi++;
00926       *(ii++) += 1.5*cosine*cosine - 0.5;
00927     }
00928     break;
00929   case colvarvalue::type_unit3vector:
00930   case colvarvalue::type_unit3vectorderiv:
00931     while (xvi != xv_end) {
00932       cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
00933       *(ii++) += 1.5*cosine*cosine - 0.5;
00934     }
00935     break;
00936   case colvarvalue::type_quaternion:
00937   case colvarvalue::type_quaternionderiv:
00938     while (xvi != xv_end) {
00939       cvm::real const cosine = (xvi++)->quaternion_value.cosine(x.quaternion_value);
00940       *(ii++) += 1.5*cosine*cosine - 0.5;
00941     }
00942     break;
00943   case colvarvalue::type_vector:
00944     while (xvi != xv_end) {
00945       cvm::real const cosine =
00946         ((xvi)->vector1d_value * x.vector1d_value) /
00947         ((xvi)->vector1d_value.norm() * x.rvector_value.norm());
00948       xvi++;
00949       *(ii++) += 1.5*cosine*cosine - 0.5;
00950     }
00951     break;
00952   default:
00953     x.undef_op();
00954   };
00955 }
00956 
00957 
00958 void colvarvalue::p2leg_opt(colvarvalue const                        &x,
00959                             std::list<colvarvalue>::iterator         &xv,
00960                             std::list<colvarvalue>::iterator const   &xv_end,
00961                             std::vector<cvm::real>::iterator         &result)
00962 {
00963   // doing type check only once, here
00964   colvarvalue::check_types(x, *xv);
00965 
00966   std::list<colvarvalue>::iterator &xvi = xv;
00967   std::vector<cvm::real>::iterator  &ii = result;
00968 
00969   switch (x.value_type) {
00970   case colvarvalue::type_scalar:
00971     cvm::error("Error: cannot calculate Legendre polynomials "
00972                "for scalar variables.\n");
00973     break;
00974   case colvarvalue::type_3vector:
00975     while (xvi != xv_end) {
00976       cvm::real const cosine =
00977         ((xvi)->rvector_value * x.rvector_value) /
00978         ((xvi)->rvector_value.norm() * x.rvector_value.norm());
00979       xvi++;
00980       *(ii++) += 1.5*cosine*cosine - 0.5;
00981     }
00982     break;
00983   case colvarvalue::type_unit3vector:
00984   case colvarvalue::type_unit3vectorderiv:
00985     while (xvi != xv_end) {
00986       cvm::real const cosine = (xvi++)->rvector_value * x.rvector_value;
00987       *(ii++) += 1.5*cosine*cosine - 0.5;
00988     }
00989     break;
00990   case colvarvalue::type_quaternion:
00991   case colvarvalue::type_quaternionderiv:
00992     while (xvi != xv_end) {
00993       cvm::real const cosine = (xvi++)->quaternion_value.cosine(x.quaternion_value);
00994       *(ii++) += 1.5*cosine*cosine - 0.5;
00995     }
00996     break;
00997   default:
00998     x.undef_op();
00999   };
01000 }
01001 
01002 
01003 

Generated on Fri Nov 8 02:44:21 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002