LCOV - code coverage report
Current view: top level - ves - CoeffsVector.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 239 468 51.1 %
Date: 2026-11-05 10:19:04 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         378 : CoeffsVector::CoeffsVector(
      61             :   const std::string& label,
      62             :   const std::vector<Value*>& args,
      63             :   std::vector<BasisFunctions*>& basisf,
      64             :   Communicator& cc,
      65         378 :   const bool use_iteration_counter):
      66             :   CoeffsBase(label,args,basisf,use_iteration_counter),
      67         378 :   data(0),
      68         378 :   averaging_counter(0),
      69         378 :   averaging_exp_decay_(0),
      70         378 :   mycomm(cc) {
      71         378 :   clear();
      72         378 : }
      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      341966 : CoeffsVector::~CoeffsVector() {}
     105             : 
     106             : 
     107       23210 : void CoeffsVector::clear() {
     108       23210 :   data.resize(getSize());
     109     1833424 :   for(size_t i=0; i<data.size(); i++) {
     110     1810214 :     data[i]=0.0;
     111             :   }
     112       23210 : }
     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         175 : void CoeffsVector::setValues(const double value) {
     301        8407 :   for(size_t i=0; i<data.size(); i++) {
     302        8232 :     data[i]=value;
     303             :   }
     304         175 : }
     305             : 
     306             : 
     307         701 : void CoeffsVector::setValues(const std::vector<double>& values) {
     308         701 :   plumed_massert( data.size()==values.size(), "Incorrect size");
     309       23138 :   for(size_t i=0; i<data.size(); i++) {
     310       22437 :     data[i]=values[i];
     311             :   }
     312         701 : }
     313             : 
     314             : 
     315       23411 : void CoeffsVector::setValues(const CoeffsVector& other_coeffsvector) {
     316       23411 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
     317     1847409 :   for(size_t i=0; i<data.size(); i++) {
     318     1823998 :     data[i]=other_coeffsvector.data[i];
     319             :   }
     320       23411 : }
     321             : 
     322             : 
     323           0 : CoeffsVector& CoeffsVector::operator=(const double value) {
     324           0 :   setValues(value);
     325           0 :   return *this;
     326             : }
     327             : 
     328             : 
     329         454 : CoeffsVector& CoeffsVector::operator=(const std::vector<double>& values) {
     330         454 :   setValues(values);
     331         454 :   return *this;
     332             : }
     333             : 
     334             : 
     335             : 
     336             : 
     337           0 : CoeffsVector CoeffsVector::operator+() const {
     338           0 :   return *this;
     339             : }
     340             : 
     341             : 
     342           0 : CoeffsVector CoeffsVector::operator-() const {
     343           0 :   return CoeffsVector(*this)*=-1.0;
     344             : }
     345             : 
     346             : 
     347           0 : void CoeffsVector::addToValues(const double value) {
     348           0 :   for(size_t i=0; i<data.size(); i++) {
     349           0 :     data[i]+=value;
     350             :   }
     351           0 : }
     352             : 
     353             : 
     354           0 : void CoeffsVector::addToValues(const std::vector<double>& values) {
     355           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
     356           0 :   for(size_t i=0; i<data.size(); i++) {
     357           0 :     data[i]+=values[i];
     358             :   }
     359           0 : }
     360             : 
     361             : 
     362       68145 : void CoeffsVector::addToValues(const CoeffsVector& other_coeffsvector) {
     363       68145 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
     364     5438520 :   for(size_t i=0; i<data.size(); i++) {
     365     5370375 :     data[i]+=other_coeffsvector.data[i];
     366             :   }
     367       68145 : }
     368             : 
     369             : 
     370           0 : void CoeffsVector::subtractFromValues(const double value) {
     371           0 :   for(size_t i=0; i<data.size(); i++) {
     372           0 :     data[i]-=value;
     373             :   }
     374           0 : }
     375             : 
     376             : 
     377       22810 : void CoeffsVector::subtractFromValues(const std::vector<double>& values) {
     378       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
     379     1823850 :   for(size_t i=0; i<data.size(); i++) {
     380     1801040 :     data[i]-=values[i];
     381             :   }
     382       22810 : }
     383             : 
     384             : 
     385       45440 : void CoeffsVector::subtractFromValues(const CoeffsVector& other_coeffsvector) {
     386       45440 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
     387     3625800 :   for(size_t i=0; i<data.size(); i++) {
     388     3580360 :     data[i]-=other_coeffsvector.data[i];
     389             :   }
     390       45440 : }
     391             : 
     392             : 
     393           0 : CoeffsVector& CoeffsVector::operator+=(const double value) {
     394           0 :   addToValues(value);
     395           0 :   return *this;
     396             : }
     397             : 
     398             : 
     399           0 : CoeffsVector operator+(const double value, const CoeffsVector& coeffsvector) {
     400           0 :   return coeffsvector+value;
     401             : }
     402             : 
     403             : 
     404           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const double value) {
     405           0 :   return CoeffsVector(coeffsvector)+=value;
     406             : }
     407             : 
     408             : 
     409           0 : CoeffsVector& CoeffsVector::operator+=(const std::vector<double>& values) {
     410           0 :   addToValues(values);
     411           0 :   return *this;
     412             : }
     413             : 
     414             : 
     415           0 : CoeffsVector operator+(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
     416           0 :   return coeffsvector+values;
     417             : }
     418             : 
     419             : 
     420           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
     421           0 :   return CoeffsVector(coeffsvector)+=values;
     422             : }
     423             : 
     424             : 
     425           0 : CoeffsVector& CoeffsVector::operator-=(const double value) {
     426           0 :   subtractFromValues(value);
     427           0 :   return *this;
     428             : }
     429             : 
     430             : 
     431           0 : CoeffsVector operator-(const double value, const CoeffsVector& coeffsvector) {
     432           0 :   return -1.0*coeffsvector+value;
     433             : }
     434             : 
     435             : 
     436           0 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const double value) {
     437           0 :   return CoeffsVector(coeffsvector)-=value;
     438             : }
     439             : 
     440             : 
     441       22810 : CoeffsVector& CoeffsVector::operator-=(const std::vector<double>& values) {
     442       22810 :   subtractFromValues(values);
     443       22810 :   return *this;
     444             : }
     445             : 
     446             : 
     447           0 : CoeffsVector operator-(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
     448           0 :   return -1.0*coeffsvector+values;
     449             : }
     450             : 
     451             : 
     452       22810 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
     453       22810 :   return CoeffsVector(coeffsvector)-=values;
     454             : }
     455             : 
     456             : 
     457       68145 : CoeffsVector& CoeffsVector::operator+=(const CoeffsVector& other_coeffsvector) {
     458       68145 :   addToValues(other_coeffsvector);
     459       68145 :   return *this;
     460             : }
     461             : 
     462             : 
     463       22735 : CoeffsVector CoeffsVector::operator+(const CoeffsVector& other_coeffsvector) const {
     464       22735 :   return CoeffsVector(*this)+=other_coeffsvector;
     465             : }
     466             : 
     467             : 
     468       45440 : CoeffsVector& CoeffsVector::operator-=(const CoeffsVector& other_coeffsvector) {
     469       45440 :   subtractFromValues(other_coeffsvector);
     470       45440 :   return *this;
     471             : }
     472             : 
     473             : 
     474       45420 : CoeffsVector CoeffsVector::operator-(const CoeffsVector& other_coeffsvector) const {
     475       45420 :   return CoeffsVector(*this)-=other_coeffsvector;
     476             : }
     477             : 
     478             : 
     479           0 : void CoeffsVector::setValuesFromDifferentShape(const CoeffsVector& other_coeffsvector) {
     480           0 :   plumed_massert(numberOfDimensions()==other_coeffsvector.numberOfDimensions(),"both coeffs vector need to have the same dimension");
     481           0 :   for(size_t i=0; i<data.size(); i++) {
     482           0 :     std::vector<unsigned int> indices=getIndices(i);
     483           0 :     if(other_coeffsvector.indicesExist(indices)) {
     484           0 :       size_t oidx = other_coeffsvector.getIndex(indices);
     485           0 :       data[i] = other_coeffsvector.data[oidx];
     486             :     }
     487             :   }
     488           0 : }
     489             : 
     490             : 
     491           0 : void CoeffsVector::averageVectors(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
     492           0 :   plumed_massert(sameShape(coeffsvec0,coeffsvec1),"both CoeffsVector objects need to have the same shape");
     493           0 :   for(size_t i=0; i<coeffsvec0.getSize(); i++) {
     494           0 :     coeffsvec0.data[i] = coeffsvec1.data[i] = 0.5 * (coeffsvec0.data[i]+coeffsvec1.data[i]);
     495             :   }
     496           0 : }
     497             : 
     498             : 
     499           0 : void CoeffsVector::averageVectors(const std::vector<CoeffsVector*>& coeffsvecSet) {
     500           0 :   const double norm_factor = 1.0/static_cast<double>(coeffsvecSet.size());
     501           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
     502           0 :     plumed_massert(coeffsvecSet[0]->sameShape(*coeffsvecSet[k]),"All CoeffsVector objects need to have the same shape");
     503             :   }
     504           0 :   for(size_t i=0; i<coeffsvecSet[0]->getSize(); i++) {
     505             :     double value = 0.0;
     506           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
     507           0 :       value += coeffsvecSet[k]->data[i];
     508             :     }
     509           0 :     value *= norm_factor;
     510           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
     511           0 :       coeffsvecSet[k]->data[i] = value;
     512             :     }
     513             :   }
     514           0 : }
     515             : 
     516             : 
     517           0 : double CoeffsVector::getMinValue() const {
     518           0 :   size_t min_index=0;
     519           0 :   return getMinValue(min_index);
     520             : }
     521             : 
     522             : 
     523           0 : double CoeffsVector::getMinValue(size_t& min_index) const {
     524           0 :   min_index=0;
     525             :   double min_value=DBL_MAX;
     526           0 :   for(size_t i=0; i<data.size(); i++) {
     527           0 :     if(data[i]<min_value) {
     528             :       min_value=data[i];
     529           0 :       min_index=i;
     530             :     }
     531             :   }
     532           0 :   return min_value;
     533             : }
     534             : 
     535             : 
     536           0 : double CoeffsVector::getMinAbsValue() const {
     537           0 :   size_t min_index=0;
     538           0 :   return getMinAbsValue(min_index);
     539             : }
     540             : 
     541             : 
     542           0 : double CoeffsVector::getMinAbsValue(size_t& min_index) const {
     543           0 :   min_index=0;
     544             :   double min_value=DBL_MAX;
     545           0 :   for(size_t i=0; i<data.size(); i++) {
     546           0 :     if(std::abs(data[i])<min_value) {
     547             :       min_value=std::abs(data[i]);
     548           0 :       min_index=i;
     549             :     }
     550             :   }
     551           0 :   return min_value;
     552             : }
     553             : 
     554             : 
     555           0 : double CoeffsVector::getMaxValue() const {
     556           0 :   size_t max_index=0;
     557           0 :   return getMaxValue(max_index);
     558             : }
     559             : 
     560             : 
     561           0 : double CoeffsVector::getMaxValue(size_t& max_index) const {
     562           0 :   max_index=0;
     563             :   double max_value=DBL_MIN;
     564           0 :   for(size_t i=0; i<data.size(); i++) {
     565           0 :     if(data[i]>max_value) {
     566             :       max_value=data[i];
     567           0 :       max_index=i;
     568             :     }
     569             :   }
     570           0 :   return max_value;
     571             : }
     572             : 
     573             : 
     574           0 : double CoeffsVector::getMaxAbsValue() const {
     575           0 :   size_t max_index=0;
     576           0 :   return getMaxAbsValue(max_index);
     577             : }
     578             : 
     579             : 
     580          80 : double CoeffsVector::getMaxAbsValue(size_t& max_index) const {
     581          80 :   max_index=0;
     582             :   double max_value=0.0;
     583         960 :   for(size_t i=0; i<data.size(); i++) {
     584         880 :     if(std::abs(data[i])>max_value) {
     585             :       max_value=std::abs(data[i]);
     586         180 :       max_index=i;
     587             :     }
     588             :   }
     589          80 :   return max_value;
     590             : }
     591             : 
     592             : 
     593          80 : double CoeffsVector::getNorm() const {
     594          80 :   return getL2Norm();
     595             : }
     596             : 
     597             : 
     598           0 : double CoeffsVector::getL1Norm() const {
     599             :   double norm=0.0;
     600           0 :   for(size_t i=0; i<data.size(); i++) {
     601           0 :     norm+=std::abs(data[i]);
     602             :   }
     603           0 :   return norm;
     604             : }
     605             : 
     606             : 
     607          80 : double CoeffsVector::getL2Norm() const {
     608             :   double norm=0.0;
     609         960 :   for(size_t i=0; i<data.size(); i++) {
     610         880 :     norm+=data[i]*data[i];
     611             :   }
     612          80 :   norm=sqrt(norm);
     613          80 :   return norm;
     614             : }
     615             : 
     616             : 
     617           0 : double CoeffsVector::getLpNorm(const double p) const {
     618             :   double norm=0.0;
     619           0 :   for(size_t i=0; i<data.size(); i++) {
     620           0 :     norm+=pow(data[i],p);
     621             :   }
     622           0 :   norm=pow(norm,(1.0/p));
     623           0 :   return norm;
     624             : }
     625             : 
     626             : 
     627          80 : double CoeffsVector::getRMS() const {
     628          80 :   return getNorm()/sqrt(numberOfCoeffs());
     629             : }
     630             : 
     631             : 
     632           0 : void CoeffsVector::normalizeCoeffs() {
     633           0 :   double norm=getNorm();
     634           0 :   scaleAllValues(norm);
     635           0 : }
     636             : 
     637             : 
     638           0 : void CoeffsVector::randomizeValuesGaussian(int randomSeed) {
     639           0 :   Random rnd;
     640           0 :   if (randomSeed<0) {
     641             :     randomSeed = -randomSeed;
     642             :   }
     643           0 :   rnd.setSeed(-randomSeed);
     644           0 :   for(size_t i=0; i<data.size(); i++) {
     645           0 :     data[i]=rnd.Gaussian();
     646             :   }
     647           0 : }
     648             : 
     649             : 
     650           0 : void CoeffsVector::resetAveraging() {
     651           0 :   clear();
     652             :   resetAveragingCounter();
     653           0 : }
     654             : 
     655             : 
     656          20 : void CoeffsVector::addToAverage(const CoeffsVector& coeffsvec) {
     657          20 :   plumed_massert( data.size()==coeffsvec.getSize(), "Incorrect size");
     658             :   //
     659          20 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
     660          20 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
     661           9 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
     662             :   }
     663             :   //
     664         240 :   for(size_t i=0; i<data.size(); i++) {
     665         220 :     data[i]+=(coeffsvec.data[i]-data[i])*aver_decay;
     666             :   }
     667          20 :   averaging_counter++;
     668          20 : }
     669             : 
     670             : 
     671           1 : size_t CoeffsVector::countValues(const double value) const {
     672             :   size_t numvalues=0;
     673          12 :   for(size_t i=0; i<data.size(); i++) {
     674          11 :     if(data[i]==value) {
     675           2 :       numvalues++;
     676             :     }
     677             :   }
     678           1 :   return numvalues;
     679             : }
     680             : 
     681             : 
     682           0 : void CoeffsVector::writeToFile(const std::string& filepath, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
     683           0 :   OFile file;
     684           0 :   if(action_pntr!=NULL) {
     685           0 :     file.link(*action_pntr);
     686             :   } else {
     687           0 :     file.link(mycomm);
     688             :   }
     689           0 :   if(append_file) {
     690           0 :     file.enforceRestart();
     691             :   }
     692           0 :   file.open(filepath);
     693           0 :   writeToFile(file,print_coeffs_descriptions);
     694           0 :   file.close();
     695           0 : }
     696             : 
     697             : 
     698        1467 : void CoeffsVector::writeToFile(OFile& ofile, const bool print_coeffs_descriptions) {
     699        1467 :   std::vector<CoeffsVector*> CoeffsSetTmp;
     700        1467 :   CoeffsSetTmp.push_back(this);
     701        1467 :   writeHeaderToFile(ofile);
     702        1467 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
     703        1467 : }
     704             : 
     705             : 
     706         881 : void CoeffsVector::writeToFile(OFile& ofile, CoeffsVector* aux_coeffsvector, const bool print_coeffs_descriptions) {
     707         881 :   std::vector<CoeffsVector*> CoeffsSetTmp;
     708         881 :   CoeffsSetTmp.push_back(this);
     709         881 :   CoeffsSetTmp.push_back(aux_coeffsvector);
     710         881 :   writeHeaderToFile(ofile);
     711         881 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
     712         881 : }
     713             : 
     714             : 
     715           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) {
     716           0 :   OFile file;
     717           0 :   if(action_pntr!=NULL) {
     718           0 :     file.link(*action_pntr);
     719             :   } else {
     720           0 :     file.link(coeffsvecSet[0]->getCommunicator());
     721             :   }
     722           0 :   if(append_file) {
     723           0 :     file.enforceRestart();
     724             :   }
     725           0 :   file.open(filepath);
     726           0 :   writeToFile(file,coeffsvecSet,print_coeffs_descriptions);
     727           0 :   file.close();
     728           0 : }
     729             : 
     730             : 
     731           0 : void CoeffsVector::writeToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
     732           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
     733           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");
     734             :   }
     735           0 :   coeffsvecSet[0]->writeHeaderToFile(ofile);
     736           0 :   writeDataToFile(ofile,coeffsvecSet, print_coeffs_descriptions);
     737           0 : }
     738             : 
     739             : 
     740        2348 : void CoeffsVector::writeHeaderToFile(OFile& ofile) const {
     741        2348 :   ofile.clearFields();
     742        2348 :   if(isIterationCounterActive()) {
     743        2061 :     writeIterationCounterAndTimeToFile(ofile);
     744             :   }
     745        2348 :   writeCoeffsInfoToFile(ofile);
     746        2348 : }
     747             : 
     748             : 
     749        2348 : void CoeffsVector::writeDataToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
     750             :   //
     751        2348 :   std::string field_indices_prefix = "idx_";
     752        2348 :   std::string field_index = "index";
     753        2348 :   std::string field_description = "description";
     754             :   //
     755        2348 :   std::string int_fmt = "%8d";
     756        2348 :   std::string str_separate = "#!-------------------";
     757             :   //
     758        2348 :   unsigned int numvec = coeffsvecSet.size();
     759        2348 :   unsigned int numdim = coeffsvecSet[0]->numberOfDimensions();
     760             :   unsigned int numcoeffs = coeffsvecSet[0]->getSize();
     761             :   std::vector<std::string> coeffs_descriptions = coeffsvecSet[0]->getAllCoeffsDescriptions();
     762        2348 :   std::string output_fmt = coeffsvecSet[0]->getOutputFmt();
     763        2348 :   std::vector<std::string> coeffs_datalabels(numvec);
     764        5577 :   for(unsigned int k=0; k<numvec; k++) {
     765        6458 :     coeffs_datalabels[k] = coeffsvecSet[k]->getDataLabel();
     766             :   }
     767             :   //
     768        2348 :   std::vector<char> s1(20);
     769        2348 :   std::vector<unsigned int> indices(numdim);
     770        2348 :   std::vector<std::string> ilabels(numdim);
     771        5260 :   for(unsigned int k=0; k<numdim; k++) {
     772        5824 :     ilabels[k]=field_indices_prefix+coeffsvecSet[0]->getDimensionLabel(k);
     773             :   }
     774             :   //
     775       86666 :   for(size_t i=0; i<numcoeffs; i++) {
     776       84318 :     indices=coeffsvecSet[0]->getIndices(i);
     777      233206 :     for(unsigned int k=0; k<numdim; k++) {
     778      148888 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
     779      297776 :       ofile.printField(ilabels[k],s1.data());
     780             :     }
     781      203216 :     for(unsigned int l=0; l<numvec; l++) {
     782      237796 :       ofile.fmtField(" "+output_fmt).printField(coeffs_datalabels[l],coeffsvecSet[l]->getValue(i));
     783             :     }
     784             :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i);
     785       84318 :     ofile.printField(field_index,s1.data());
     786       84318 :     if(print_coeffs_descriptions) {
     787        9492 :       ofile.printField(field_description,"  "+coeffs_descriptions[i]);
     788             :     }
     789       84318 :     ofile.printField();
     790             :   }
     791        2348 :   ofile.fmtField();
     792             :   // blank line between iterations to allow proper plotting with gnuplot
     793        2348 :   ofile.printf("%s\n",str_separate.c_str());
     794        2348 :   ofile.printf("\n");
     795        2348 :   ofile.printf("\n");
     796        9392 : }
     797             : 
     798             : 
     799          76 : size_t CoeffsVector::readFromFile(IFile& ifile, const bool ignore_missing_coeffs, const bool ignore_header) {
     800          76 :   ifile.allowIgnoredFields();
     801             :   size_t ncoeffs_read=0;
     802         598 :   while(ifile) {
     803         446 :     if(!ignore_header) {
     804         372 :       readHeaderFromFile(ifile);
     805             :     }
     806         446 :     if(ifile) {
     807         410 :       ncoeffs_read=readDataFromFile(ifile,ignore_missing_coeffs);
     808             :     }
     809             :   }
     810          76 :   return ncoeffs_read;
     811             : }
     812             : 
     813             : 
     814          36 : size_t CoeffsVector::readOneSetFromFile(IFile& ifile, const bool ignore_header) {
     815          36 :   ifile.allowIgnoredFields();
     816             :   size_t ncoeffs_read=0;
     817          36 :   if(ifile) {
     818          36 :     if(!ignore_header) {
     819          36 :       readHeaderFromFile(ifile);
     820             :     }
     821          36 :     if(ifile) {
     822          33 :       ncoeffs_read=readDataFromFile(ifile,false);
     823             :     }
     824             :   }
     825          36 :   return ncoeffs_read;
     826             : }
     827             : 
     828             : 
     829          40 : size_t CoeffsVector::readFromFile(const std::string& filepath, const bool ignore_missing_coeffs, const bool ignore_header) {
     830          40 :   IFile file;
     831          40 :   file.link(mycomm);
     832          40 :   file.open(filepath);
     833          40 :   size_t ncoeffs_read=readFromFile(file,ignore_missing_coeffs, ignore_header);
     834          40 :   file.close();
     835          40 :   return ncoeffs_read;
     836          40 : }
     837             : 
     838             : 
     839         408 : void CoeffsVector::readHeaderFromFile(IFile& ifile, const bool ignore_coeffs_info) {
     840         408 :   if(ifile && isIterationCounterActive()) {
     841         408 :     getIterationCounterAndTimeFromFile(ifile);
     842             :   }
     843         408 :   if(ifile) {
     844         369 :     getCoeffsInfoFromFile(ifile,ignore_coeffs_info);
     845             :   }
     846         408 : }
     847             : 
     848             : 
     849         443 : size_t CoeffsVector::readDataFromFile(IFile& ifile, const bool ignore_missing_coeffs) {
     850             :   //
     851         443 :   std::string field_indices_prefix = "idx_";
     852             :   std::string field_coeffs = getDataLabel();
     853         443 :   std::string field_index = "index";
     854         443 :   std::string field_description = "description";
     855             :   //
     856         443 :   std::vector<std::string> ilabels(numberOfDimensions());
     857         905 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
     858         924 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
     859             :   }
     860             :   //
     861         443 :   std::vector<unsigned int> indices(numberOfDimensions());
     862         443 :   double coeff_tmp=0.0;
     863             :   std::string str_tmp;
     864             :   size_t ncoeffs_read=0;
     865             :   //
     866        5479 :   while(ifile.scanField(field_coeffs,coeff_tmp)) {
     867             :     int idx_tmp;
     868       12139 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
     869        6700 :       ifile.scanField(ilabels[k],idx_tmp);
     870        6700 :       indices[k] = static_cast<unsigned int>(idx_tmp);
     871             :     }
     872        5439 :     data[getIndex(indices)] = coeff_tmp;
     873        5439 :     ifile.scanField(field_index,idx_tmp);
     874        5439 :     if(getIndex(indices)!=static_cast<unsigned int>(idx_tmp)) {
     875             :       std::string is1;
     876           0 :       Tools::convert(idx_tmp,is1);
     877           0 :       std::string msg="ERROR: problem with indices at index " + is1 + " when reading coefficients from file";
     878           0 :       plumed_merror(msg);
     879             :     }
     880        5439 :     if(ifile.FieldExist(field_description)) {
     881         393 :       ifile.scanField(field_description,str_tmp);
     882             :     }
     883             :     //
     884        5439 :     ifile.scanField();
     885        5439 :     ncoeffs_read++;
     886        5439 :     if(ncoeffs_read==numberOfCoeffs()) {
     887         403 :       if((static_cast<unsigned int>(idx_tmp)+1)!=numberOfCoeffs()) {
     888           0 :         plumed_merror("something strange about the coefficient file that is being read in, perhaps multiple entries or missing values");
     889             :       }
     890         403 :       break;
     891             :     }
     892             :   }
     893             :   // checks on the coeffs read
     894         443 :   if(ncoeffs_read>0 &&!ignore_missing_coeffs && ncoeffs_read < numberOfCoeffs()) {
     895           0 :     plumed_merror("ERROR: missing coefficients when reading from file");
     896             :   }
     897             :   //
     898         443 :   return ncoeffs_read;
     899         443 : }
     900             : 
     901             : 
     902             : }
     903             : }

Generated by: LCOV version 1.16