Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2018 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 : data(0),
53 : averaging_counter(0),
54 : averaging_exp_decay_(0),
55 0 : mycomm(cc)
56 : {
57 0 : clear();
58 0 : }
59 :
60 :
61 294 : CoeffsVector::CoeffsVector(
62 : const std::string& label,
63 : std::vector<Value*>& args,
64 : std::vector<BasisFunctions*>& basisf,
65 : Communicator& cc,
66 294 : const bool use_iteration_counter):
67 : CoeffsBase(label,args,basisf,use_iteration_counter),
68 : data(0),
69 : averaging_counter(0),
70 : averaging_exp_decay_(0),
71 294 : mycomm(cc)
72 : {
73 294 : clear();
74 294 : }
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 : data(0),
86 : averaging_counter(0),
87 : 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 : data(0),
100 : averaging_counter(0),
101 : averaging_exp_decay_(0),
102 0 : mycomm(cc)
103 : {
104 0 : clear();
105 0 : }
106 :
107 :
108 22576 : CoeffsVector::~CoeffsVector() {}
109 :
110 :
111 1116 : void CoeffsVector::clear() {
112 2232 : data.resize(getSize());
113 74988 : for(size_t i=0; i<data.size(); i++) {
114 36936 : data[i]=0.0;
115 : }
116 1116 : }
117 :
118 :
119 0 : void CoeffsVector::setAllValuesToZero() {
120 0 : for(size_t i=0; i<data.size(); i++) {
121 0 : data[i]=0.0;
122 : }
123 0 : }
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 81 : double& CoeffsVector::operator[](const size_t index) {
178 : plumed_dbg_assert(index<data.size());
179 81 : 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 20350 : double& CoeffsVector::operator()(const size_t index) {
200 : plumed_dbg_assert(index<data.size());
201 20350 : return data[index];
202 : }
203 :
204 :
205 20350 : const double& CoeffsVector::operator()(const size_t index) const {
206 : plumed_dbg_assert(index<data.size());
207 20350 : 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 0 : void CoeffsVector::setValue(const size_t index, const double value) {
222 : plumed_dbg_assert(index<data.size());
223 0 : data[index]=value;
224 0 : }
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 1346 : void CoeffsVector::scaleAllValues(const double scalef) {
244 80426 : for(size_t i=0; i<data.size(); i++) {
245 39540 : data[i]*=scalef;
246 : }
247 1346 : }
248 :
249 :
250 1340 : CoeffsVector& CoeffsVector::operator*=(const double scalef) {
251 1340 : scaleAllValues(scalef);
252 1340 : return *this;
253 : }
254 :
255 :
256 1340 : CoeffsVector operator*(const double scalef, const CoeffsVector& coeffsvector) {
257 1340 : 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 670 : CoeffsVector& CoeffsVector::operator*=(const CoeffsVector& other_coeffsvector) {
267 670 : plumed_massert(data.size()==other_coeffsvector.getSize(),"Coeffs vectors do not have the same size");
268 40050 : for(size_t i=0; i<data.size(); i++) {
269 39380 : data[i]*=other_coeffsvector.data[i];
270 : }
271 670 : return *this;
272 : }
273 :
274 :
275 670 : CoeffsVector CoeffsVector::operator*(const CoeffsVector& other_coeffsvector) const {
276 670 : return CoeffsVector(*this)*=other_coeffsvector;
277 : }
278 :
279 :
280 158 : void CoeffsVector::setValues(const double value) {
281 12562 : for(size_t i=0; i<data.size(); i++) {
282 6202 : data[i]=value;
283 : }
284 158 : }
285 :
286 :
287 596 : void CoeffsVector::setValues(const std::vector<double>& values) {
288 596 : plumed_massert( data.size()==values.size(), "Incorrect size");
289 36792 : for(size_t i=0; i<data.size(); i++) {
290 18098 : data[i]=values[i];
291 : }
292 596 : }
293 :
294 :
295 1330 : void CoeffsVector::setValues(const CoeffsVector& other_coeffsvector) {
296 1330 : plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
297 100842 : for(size_t i=0; i<data.size(); i++) {
298 49756 : data[i]=other_coeffsvector.data[i];
299 : }
300 1330 : }
301 :
302 :
303 0 : CoeffsVector& CoeffsVector::operator=(const double value) {
304 0 : setValues(value);
305 0 : return *this;
306 : }
307 :
308 :
309 421 : CoeffsVector& CoeffsVector::operator=(const std::vector<double>& values) {
310 421 : setValues(values);
311 421 : return *this;
312 : }
313 :
314 :
315 : // CoeffsVector& CoeffsVector::operator=(const CoeffsVector& other_coeffsvector) {
316 : // setValues(other_coeffsvector);
317 : // return *this;
318 : // }
319 :
320 :
321 0 : CoeffsVector CoeffsVector::operator+() const {
322 0 : return *this;
323 : }
324 :
325 :
326 0 : CoeffsVector CoeffsVector::operator-() const {
327 0 : return CoeffsVector(*this)*=-1.0;
328 : }
329 :
330 :
331 0 : void CoeffsVector::addToValues(const double value) {
332 0 : for(size_t i=0; i<data.size(); i++) {
333 0 : data[i]+=value;
334 : }
335 0 : }
336 :
337 :
338 0 : void CoeffsVector::addToValues(const std::vector<double>& values) {
339 0 : plumed_massert( data.size()==values.size(), "Incorrect size");
340 0 : for(size_t i=0; i<data.size(); i++) {
341 0 : data[i]+=values[i];
342 : }
343 0 : }
344 :
345 :
346 2070 : void CoeffsVector::addToValues(const CoeffsVector& other_coeffsvector) {
347 2070 : plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
348 121530 : for(size_t i=0; i<data.size(); i++) {
349 119460 : data[i]+=other_coeffsvector.data[i];
350 : }
351 2070 : }
352 :
353 :
354 0 : void CoeffsVector::subtractFromValues(const double value) {
355 0 : for(size_t i=0; i<data.size(); i++) {
356 0 : data[i]-=value;
357 : }
358 0 : }
359 :
360 :
361 770 : void CoeffsVector::subtractFromValues(const std::vector<double>& values) {
362 770 : plumed_massert( data.size()==values.size(), "Incorrect size");
363 61430 : for(size_t i=0; i<data.size(); i++) {
364 60660 : data[i]-=values[i];
365 : }
366 770 : }
367 :
368 :
369 1400 : void CoeffsVector::subtractFromValues(const CoeffsVector& other_coeffsvector) {
370 1400 : plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
371 81480 : for(size_t i=0; i<data.size(); i++) {
372 80080 : data[i]-=other_coeffsvector.data[i];
373 : }
374 1400 : }
375 :
376 :
377 0 : CoeffsVector& CoeffsVector::operator+=(const double value) {
378 0 : addToValues(value);
379 0 : return *this;
380 : }
381 :
382 :
383 0 : CoeffsVector operator+(const double value, const CoeffsVector& coeffsvector) {
384 0 : return coeffsvector+value;
385 : }
386 :
387 :
388 0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const double value) {
389 0 : return CoeffsVector(coeffsvector)+=value;
390 : }
391 :
392 :
393 0 : CoeffsVector& CoeffsVector::operator+=(const std::vector<double>& values) {
394 0 : addToValues(values);
395 0 : return *this;
396 : }
397 :
398 :
399 0 : CoeffsVector operator+(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
400 0 : return coeffsvector+values;
401 : }
402 :
403 :
404 0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
405 0 : return CoeffsVector(coeffsvector)+=values;
406 : }
407 :
408 :
409 0 : CoeffsVector& CoeffsVector::operator-=(const double value) {
410 0 : subtractFromValues(value);
411 0 : return *this;
412 : }
413 :
414 :
415 0 : CoeffsVector operator-(const double value, const CoeffsVector& coeffsvector) {
416 0 : return -1.0*coeffsvector+value;
417 : }
418 :
419 :
420 0 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const double value) {
421 0 : return CoeffsVector(coeffsvector)-=value;
422 : }
423 :
424 :
425 770 : CoeffsVector& CoeffsVector::operator-=(const std::vector<double>& values) {
426 770 : subtractFromValues(values);
427 770 : return *this;
428 : }
429 :
430 :
431 0 : CoeffsVector operator-(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
432 0 : return -1.0*coeffsvector+values;
433 : }
434 :
435 :
436 770 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
437 770 : return CoeffsVector(coeffsvector)-=values;
438 : }
439 :
440 :
441 2070 : CoeffsVector& CoeffsVector::operator+=(const CoeffsVector& other_coeffsvector) {
442 2070 : addToValues(other_coeffsvector);
443 2070 : return *this;
444 : }
445 :
446 :
447 730 : CoeffsVector CoeffsVector::operator+(const CoeffsVector& other_coeffsvector) const {
448 730 : return CoeffsVector(*this)+=other_coeffsvector;
449 : }
450 :
451 :
452 1400 : CoeffsVector& CoeffsVector::operator-=(const CoeffsVector& other_coeffsvector) {
453 1400 : subtractFromValues(other_coeffsvector);
454 1400 : return *this;
455 : }
456 :
457 :
458 1400 : CoeffsVector CoeffsVector::operator-(const CoeffsVector& other_coeffsvector) const {
459 1400 : return CoeffsVector(*this)-=other_coeffsvector;
460 : }
461 :
462 :
463 0 : void CoeffsVector::setValuesFromDifferentShape(const CoeffsVector& other_coeffsvector) {
464 0 : plumed_massert(numberOfDimensions()==other_coeffsvector.numberOfDimensions(),"both coeffs vector need to have the same dimension");
465 0 : for(size_t i=0; i<data.size(); i++) {
466 0 : std::vector<unsigned int> indices=getIndices(i);
467 0 : if(other_coeffsvector.indicesExist(indices)) {
468 : size_t oidx = other_coeffsvector.getIndex(indices);
469 0 : data[i] = other_coeffsvector.data[oidx];
470 : }
471 : }
472 0 : }
473 :
474 :
475 0 : void CoeffsVector::averageVectors(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
476 0 : plumed_massert(sameShape(coeffsvec0,coeffsvec1),"both CoeffsVector objects need to have the same shape");
477 0 : for(size_t i=0; i<coeffsvec0.getSize(); i++) {
478 0 : coeffsvec0.data[i] = coeffsvec1.data[i] = 0.5 * (coeffsvec0.data[i]+coeffsvec1.data[i]);
479 : }
480 0 : }
481 :
482 :
483 0 : void CoeffsVector::averageVectors(const std::vector<CoeffsVector*>& coeffsvecSet) {
484 0 : const double norm_factor = 1.0/static_cast<double>(coeffsvecSet.size());
485 0 : for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
486 0 : plumed_massert(coeffsvecSet[0]->sameShape(*coeffsvecSet[k]),"All CoeffsVector objects need to have the same shape");
487 : }
488 0 : for(size_t i=0; i<coeffsvecSet[0]->getSize(); i++) {
489 : double value = 0.0;
490 0 : for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
491 0 : value += coeffsvecSet[k]->data[i];
492 : }
493 0 : value *= norm_factor;
494 0 : for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
495 0 : coeffsvecSet[k]->data[i] = value;
496 : }
497 : }
498 0 : }
499 :
500 :
501 0 : double CoeffsVector::getMinValue() const {
502 0 : size_t min_index=0;
503 0 : return getMinValue(min_index);
504 : }
505 :
506 :
507 0 : double CoeffsVector::getMinValue(size_t& min_index) const {
508 0 : min_index=0;
509 : double min_value=DBL_MAX;
510 0 : for(size_t i=0; i<data.size(); i++) {
511 0 : if(data[i]<min_value) {
512 : min_value=data[i];
513 0 : min_index=i;
514 : }
515 : }
516 0 : return min_value;
517 : }
518 :
519 :
520 0 : double CoeffsVector::getMinAbsValue() const {
521 0 : size_t min_index=0;
522 0 : return getMinAbsValue(min_index);
523 : }
524 :
525 :
526 0 : double CoeffsVector::getMinAbsValue(size_t& min_index) const {
527 0 : min_index=0;
528 : double min_value=DBL_MAX;
529 0 : for(size_t i=0; i<data.size(); i++) {
530 0 : if(std::abs(data[i])<min_value) {
531 : min_value=std::abs(data[i]);
532 0 : min_index=i;
533 : }
534 : }
535 0 : return min_value;
536 : }
537 :
538 :
539 0 : double CoeffsVector::getMaxValue() const {
540 0 : size_t max_index=0;
541 0 : return getMaxValue(max_index);
542 : }
543 :
544 :
545 0 : double CoeffsVector::getMaxValue(size_t& max_index) const {
546 0 : max_index=0;
547 : double max_value=DBL_MIN;
548 0 : for(size_t i=0; i<data.size(); i++) {
549 0 : if(data[i]>max_value) {
550 : max_value=data[i];
551 0 : max_index=i;
552 : }
553 : }
554 0 : return max_value;
555 : }
556 :
557 :
558 0 : double CoeffsVector::getMaxAbsValue() const {
559 0 : size_t max_index=0;
560 0 : return getMaxAbsValue(max_index);
561 : }
562 :
563 :
564 40 : double CoeffsVector::getMaxAbsValue(size_t& max_index) const {
565 40 : max_index=0;
566 : double max_value=0.0;
567 920 : for(size_t i=0; i<data.size(); i++) {
568 880 : if(std::abs(data[i])>max_value) {
569 : max_value=std::abs(data[i]);
570 86 : max_index=i;
571 : }
572 : }
573 40 : return max_value;
574 : }
575 :
576 :
577 40 : double CoeffsVector::getNorm() const {
578 40 : return getL2Norm();
579 : }
580 :
581 :
582 0 : double CoeffsVector::getL1Norm() const {
583 : double norm=0.0;
584 0 : for(size_t i=0; i<data.size(); i++) {
585 0 : norm+=std::abs(data[i]);
586 : }
587 0 : return norm;
588 : }
589 :
590 :
591 40 : double CoeffsVector::getL2Norm() const {
592 : double norm=0.0;
593 920 : for(size_t i=0; i<data.size(); i++) {
594 440 : norm+=data[i]*data[i];
595 : }
596 40 : norm=sqrt(norm);
597 40 : return norm;
598 : }
599 :
600 :
601 0 : double CoeffsVector::getLpNorm(const double p) const {
602 : double norm=0.0;
603 0 : for(size_t i=0; i<data.size(); i++) {
604 0 : norm+=pow(data[i],p);
605 : }
606 0 : norm=pow(norm,(1.0/p));
607 0 : return norm;
608 : }
609 :
610 :
611 40 : double CoeffsVector::getRMS() const {
612 80 : return getNorm()/sqrt(numberOfCoeffs());
613 : }
614 :
615 :
616 0 : void CoeffsVector::normalizeCoeffs() {
617 0 : double norm=getNorm();
618 0 : scaleAllValues(norm);
619 0 : }
620 :
621 :
622 0 : void CoeffsVector::randomizeValuesGaussian(int randomSeed) {
623 0 : Random rnd;
624 0 : if (randomSeed<0) {randomSeed = -randomSeed;}
625 0 : rnd.setSeed(-randomSeed);
626 0 : for(size_t i=0; i<data.size(); i++) {
627 0 : data[i]=rnd.Gaussian();
628 : }
629 0 : }
630 :
631 :
632 0 : void CoeffsVector::resetAveraging() {
633 0 : clear();
634 : resetAveragingCounter();
635 0 : }
636 :
637 :
638 20 : void CoeffsVector::addToAverage(const CoeffsVector& coeffsvec) {
639 20 : plumed_massert( data.size()==coeffsvec.getSize(), "Incorrect size");
640 : //
641 20 : double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
642 20 : if(averaging_exp_decay_>0 && (averaging_counter+1 > averaging_exp_decay_) ) {
643 9 : aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
644 : }
645 : //
646 460 : for(size_t i=0; i<data.size(); i++) {
647 440 : data[i]+=(coeffsvec.data[i]-data[i])*aver_decay;
648 : }
649 20 : averaging_counter++;
650 20 : }
651 :
652 :
653 1 : size_t CoeffsVector::countValues(const double value) const {
654 : size_t numvalues=0;
655 23 : for(size_t i=0; i<data.size(); i++) {
656 11 : if(data[i]==value) {
657 2 : numvalues++;
658 : }
659 : }
660 1 : return numvalues;
661 : }
662 :
663 :
664 0 : void CoeffsVector::writeToFile(const std::string& filepath, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
665 0 : OFile file;
666 0 : if(action_pntr!=NULL) {
667 0 : file.link(*action_pntr);
668 : }
669 : else {
670 0 : file.link(mycomm);
671 : }
672 0 : if(append_file) { file.enforceRestart(); }
673 0 : file.open(filepath);
674 0 : writeToFile(file,print_coeffs_descriptions);
675 0 : file.close();
676 0 : }
677 :
678 :
679 1354 : void CoeffsVector::writeToFile(OFile& ofile, const bool print_coeffs_descriptions) {
680 : std::vector<CoeffsVector*> CoeffsSetTmp;
681 2708 : CoeffsSetTmp.push_back(this);
682 1354 : writeHeaderToFile(ofile);
683 1354 : writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
684 1354 : }
685 :
686 :
687 827 : void CoeffsVector::writeToFile(OFile& ofile, CoeffsVector* aux_coeffsvector, const bool print_coeffs_descriptions) {
688 : std::vector<CoeffsVector*> CoeffsSetTmp;
689 1654 : CoeffsSetTmp.push_back(this);
690 827 : CoeffsSetTmp.push_back(aux_coeffsvector);
691 827 : writeHeaderToFile(ofile);
692 827 : writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
693 827 : }
694 :
695 :
696 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) {
697 0 : OFile file;
698 0 : if(action_pntr!=NULL) {
699 0 : file.link(*action_pntr);
700 : }
701 : else {
702 0 : file.link(coeffsvecSet[0]->getCommunicator());
703 : }
704 0 : if(append_file) { file.enforceRestart(); }
705 0 : file.open(filepath);
706 0 : writeToFile(file,coeffsvecSet,print_coeffs_descriptions);
707 0 : file.close();
708 0 : }
709 :
710 :
711 0 : void CoeffsVector::writeToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
712 0 : for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
713 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");
714 : }
715 0 : coeffsvecSet[0]->writeHeaderToFile(ofile);
716 0 : writeDataToFile(ofile,coeffsvecSet, print_coeffs_descriptions);
717 0 : }
718 :
719 :
720 2181 : void CoeffsVector::writeHeaderToFile(OFile& ofile) const {
721 2181 : ofile.clearFields();
722 2181 : if(isIterationCounterActive()) {
723 1969 : writeIterationCounterAndTimeToFile(ofile);
724 : }
725 2181 : writeCoeffsInfoToFile(ofile);
726 2181 : }
727 :
728 :
729 2181 : void CoeffsVector::writeDataToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
730 : //
731 2181 : std::string field_indices_prefix = "idx_";
732 2181 : std::string field_index = "index";
733 2181 : std::string field_description = "description";
734 : //
735 2181 : std::string int_fmt = "%8d";
736 2181 : std::string str_separate = "#!-------------------";
737 : //
738 2181 : unsigned int numvec = coeffsvecSet.size();
739 2181 : unsigned int numdim = coeffsvecSet[0]->numberOfDimensions();
740 : unsigned int numcoeffs = coeffsvecSet[0]->getSize();
741 2181 : std::vector<std::string> coeffs_descriptions = coeffsvecSet[0]->getAllCoeffsDescriptions();
742 2181 : std::string output_fmt = coeffsvecSet[0]->getOutputFmt();
743 4362 : std::vector<std::string> coeffs_datalabels(numvec);
744 8197 : for(unsigned int k=0; k<numvec; k++) {
745 12032 : coeffs_datalabels[k] = coeffsvecSet[k]->getDataLabel();
746 : }
747 : //
748 2181 : char* s1 = new char[20];
749 2181 : std::vector<unsigned int> indices(numdim);
750 4362 : std::vector<std::string> ilabels(numdim);
751 7641 : for(unsigned int k=0; k<numdim; k++) {
752 13650 : ilabels[k]=field_indices_prefix+coeffsvecSet[0]->getDimensionLabel(k);
753 : }
754 : //
755 157775 : for(size_t i=0; i<numcoeffs; i++) {
756 155594 : indices=coeffsvecSet[0]->getIndices(i);
757 352309 : for(unsigned int k=0; k<numdim; k++) {
758 274512 : sprintf(s1,int_fmt.c_str(),indices[k]);
759 411768 : ofile.printField(ilabels[k],s1);
760 : }
761 297037 : for(unsigned int l=0; l<numvec; l++) {
762 438480 : ofile.fmtField(" "+output_fmt).printField(coeffs_datalabels[l],coeffsvecSet[l]->getValue(i));
763 : }
764 155594 : sprintf(s1,int_fmt.c_str(),i); ofile.printField(field_index,s1);
765 83527 : if(print_coeffs_descriptions) { ofile.printField(field_description," "+coeffs_descriptions[i]);}
766 77797 : ofile.printField();
767 : }
768 2181 : ofile.fmtField();
769 : // blank line between iterations to allow proper plotting with gnuplot
770 2181 : ofile.printf("%s\n",str_separate.c_str());
771 2181 : ofile.printf("\n");
772 2181 : ofile.printf("\n");
773 2181 : delete [] s1;
774 2181 : }
775 :
776 :
777 73 : size_t CoeffsVector::readFromFile(IFile& ifile, const bool ignore_missing_coeffs, const bool ignore_header) {
778 73 : ifile.allowIgnoredFields();
779 : size_t ncoeffs_read=0;
780 514 : while(ifile) {
781 441 : if(!ignore_header) {readHeaderFromFile(ifile);}
782 441 : if(ifile) {
783 406 : ncoeffs_read=readDataFromFile(ifile,ignore_missing_coeffs);
784 : }
785 : }
786 73 : return ncoeffs_read;
787 : }
788 :
789 :
790 36 : size_t CoeffsVector::readOneSetFromFile(IFile& ifile, const bool ignore_header) {
791 36 : ifile.allowIgnoredFields();
792 : size_t ncoeffs_read=0;
793 36 : if(ifile) {
794 36 : if(!ignore_header) {readHeaderFromFile(ifile);}
795 36 : if(ifile) {ncoeffs_read=readDataFromFile(ifile,false);}
796 : }
797 36 : return ncoeffs_read;
798 : }
799 :
800 :
801 38 : size_t CoeffsVector::readFromFile(const std::string& filepath, const bool ignore_missing_coeffs, const bool ignore_header) {
802 76 : IFile file;
803 38 : file.link(mycomm);
804 38 : file.open(filepath);
805 38 : size_t ncoeffs_read=readFromFile(file,ignore_missing_coeffs, ignore_header);
806 38 : file.close();
807 38 : return ncoeffs_read;
808 : }
809 :
810 :
811 406 : void CoeffsVector::readHeaderFromFile(IFile& ifile, const bool ignore_coeffs_info) {
812 812 : if(ifile && isIterationCounterActive()) {
813 406 : getIterationCounterAndTimeFromFile(ifile);
814 : }
815 406 : if(ifile) {
816 368 : getCoeffsInfoFromFile(ifile,ignore_coeffs_info);
817 : }
818 406 : }
819 :
820 :
821 439 : size_t CoeffsVector::readDataFromFile(IFile& ifile, const bool ignore_missing_coeffs) {
822 : //
823 439 : std::string field_indices_prefix = "idx_";
824 : std::string field_coeffs = getDataLabel();
825 439 : std::string field_index = "index";
826 439 : std::string field_description = "description";
827 : //
828 878 : std::vector<std::string> ilabels(numberOfDimensions());
829 1353 : for(unsigned int k=0; k<numberOfDimensions(); k++) {
830 1828 : ilabels[k]=field_indices_prefix+getDimensionLabel(k);
831 : }
832 : //
833 439 : std::vector<unsigned int> indices(numberOfDimensions());
834 439 : double coeff_tmp=0.0;
835 : std::string str_tmp;
836 : size_t ncoeffs_read=0;
837 : //
838 10463 : while(ifile.scanField(field_coeffs,coeff_tmp)) {
839 : int idx_tmp;
840 18739 : for(unsigned int k=0; k<numberOfDimensions(); k++) {
841 13326 : ifile.scanField(ilabels[k],idx_tmp);
842 13326 : indices[k] = static_cast<unsigned int>(idx_tmp);
843 : }
844 5413 : data[getIndex(indices)] = coeff_tmp;
845 5413 : ifile.scanField(field_index,idx_tmp);
846 5413 : if(getIndex(indices)!=static_cast<unsigned int>(idx_tmp)) {
847 0 : std::string is1; Tools::convert(idx_tmp,is1);
848 0 : std::string msg="ERROR: problem with indices at index " + is1 + " when reading coefficients from file";
849 0 : plumed_merror(msg);
850 : }
851 5413 : if(ifile.FieldExist(field_description)) { ifile.scanField(field_description,str_tmp); }
852 : //
853 5413 : ifile.scanField();
854 5413 : ncoeffs_read++;
855 5413 : if(ncoeffs_read==numberOfCoeffs()) {
856 401 : if((static_cast<unsigned int>(idx_tmp)+1)!=numberOfCoeffs()) {
857 0 : plumed_merror("something strange about the coefficent file that is being read in, perhaps multiple entries or missing values");
858 : }
859 401 : break;
860 : }
861 : }
862 : // checks on the coeffs read
863 807 : if(ncoeffs_read>0 &&!ignore_missing_coeffs && ncoeffs_read < numberOfCoeffs()) {
864 0 : plumed_merror("ERROR: missing coefficients when reading from file");
865 : }
866 : //
867 439 : return ncoeffs_read;
868 : }
869 :
870 :
871 : }
872 4839 : }
|