LCOV - code coverage report
Current view: top level - ves - CoeffsVector.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 237 465 51.0 %
Date: 2025-03-25 09:33:27 Functions: 45 99 45.5 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2016-2021 The VES code team
       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
       4             : 
       5             :    See http://www.ves-code.org for more information.
       6             : 
       7             :    This file is part of VES code module.
       8             : 
       9             :    The VES code module is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    The VES code module is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : 
      23             : #include "CoeffsVector.h"
      24             : #include "CoeffsMatrix.h"
      25             : #include "BasisFunctions.h"
      26             : 
      27             : #include "tools/Tools.h"
      28             : #include "core/Value.h"
      29             : #include "tools/File.h"
      30             : #include "tools/Exception.h"
      31             : #include "tools/Random.h"
      32             : #include "tools/Communicator.h"
      33             : 
      34             : #include <vector>
      35             : #include <cmath>
      36             : #include <iostream>
      37             : #include <sstream>
      38             : #include <cstdio>
      39             : #include <cfloat>
      40             : 
      41             : 
      42             : namespace PLMD {
      43             : namespace ves {
      44             : 
      45           0 : CoeffsVector::CoeffsVector(
      46             :   const std::string& label,
      47             :   const std::vector<std::string>& dimension_labels,
      48             :   const std::vector<unsigned int>& indices_shape,
      49             :   Communicator& cc,
      50           0 :   const bool use_iteration_counter):
      51             :   CoeffsBase(label,dimension_labels,indices_shape,use_iteration_counter),
      52           0 :   data(0),
      53           0 :   averaging_counter(0),
      54           0 :   averaging_exp_decay_(0),
      55           0 :   mycomm(cc) {
      56           0 :   clear();
      57           0 : }
      58             : 
      59             : 
      60         377 : CoeffsVector::CoeffsVector(
      61             :   const std::string& label,
      62             :   const std::vector<Value*>& args,
      63             :   std::vector<BasisFunctions*>& basisf,
      64             :   Communicator& cc,
      65         377 :   const bool use_iteration_counter):
      66             :   CoeffsBase(label,args,basisf,use_iteration_counter),
      67         377 :   data(0),
      68         377 :   averaging_counter(0),
      69         377 :   averaging_exp_decay_(0),
      70         377 :   mycomm(cc) {
      71         377 :   clear();
      72         377 : }
      73             : 
      74             : 
      75           0 : CoeffsVector::CoeffsVector(
      76             :   const std::string& label,
      77             :   std::vector<std::vector<Value*> >& argsv,
      78             :   std::vector<std::vector<BasisFunctions*> >& basisfv,
      79             :   Communicator& cc,
      80             :   const bool use_iteration_counter,
      81           0 :   const std::string& multicoeffs_label):
      82             :   CoeffsBase(label,argsv,basisfv,use_iteration_counter,multicoeffs_label),
      83           0 :   data(0),
      84           0 :   averaging_counter(0),
      85           0 :   averaging_exp_decay_(0),
      86           0 :   mycomm(cc) {
      87           0 :   clear();
      88           0 : }
      89             : 
      90             : 
      91           0 : CoeffsVector::CoeffsVector(
      92             :   const std::string& label,
      93             :   CoeffsMatrix* coeffsMat,
      94           0 :   Communicator& cc):
      95             :   CoeffsBase( *(static_cast<CoeffsBase*>(coeffsMat)) ),
      96           0 :   data(0),
      97           0 :   averaging_counter(0),
      98           0 :   averaging_exp_decay_(0),
      99           0 :   mycomm(cc) {
     100           0 :   clear();
     101           0 : }
     102             : 
     103             : 
     104      341962 : CoeffsVector::~CoeffsVector() {}
     105             : 
     106             : 
     107       23209 : void CoeffsVector::clear() {
     108       23209 :   data.resize(getSize());
     109     1833419 :   for(size_t i=0; i<data.size(); i++) {
     110     1810210 :     data[i]=0.0;
     111             :   }
     112       23209 : }
     113             : 
     114             : 
     115           2 : void CoeffsVector::setAllValuesToZero() {
     116          24 :   for(size_t i=0; i<data.size(); i++) {
     117          22 :     data[i]=0.0;
     118             :   }
     119           2 : }
     120             : 
     121             : 
     122           6 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvector_in) const {
     123           6 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsvector_in)) );
     124             : }
     125             : 
     126             : 
     127           0 : bool CoeffsVector::sameShape(CoeffsMatrix& coeffsmat_in) const {
     128           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsmat_in)) );
     129             : }
     130             : 
     131             : 
     132           0 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
     133           0 :   return coeffsvec0.sameShape(coeffsvec1);
     134             : }
     135             : 
     136             : 
     137           0 : void CoeffsVector::resizeCoeffs(const std::vector<unsigned int>& indices_shape_new) {
     138           0 :   CoeffsVector coeffsVecOld(*this);
     139           0 :   resizeIndices(indices_shape_new);
     140           0 :   clear();
     141           0 :   setValuesFromDifferentShape(coeffsVecOld);
     142           0 : }
     143             : 
     144             : 
     145           0 : void CoeffsVector::resizeCoeffs(std::vector<BasisFunctions*>& basisf_new) {
     146           0 :   CoeffsVector coeffsVecOld(*this);
     147           0 :   resizeIndices(basisf_new);
     148           0 :   clear();
     149           0 :   setValuesFromDifferentShape(coeffsVecOld);
     150           0 : }
     151             : 
     152             : 
     153           0 : void CoeffsVector::sumCommMPI() {
     154           0 :   mycomm.Sum(data);
     155           0 : }
     156             : 
     157             : 
     158           0 : void CoeffsVector::sumCommMPI(Communicator& cc) {
     159           0 :   cc.Sum(data);
     160           0 : }
     161             : 
     162             : 
     163           0 : void CoeffsVector::sumMultiSimCommMPI(Communicator& multi_sim_cc) {
     164           0 :   if(mycomm.Get_rank()==0) {
     165           0 :     double nwalkers = static_cast<double>(multi_sim_cc.Get_size());
     166           0 :     multi_sim_cc.Sum(data);
     167           0 :     scaleAllValues(1.0/nwalkers);
     168             :   }
     169           0 :   mycomm.Bcast(data,0);
     170           0 : }
     171             : 
     172             : 
     173         178 : double& CoeffsVector::operator[](const size_t index) {
     174             :   plumed_dbg_assert(index<data.size());
     175         178 :   return data[index];
     176             : }
     177             : 
     178             : 
     179           0 : const double& CoeffsVector::operator[](const size_t index) const {
     180             :   plumed_dbg_assert(index<data.size());
     181           0 :   return data[index];
     182             : }
     183             : 
     184             : 
     185           0 : double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) {
     186           0 :   return data[getIndex(indices)];
     187             : }
     188             : 
     189             : 
     190           0 : const double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) const {
     191           0 :   return data[getIndex(indices)];
     192             : }
     193             : 
     194             : 
     195     1790345 : double& CoeffsVector::operator()(const size_t index) {
     196             :   plumed_dbg_assert(index<data.size());
     197     1790345 :   return data[index];
     198             : }
     199             : 
     200             : 
     201     1790345 : const double& CoeffsVector::operator()(const size_t index) const {
     202             :   plumed_dbg_assert(index<data.size());
     203     1790345 :   return data[index];
     204             : }
     205             : 
     206             : 
     207           0 : double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) {
     208           0 :   return data[getIndex(indices)];
     209             : }
     210             : 
     211             : 
     212           0 : const double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) const {
     213           0 :   return data[getIndex(indices)];
     214             : }
     215             : 
     216             : 
     217         219 : void CoeffsVector::setValue(const size_t index, const double value) {
     218             :   plumed_dbg_assert(index<data.size());
     219         219 :   data[index]=value;
     220         219 : }
     221             : 
     222             : 
     223           0 : void CoeffsVector::setValue(const std::vector<unsigned int>& indices, const double value) {
     224           0 :   setValue(getIndex(indices),value);
     225           0 : }
     226             : 
     227             : 
     228           0 : void CoeffsVector::addToValue(const size_t index, const double value) {
     229             :   plumed_dbg_assert(index<data.size());
     230           0 :   data[index]+=value;
     231           0 : }
     232             : 
     233             : 
     234           0 : void CoeffsVector::addToValue(const std::vector<unsigned int>& indices, const double value) {
     235           0 :   addToValue(getIndex(indices),value);
     236           0 : }
     237             : 
     238             : 
     239       45477 : void CoeffsVector::scaleAllValues(const double scalef) {
     240     3626338 :   for(size_t i=0; i<data.size(); i++) {
     241     3580861 :     data[i]*=scalef;
     242             :   }
     243       45477 : }
     244             : 
     245             : 
     246       45470 : CoeffsVector& CoeffsVector::operator*=(const double scalef) {
     247       45470 :   scaleAllValues(scalef);
     248       45470 :   return *this;
     249             : }
     250             : 
     251             : 
     252       45430 : CoeffsVector operator*(const double scalef, const CoeffsVector& coeffsvector) {
     253       45430 :   return CoeffsVector(coeffsvector)*=scalef;
     254             : }
     255             : 
     256             : 
     257           0 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const double scalef) {
     258           0 :   return scalef*coeffsvector;
     259             : }
     260             : 
     261             : 
     262          20 : void CoeffsVector::multiplyWithValues(const std::vector<double>& values) {
     263          20 :   plumed_massert( data.size()==values.size(), "Incorrect size");
     264         240 :   for(size_t i=0; i<data.size(); i++) {
     265         220 :     data[i]*=values[i];
     266             :   }
     267          20 : }
     268             : 
     269             : 
     270       22765 : CoeffsVector& CoeffsVector::operator*=(const CoeffsVector& other_coeffsvector) {
     271       22765 :   plumed_massert(data.size()==other_coeffsvector.getSize(),"Coeffs vectors do not have the same size");
     272     1813440 :   for(size_t i=0; i<data.size(); i++) {
     273     1790675 :     data[i]*=other_coeffsvector.data[i];
     274             :   }
     275       22765 :   return *this;
     276             : }
     277             : 
     278             : 
     279       22765 : CoeffsVector CoeffsVector::operator*(const CoeffsVector& other_coeffsvector) const {
     280       22765 :   return CoeffsVector(*this)*=other_coeffsvector;
     281             : }
     282             : 
     283             : 
     284           0 : CoeffsVector operator*(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
     285           0 :   return coeffsvector*values;
     286             : }
     287             : 
     288             : 
     289          20 : CoeffsVector& CoeffsVector::operator*=(const std::vector<double>& values) {
     290          20 :   multiplyWithValues(values);
     291          20 :   return *this;
     292             : }
     293             : 
     294             : 
     295          20 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
     296          20 :   return CoeffsVector(coeffsvector)*=values;
     297             : }
     298             : 
     299             : 
     300         174 : void CoeffsVector::setValues(const double value) {
     301        8402 :   for(size_t i=0; i<data.size(); i++) {
     302        8228 :     data[i]=value;
     303             :   }
     304         174 : }
     305             : 
     306             : 
     307         700 : void CoeffsVector::setValues(const std::vector<double>& values) {
     308         700 :   plumed_massert( data.size()==values.size(), "Incorrect size");
     309       23133 :   for(size_t i=0; i<data.size(); i++) {
     310       22433 :     data[i]=values[i];
     311             :   }
     312         700 : }
     313             : 
     314             : 
     315       23410 : void CoeffsVector::setValues(const CoeffsVector& other_coeffsvector) {
     316       23410 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
     317     1847404 :   for(size_t i=0; i<data.size(); i++) {
     318     1823994 :     data[i]=other_coeffsvector.data[i];
     319             :   }
     320       23410 : }
     321             : 
     322             : 
     323           0 : CoeffsVector& CoeffsVector::operator=(const double value) {
     324           0 :   setValues(value);
     325           0 :   return *this;
     326             : }
     327             : 
     328             : 
     329         453 : CoeffsVector& CoeffsVector::operator=(const std::vector<double>& values) {
     330         453 :   setValues(values);
     331         453 :   return *this;
     332             : }
     333             : 
     334             : 
     335             : // CoeffsVector& CoeffsVector::operator=(const CoeffsVector& other_coeffsvector) {
     336             : //   setValues(other_coeffsvector);
     337             : //   return *this;
     338             : // }
     339             : 
     340             : 
     341           0 : CoeffsVector CoeffsVector::operator+() const {
     342           0 :   return *this;
     343             : }
     344             : 
     345             : 
     346           0 : CoeffsVector CoeffsVector::operator-() const {
     347           0 :   return CoeffsVector(*this)*=-1.0;
     348             : }
     349             : 
     350             : 
     351           0 : void CoeffsVector::addToValues(const double value) {
     352           0 :   for(size_t i=0; i<data.size(); i++) {
     353           0 :     data[i]+=value;
     354             :   }
     355           0 : }
     356             : 
     357             : 
     358           0 : void CoeffsVector::addToValues(const std::vector<double>& values) {
     359           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
     360           0 :   for(size_t i=0; i<data.size(); i++) {
     361           0 :     data[i]+=values[i];
     362             :   }
     363           0 : }
     364             : 
     365             : 
     366       68145 : void CoeffsVector::addToValues(const CoeffsVector& other_coeffsvector) {
     367       68145 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
     368     5438520 :   for(size_t i=0; i<data.size(); i++) {
     369     5370375 :     data[i]+=other_coeffsvector.data[i];
     370             :   }
     371       68145 : }
     372             : 
     373             : 
     374           0 : void CoeffsVector::subtractFromValues(const double value) {
     375           0 :   for(size_t i=0; i<data.size(); i++) {
     376           0 :     data[i]-=value;
     377             :   }
     378           0 : }
     379             : 
     380             : 
     381       22810 : void CoeffsVector::subtractFromValues(const std::vector<double>& values) {
     382       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
     383     1823850 :   for(size_t i=0; i<data.size(); i++) {
     384     1801040 :     data[i]-=values[i];
     385             :   }
     386       22810 : }
     387             : 
     388             : 
     389       45440 : void CoeffsVector::subtractFromValues(const CoeffsVector& other_coeffsvector) {
     390       45440 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
     391     3625800 :   for(size_t i=0; i<data.size(); i++) {
     392     3580360 :     data[i]-=other_coeffsvector.data[i];
     393             :   }
     394       45440 : }
     395             : 
     396             : 
     397           0 : CoeffsVector& CoeffsVector::operator+=(const double value) {
     398           0 :   addToValues(value);
     399           0 :   return *this;
     400             : }
     401             : 
     402             : 
     403           0 : CoeffsVector operator+(const double value, const CoeffsVector& coeffsvector) {
     404           0 :   return coeffsvector+value;
     405             : }
     406             : 
     407             : 
     408           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const double value) {
     409           0 :   return CoeffsVector(coeffsvector)+=value;
     410             : }
     411             : 
     412             : 
     413           0 : CoeffsVector& CoeffsVector::operator+=(const std::vector<double>& values) {
     414           0 :   addToValues(values);
     415           0 :   return *this;
     416             : }
     417             : 
     418             : 
     419           0 : CoeffsVector operator+(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
     420           0 :   return coeffsvector+values;
     421             : }
     422             : 
     423             : 
     424           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
     425           0 :   return CoeffsVector(coeffsvector)+=values;
     426             : }
     427             : 
     428             : 
     429           0 : CoeffsVector& CoeffsVector::operator-=(const double value) {
     430           0 :   subtractFromValues(value);
     431           0 :   return *this;
     432             : }
     433             : 
     434             : 
     435           0 : CoeffsVector operator-(const double value, const CoeffsVector& coeffsvector) {
     436           0 :   return -1.0*coeffsvector+value;
     437             : }
     438             : 
     439             : 
     440           0 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const double value) {
     441           0 :   return CoeffsVector(coeffsvector)-=value;
     442             : }
     443             : 
     444             : 
     445       22810 : CoeffsVector& CoeffsVector::operator-=(const std::vector<double>& values) {
     446       22810 :   subtractFromValues(values);
     447       22810 :   return *this;
     448             : }
     449             : 
     450             : 
     451           0 : CoeffsVector operator-(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
     452           0 :   return -1.0*coeffsvector+values;
     453             : }
     454             : 
     455             : 
     456       22810 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
     457       22810 :   return CoeffsVector(coeffsvector)-=values;
     458             : }
     459             : 
     460             : 
     461       68145 : CoeffsVector& CoeffsVector::operator+=(const CoeffsVector& other_coeffsvector) {
     462       68145 :   addToValues(other_coeffsvector);
     463       68145 :   return *this;
     464             : }
     465             : 
     466             : 
     467       22735 : CoeffsVector CoeffsVector::operator+(const CoeffsVector& other_coeffsvector) const {
     468       22735 :   return CoeffsVector(*this)+=other_coeffsvector;
     469             : }
     470             : 
     471             : 
     472       45440 : CoeffsVector& CoeffsVector::operator-=(const CoeffsVector& other_coeffsvector) {
     473       45440 :   subtractFromValues(other_coeffsvector);
     474       45440 :   return *this;
     475             : }
     476             : 
     477             : 
     478       45420 : CoeffsVector CoeffsVector::operator-(const CoeffsVector& other_coeffsvector) const {
     479       45420 :   return CoeffsVector(*this)-=other_coeffsvector;
     480             : }
     481             : 
     482             : 
     483           0 : void CoeffsVector::setValuesFromDifferentShape(const CoeffsVector& other_coeffsvector) {
     484           0 :   plumed_massert(numberOfDimensions()==other_coeffsvector.numberOfDimensions(),"both coeffs vector need to have the same dimension");
     485           0 :   for(size_t i=0; i<data.size(); i++) {
     486           0 :     std::vector<unsigned int> indices=getIndices(i);
     487           0 :     if(other_coeffsvector.indicesExist(indices)) {
     488           0 :       size_t oidx = other_coeffsvector.getIndex(indices);
     489           0 :       data[i] = other_coeffsvector.data[oidx];
     490             :     }
     491             :   }
     492           0 : }
     493             : 
     494             : 
     495           0 : void CoeffsVector::averageVectors(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
     496           0 :   plumed_massert(sameShape(coeffsvec0,coeffsvec1),"both CoeffsVector objects need to have the same shape");
     497           0 :   for(size_t i=0; i<coeffsvec0.getSize(); i++) {
     498           0 :     coeffsvec0.data[i] = coeffsvec1.data[i] = 0.5 * (coeffsvec0.data[i]+coeffsvec1.data[i]);
     499             :   }
     500           0 : }
     501             : 
     502             : 
     503           0 : void CoeffsVector::averageVectors(const std::vector<CoeffsVector*>& coeffsvecSet) {
     504           0 :   const double norm_factor = 1.0/static_cast<double>(coeffsvecSet.size());
     505           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
     506           0 :     plumed_massert(coeffsvecSet[0]->sameShape(*coeffsvecSet[k]),"All CoeffsVector objects need to have the same shape");
     507             :   }
     508           0 :   for(size_t i=0; i<coeffsvecSet[0]->getSize(); i++) {
     509             :     double value = 0.0;
     510           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
     511           0 :       value += coeffsvecSet[k]->data[i];
     512             :     }
     513           0 :     value *= norm_factor;
     514           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
     515           0 :       coeffsvecSet[k]->data[i] = value;
     516             :     }
     517             :   }
     518           0 : }
     519             : 
     520             : 
     521           0 : double CoeffsVector::getMinValue() const {
     522           0 :   size_t min_index=0;
     523           0 :   return getMinValue(min_index);
     524             : }
     525             : 
     526             : 
     527           0 : double CoeffsVector::getMinValue(size_t& min_index) const {
     528           0 :   min_index=0;
     529             :   double min_value=DBL_MAX;
     530           0 :   for(size_t i=0; i<data.size(); i++) {
     531           0 :     if(data[i]<min_value) {
     532             :       min_value=data[i];
     533           0 :       min_index=i;
     534             :     }
     535             :   }
     536           0 :   return min_value;
     537             : }
     538             : 
     539             : 
     540           0 : double CoeffsVector::getMinAbsValue() const {
     541           0 :   size_t min_index=0;
     542           0 :   return getMinAbsValue(min_index);
     543             : }
     544             : 
     545             : 
     546           0 : double CoeffsVector::getMinAbsValue(size_t& min_index) const {
     547           0 :   min_index=0;
     548             :   double min_value=DBL_MAX;
     549           0 :   for(size_t i=0; i<data.size(); i++) {
     550           0 :     if(std::abs(data[i])<min_value) {
     551             :       min_value=std::abs(data[i]);
     552           0 :       min_index=i;
     553             :     }
     554             :   }
     555           0 :   return min_value;
     556             : }
     557             : 
     558             : 
     559           0 : double CoeffsVector::getMaxValue() const {
     560           0 :   size_t max_index=0;
     561           0 :   return getMaxValue(max_index);
     562             : }
     563             : 
     564             : 
     565           0 : double CoeffsVector::getMaxValue(size_t& max_index) const {
     566           0 :   max_index=0;
     567             :   double max_value=DBL_MIN;
     568           0 :   for(size_t i=0; i<data.size(); i++) {
     569           0 :     if(data[i]>max_value) {
     570             :       max_value=data[i];
     571           0 :       max_index=i;
     572             :     }
     573             :   }
     574           0 :   return max_value;
     575             : }
     576             : 
     577             : 
     578           0 : double CoeffsVector::getMaxAbsValue() const {
     579           0 :   size_t max_index=0;
     580           0 :   return getMaxAbsValue(max_index);
     581             : }
     582             : 
     583             : 
     584          80 : double CoeffsVector::getMaxAbsValue(size_t& max_index) const {
     585          80 :   max_index=0;
     586             :   double max_value=0.0;
     587         960 :   for(size_t i=0; i<data.size(); i++) {
     588         880 :     if(std::abs(data[i])>max_value) {
     589             :       max_value=std::abs(data[i]);
     590         180 :       max_index=i;
     591             :     }
     592             :   }
     593          80 :   return max_value;
     594             : }
     595             : 
     596             : 
     597          80 : double CoeffsVector::getNorm() const {
     598          80 :   return getL2Norm();
     599             : }
     600             : 
     601             : 
     602           0 : double CoeffsVector::getL1Norm() const {
     603             :   double norm=0.0;
     604           0 :   for(size_t i=0; i<data.size(); i++) {
     605           0 :     norm+=std::abs(data[i]);
     606             :   }
     607           0 :   return norm;
     608             : }
     609             : 
     610             : 
     611          80 : double CoeffsVector::getL2Norm() const {
     612             :   double norm=0.0;
     613         960 :   for(size_t i=0; i<data.size(); i++) {
     614         880 :     norm+=data[i]*data[i];
     615             :   }
     616          80 :   norm=sqrt(norm);
     617          80 :   return norm;
     618             : }
     619             : 
     620             : 
     621           0 : double CoeffsVector::getLpNorm(const double p) const {
     622             :   double norm=0.0;
     623           0 :   for(size_t i=0; i<data.size(); i++) {
     624           0 :     norm+=pow(data[i],p);
     625             :   }
     626           0 :   norm=pow(norm,(1.0/p));
     627           0 :   return norm;
     628             : }
     629             : 
     630             : 
     631          80 : double CoeffsVector::getRMS() const {
     632          80 :   return getNorm()/sqrt(numberOfCoeffs());
     633             : }
     634             : 
     635             : 
     636           0 : void CoeffsVector::normalizeCoeffs() {
     637           0 :   double norm=getNorm();
     638           0 :   scaleAllValues(norm);
     639           0 : }
     640             : 
     641             : 
     642           0 : void CoeffsVector::randomizeValuesGaussian(int randomSeed) {
     643           0 :   Random rnd;
     644             :   if (randomSeed<0) {
     645             :     randomSeed = -randomSeed;
     646             :   }
     647           0 :   rnd.setSeed(-randomSeed);
     648           0 :   for(size_t i=0; i<data.size(); i++) {
     649           0 :     data[i]=rnd.Gaussian();
     650             :   }
     651           0 : }
     652             : 
     653             : 
     654           0 : void CoeffsVector::resetAveraging() {
     655           0 :   clear();
     656             :   resetAveragingCounter();
     657           0 : }
     658             : 
     659             : 
     660          20 : void CoeffsVector::addToAverage(const CoeffsVector& coeffsvec) {
     661          20 :   plumed_massert( data.size()==coeffsvec.getSize(), "Incorrect size");
     662             :   //
     663          20 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
     664          20 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
     665           9 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
     666             :   }
     667             :   //
     668         240 :   for(size_t i=0; i<data.size(); i++) {
     669         220 :     data[i]+=(coeffsvec.data[i]-data[i])*aver_decay;
     670             :   }
     671          20 :   averaging_counter++;
     672          20 : }
     673             : 
     674             : 
     675           1 : size_t CoeffsVector::countValues(const double value) const {
     676             :   size_t numvalues=0;
     677          12 :   for(size_t i=0; i<data.size(); i++) {
     678          11 :     if(data[i]==value) {
     679           2 :       numvalues++;
     680             :     }
     681             :   }
     682           1 :   return numvalues;
     683             : }
     684             : 
     685             : 
     686           0 : void CoeffsVector::writeToFile(const std::string& filepath, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
     687           0 :   OFile file;
     688           0 :   if(action_pntr!=NULL) {
     689           0 :     file.link(*action_pntr);
     690             :   } else {
     691           0 :     file.link(mycomm);
     692             :   }
     693           0 :   if(append_file) {
     694           0 :     file.enforceRestart();
     695             :   }
     696           0 :   file.open(filepath);
     697           0 :   writeToFile(file,print_coeffs_descriptions);
     698           0 :   file.close();
     699           0 : }
     700             : 
     701             : 
     702        1467 : void CoeffsVector::writeToFile(OFile& ofile, const bool print_coeffs_descriptions) {
     703             :   std::vector<CoeffsVector*> CoeffsSetTmp;
     704        1467 :   CoeffsSetTmp.push_back(this);
     705        1467 :   writeHeaderToFile(ofile);
     706        1467 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
     707        1467 : }
     708             : 
     709             : 
     710         881 : void CoeffsVector::writeToFile(OFile& ofile, CoeffsVector* aux_coeffsvector, const bool print_coeffs_descriptions) {
     711             :   std::vector<CoeffsVector*> CoeffsSetTmp;
     712         881 :   CoeffsSetTmp.push_back(this);
     713         881 :   CoeffsSetTmp.push_back(aux_coeffsvector);
     714         881 :   writeHeaderToFile(ofile);
     715         881 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
     716         881 : }
     717             : 
     718             : 
     719           0 : void CoeffsVector::writeToFile(const std::string& filepath, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
     720           0 :   OFile file;
     721           0 :   if(action_pntr!=NULL) {
     722           0 :     file.link(*action_pntr);
     723             :   } else {
     724           0 :     file.link(coeffsvecSet[0]->getCommunicator());
     725             :   }
     726           0 :   if(append_file) {
     727           0 :     file.enforceRestart();
     728             :   }
     729           0 :   file.open(filepath);
     730           0 :   writeToFile(file,coeffsvecSet,print_coeffs_descriptions);
     731           0 :   file.close();
     732           0 : }
     733             : 
     734             : 
     735           0 : void CoeffsVector::writeToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
     736           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
     737           0 :     plumed_massert(coeffsvecSet[k]->sameShape(*coeffsvecSet[0]),"Error in writing a set of coeffs to file: The coeffs do not have the same shape and size");
     738             :   }
     739           0 :   coeffsvecSet[0]->writeHeaderToFile(ofile);
     740           0 :   writeDataToFile(ofile,coeffsvecSet, print_coeffs_descriptions);
     741           0 : }
     742             : 
     743             : 
     744        2348 : void CoeffsVector::writeHeaderToFile(OFile& ofile) const {
     745        2348 :   ofile.clearFields();
     746        2348 :   if(isIterationCounterActive()) {
     747        2061 :     writeIterationCounterAndTimeToFile(ofile);
     748             :   }
     749        2348 :   writeCoeffsInfoToFile(ofile);
     750        2348 : }
     751             : 
     752             : 
     753        2348 : void CoeffsVector::writeDataToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
     754             :   //
     755        2348 :   std::string field_indices_prefix = "idx_";
     756        2348 :   std::string field_index = "index";
     757        2348 :   std::string field_description = "description";
     758             :   //
     759        2348 :   std::string int_fmt = "%8d";
     760        2348 :   std::string str_separate = "#!-------------------";
     761             :   //
     762        2348 :   unsigned int numvec = coeffsvecSet.size();
     763        2348 :   unsigned int numdim = coeffsvecSet[0]->numberOfDimensions();
     764             :   unsigned int numcoeffs = coeffsvecSet[0]->getSize();
     765             :   std::vector<std::string> coeffs_descriptions = coeffsvecSet[0]->getAllCoeffsDescriptions();
     766        2348 :   std::string output_fmt = coeffsvecSet[0]->getOutputFmt();
     767        2348 :   std::vector<std::string> coeffs_datalabels(numvec);
     768        5577 :   for(unsigned int k=0; k<numvec; k++) {
     769        6458 :     coeffs_datalabels[k] = coeffsvecSet[k]->getDataLabel();
     770             :   }
     771             :   //
     772        2348 :   std::vector<char> s1(20);
     773        2348 :   std::vector<unsigned int> indices(numdim);
     774        2348 :   std::vector<std::string> ilabels(numdim);
     775        5260 :   for(unsigned int k=0; k<numdim; k++) {
     776        5824 :     ilabels[k]=field_indices_prefix+coeffsvecSet[0]->getDimensionLabel(k);
     777             :   }
     778             :   //
     779       86666 :   for(size_t i=0; i<numcoeffs; i++) {
     780       84318 :     indices=coeffsvecSet[0]->getIndices(i);
     781      233206 :     for(unsigned int k=0; k<numdim; k++) {
     782      148888 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
     783      297776 :       ofile.printField(ilabels[k],s1.data());
     784             :     }
     785      203216 :     for(unsigned int l=0; l<numvec; l++) {
     786      237796 :       ofile.fmtField(" "+output_fmt).printField(coeffs_datalabels[l],coeffsvecSet[l]->getValue(i));
     787             :     }
     788             :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i);
     789       84318 :     ofile.printField(field_index,s1.data());
     790       84318 :     if(print_coeffs_descriptions) {
     791        9492 :       ofile.printField(field_description,"  "+coeffs_descriptions[i]);
     792             :     }
     793       84318 :     ofile.printField();
     794             :   }
     795        2348 :   ofile.fmtField();
     796             :   // blank line between iterations to allow proper plotting with gnuplot
     797        2348 :   ofile.printf("%s\n",str_separate.c_str());
     798        2348 :   ofile.printf("\n");
     799        2348 :   ofile.printf("\n");
     800        9392 : }
     801             : 
     802             : 
     803          75 : size_t CoeffsVector::readFromFile(IFile& ifile, const bool ignore_missing_coeffs, const bool ignore_header) {
     804          75 :   ifile.allowIgnoredFields();
     805             :   size_t ncoeffs_read=0;
     806         594 :   while(ifile) {
     807         444 :     if(!ignore_header) {
     808         370 :       readHeaderFromFile(ifile);
     809             :     }
     810         444 :     if(ifile) {
     811         409 :       ncoeffs_read=readDataFromFile(ifile,ignore_missing_coeffs);
     812             :     }
     813             :   }
     814          75 :   return ncoeffs_read;
     815             : }
     816             : 
     817             : 
     818          36 : size_t CoeffsVector::readOneSetFromFile(IFile& ifile, const bool ignore_header) {
     819          36 :   ifile.allowIgnoredFields();
     820             :   size_t ncoeffs_read=0;
     821          36 :   if(ifile) {
     822          36 :     if(!ignore_header) {
     823          36 :       readHeaderFromFile(ifile);
     824             :     }
     825          36 :     if(ifile) {
     826          33 :       ncoeffs_read=readDataFromFile(ifile,false);
     827             :     }
     828             :   }
     829          36 :   return ncoeffs_read;
     830             : }
     831             : 
     832             : 
     833          40 : size_t CoeffsVector::readFromFile(const std::string& filepath, const bool ignore_missing_coeffs, const bool ignore_header) {
     834          40 :   IFile file;
     835          40 :   file.link(mycomm);
     836          40 :   file.open(filepath);
     837          40 :   size_t ncoeffs_read=readFromFile(file,ignore_missing_coeffs, ignore_header);
     838          40 :   file.close();
     839          40 :   return ncoeffs_read;
     840          40 : }
     841             : 
     842             : 
     843         406 : void CoeffsVector::readHeaderFromFile(IFile& ifile, const bool ignore_coeffs_info) {
     844         406 :   if(ifile && isIterationCounterActive()) {
     845         406 :     getIterationCounterAndTimeFromFile(ifile);
     846             :   }
     847         406 :   if(ifile) {
     848         368 :     getCoeffsInfoFromFile(ifile,ignore_coeffs_info);
     849             :   }
     850         406 : }
     851             : 
     852             : 
     853         442 : size_t CoeffsVector::readDataFromFile(IFile& ifile, const bool ignore_missing_coeffs) {
     854             :   //
     855         442 :   std::string field_indices_prefix = "idx_";
     856             :   std::string field_coeffs = getDataLabel();
     857         442 :   std::string field_index = "index";
     858         442 :   std::string field_description = "description";
     859             :   //
     860         442 :   std::vector<std::string> ilabels(numberOfDimensions());
     861         903 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
     862         922 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
     863             :   }
     864             :   //
     865         442 :   std::vector<unsigned int> indices(numberOfDimensions());
     866         442 :   double coeff_tmp=0.0;
     867             :   std::string str_tmp;
     868             :   size_t ncoeffs_read=0;
     869             :   //
     870        5475 :   while(ifile.scanField(field_coeffs,coeff_tmp)) {
     871             :     int idx_tmp;
     872       12131 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
     873        6696 :       ifile.scanField(ilabels[k],idx_tmp);
     874        6696 :       indices[k] = static_cast<unsigned int>(idx_tmp);
     875             :     }
     876        5435 :     data[getIndex(indices)] = coeff_tmp;
     877        5435 :     ifile.scanField(field_index,idx_tmp);
     878        5435 :     if(getIndex(indices)!=static_cast<unsigned int>(idx_tmp)) {
     879             :       std::string is1;
     880           0 :       Tools::convert(idx_tmp,is1);
     881           0 :       std::string msg="ERROR: problem with indices at index " + is1 + " when reading coefficients from file";
     882           0 :       plumed_merror(msg);
     883             :     }
     884        5435 :     if(ifile.FieldExist(field_description)) {
     885         393 :       ifile.scanField(field_description,str_tmp);
     886             :     }
     887             :     //
     888        5435 :     ifile.scanField();
     889        5435 :     ncoeffs_read++;
     890        5435 :     if(ncoeffs_read==numberOfCoeffs()) {
     891         402 :       if((static_cast<unsigned int>(idx_tmp)+1)!=numberOfCoeffs()) {
     892           0 :         plumed_merror("something strange about the coefficient file that is being read in, perhaps multiple entries or missing values");
     893             :       }
     894         402 :       break;
     895             :     }
     896             :   }
     897             :   // checks on the coeffs read
     898         442 :   if(ncoeffs_read>0 &&!ignore_missing_coeffs && ncoeffs_read < numberOfCoeffs()) {
     899           0 :     plumed_merror("ERROR: missing coefficients when reading from file");
     900             :   }
     901             :   //
     902         442 :   return ncoeffs_read;
     903         442 : }
     904             : 
     905             : 
     906             : }
     907             : }

Generated by: LCOV version 1.16