00001
00002
00003
00004
00005
00006
00007
00008
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
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
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
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
00244 size_t i;
00245 for (i = 0; i < elem_types.size(); i++) {
00246 if (elem_sizes[i] == 1) continue;
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
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
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
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
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
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
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
00583
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
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
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
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
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
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