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