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 00011 #ifndef COLVARMODULE_UTILS_H 00012 #define COLVARMODULE_UTILS_H 00013 00014 00015 #include "colvarmodule.h" 00016 00017 00018 template <typename T> 00019 cvm::real get_force_norm2(T const &x) 00020 { 00021 return x.norm2(); 00022 } 00023 00024 00025 template <> 00026 inline cvm::real get_force_norm2(cvm::real const &x) 00027 { 00028 return x*x; 00029 } 00030 00031 00032 template <typename T, int flag, bool get_index> 00033 cvm::real compute_norm2_stats(std::vector<T> const &v, 00034 int *minmax_index = NULL) 00035 { 00036 cvm::real result = 0.0; 00037 if (flag == -1) { 00038 // Initialize for minimum search, using approx. largest float32 value 00039 result = 1.0e38; 00040 } 00041 00042 typename std::vector<T>::const_iterator xi = v.begin(); 00043 size_t i = 0; 00044 00045 if (get_index) *minmax_index = -1; // Let's not assume minmax_index is initialized to -1 00046 00047 for ( ; xi != v.end(); xi++, i++) { 00048 cvm::real const norm2 = get_force_norm2<T>(*xi); 00049 if (flag == 0) { 00050 result += norm2; 00051 } 00052 if (flag == 1) { 00053 if (norm2 > result) { 00054 result = norm2; 00055 if (get_index) *minmax_index = i; 00056 } 00057 } 00058 if (flag == -1) { 00059 if (norm2 < result) { 00060 result = norm2; 00061 if (get_index) *minmax_index = i; 00062 } 00063 } 00064 } 00065 00066 size_t const n = v.size(); 00067 00068 if (flag == 0) { 00069 if (n > 0) { 00070 result /= cvm::real(n); 00071 } 00072 } 00073 00074 result = cvm::sqrt(result); 00075 00076 return result; 00077 } 00078 00079 00080 #endif