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 : }
|