6
6
#include < algorithm>
7
7
#include < vector>
8
8
#include < random>
9
+ #include < stdexcept>
9
10
10
11
11
12
// --- Integrate
12
13
13
- void MCI::integrate (const long &Nmc, double * average, double * error, bool findMRT2step, bool initialdecorrelation)
14
+ void MCI::integrate (const long &Nmc, double * average, double * error, bool findMRT2step, bool initialdecorrelation, size_t nblocks )
14
15
{
15
- long i;
16
+ MCI::integrate (Nmc, average, error, findMRT2step ? -1 : 0 , initialdecorrelation ? -1 : 0 , nblocks);
17
+ }
18
+
19
+ void MCI::integrate (const long &Nmc, double * average, double * error, int NfindMRT2stepIterations, int NdecorrelationSteps, size_t nblocks)
20
+ {
21
+ long i,j;
22
+ const bool fixedBlocks = (nblocks>0 );
23
+ const long stepsPerBlock = fixedBlocks ? Nmc/nblocks : 1 ;
24
+ const long trueNmc = fixedBlocks ? stepsPerBlock*nblocks : Nmc;
25
+ const long ndatax = fixedBlocks ? nblocks : Nmc;
16
26
17
27
if ( _flagpdf )
18
28
{
19
29
// find the optimal mrt2 step
20
- if (findMRT2step) this ->findMRT2Step ();
30
+ this ->findMRT2Step (NfindMRT2stepIterations );
21
31
// take care to do the initial decorrelation of the walker
22
- if (initialdecorrelation) this ->initialDecorrelation ();
32
+ this ->initialDecorrelation (NdecorrelationSteps );
23
33
}
24
34
25
35
// allocation of the array where the data will be stored
26
- _datax = new double *[Nmc ];
27
- for (i=0 ; i<Nmc ; ++i){ *(_datax+i) = new double [_nobsdim]; }
36
+ _datax = new double *[ndatax ];
37
+ for (i=0 ; i<ndatax ; ++i) { *(_datax+i) = new double [_nobsdim]; }
28
38
29
39
// sample the observables
30
40
if (_flagobsfile) _obsfile.open (_pathobsfile);
31
41
if (_flagwlkfile) _wlkfile.open (_pathwlkfile);
32
42
_flagMC = true ;
33
- this ->sample (Nmc , true );
43
+ this ->sample (trueNmc , true , stepsPerBlock );
34
44
_flagMC = false ;
35
45
if (_flagobsfile) _obsfile.close ();
36
46
if (_flagwlkfile) _wlkfile.close ();
37
47
48
+ // reduce block averages
49
+ if (fixedBlocks) {
50
+ const double fac = 1 ./stepsPerBlock;
51
+ for (i=0 ; i<ndatax; ++i) {
52
+ for (j=0 ; j<_nobsdim; ++j) {
53
+ *(*(_datax+i)+j) *= fac;
54
+ }
55
+ }
56
+ }
57
+
38
58
// estimate average and standard deviation
39
- if ( _flagpdf )
59
+ if ( _flagpdf && !fixedBlocks )
40
60
{
41
- mci::MultiDimCorrelatedEstimator (Nmc , _nobsdim, _datax, average, error);
61
+ mci::MultiDimCorrelatedEstimator (ndatax , _nobsdim, _datax, average, error);
42
62
}
43
63
else
44
64
{
45
- mci::MultiDimUncorrelatedEstimator (Nmc, _nobsdim, _datax, average, error);
46
- for (i=0 ; i<_nobsdim; ++i)
47
- {
48
- *(average+i) *=_vol; *(error+i) *=_vol;
65
+ mci::MultiDimUncorrelatedEstimator (ndatax, _nobsdim, _datax, average, error);
66
+ if (!_flagpdf) {
67
+ for (i=0 ; i<_nobsdim; ++i) {
68
+ *(average+i) *=_vol;
69
+ *(error+i) *=_vol;
49
70
}
71
+ }
50
72
}
51
73
52
74
// deallocation of the data array
53
- for (int i=0 ; i<Nmc ; ++i){ delete [] *(_datax+i); }
75
+ for (int i=0 ; i<ndatax ; ++i){ delete [] *(_datax+i); }
54
76
delete [] _datax;
55
77
}
56
78
@@ -64,10 +86,12 @@ void MCI::storeObservables()
64
86
if ( _ridx%_freqobsfile == 0 )
65
87
{
66
88
_obsfile << _ridx;
67
- for (int j=0 ; j<_nobsdim; ++j)
89
+ for (size_t i=0 ; i<_obs.size (); ++i) {
90
+ for (int j=0 ; j<_obs[i]->getNObs (); ++j)
68
91
{
69
- _obsfile << " " << *(*(_datax+_ridx)+j) ;
92
+ _obsfile << " " << _obs[i]-> getObservable (j) ;
70
93
}
94
+ }
71
95
_obsfile << std::endl;
72
96
}
73
97
}
@@ -87,52 +111,72 @@ void MCI::storeWalkerPositions()
87
111
}
88
112
89
113
90
- void MCI::initialDecorrelation ()
114
+ void MCI::initialDecorrelation (const int &NdecorrelationSteps )
91
115
{
92
- long i;
93
- // constants
94
- const long MIN_NMC=100 ;
95
- // allocate the data array that will be used
96
- _datax = new double *[MIN_NMC];
97
- for (i=0 ; i<MIN_NMC; ++i) {*(_datax+i) = new double [_nobsdim]; }
98
- // do a first estimate of the observables
99
- this ->sample (MIN_NMC, true );
100
- double * oldestimate = new double [_nobsdim];
101
- double * olderrestim = new double [_nobsdim];
102
- mci::MultiDimCorrelatedEstimator (MIN_NMC, _nobsdim, _datax, oldestimate, olderrestim);
103
- // start a loop which will stop when the observables are stabilized
104
- bool flag_loop=true ;
105
- double * newestimate = new double [_nobsdim];
106
- double * newerrestim = new double [_nobsdim];
107
- double * foo;
108
- while ( flag_loop )
109
- {
116
+ if (NdecorrelationSteps < 0 ) {
117
+ long i;
118
+ // constants
119
+ const long MIN_NMC=100 ;
120
+ // allocate the data array that will be used
121
+ _datax = new double *[MIN_NMC];
122
+ for (i=0 ; i<MIN_NMC; ++i) { *(_datax+i) = new double [_nobsdim]; }
123
+ // do a first estimate of the observables
124
+ this ->sample (MIN_NMC, true );
125
+ double * oldestimate = new double [_nobsdim];
126
+ double * olderrestim = new double [_nobsdim];
127
+ mci::MultiDimCorrelatedEstimator (MIN_NMC, _nobsdim, _datax, oldestimate, olderrestim);
128
+ // start a loop which will stop when the observables are stabilized
129
+ bool flag_loop=true ;
130
+ double * newestimate = new double [_nobsdim];
131
+ double * newerrestim = new double [_nobsdim];
132
+ double * foo;
133
+ while ( flag_loop ) {
134
+ flag_loop = false ;
110
135
this ->sample (MIN_NMC, true );
111
136
mci::MultiDimCorrelatedEstimator (MIN_NMC, _nobsdim, _datax, newestimate, newerrestim);
112
- for (i=0 ; i<_nobsdim; ++i)
113
- {
114
- if ( abs ( *(oldestimate+i) - *(newestimate+i) ) <= *(olderrestim+i) + *(newerrestim+i) ) flag_loop=false ;
115
- if (flag_loop) *(oldestimate+i) = *(newestimate+i);
137
+ for (i=0 ; i<_nobsdim; ++i) {
138
+ if ( std::abs ( *(oldestimate+i) - *(newestimate+i) ) > *(olderrestim+i) + *(newerrestim+i) ) {
139
+ flag_loop=true ;
116
140
}
141
+ }
117
142
foo=oldestimate;
118
143
oldestimate=newestimate;
119
144
newestimate=foo;
120
145
}
121
- // memory deallocation
122
- delete [] newestimate;
123
- delete [] newerrestim;
124
- delete [] oldestimate;
125
- delete [] olderrestim;
126
- for (i=0 ; i<MIN_NMC; ++i){ delete[] *(_datax+i); }
127
- delete [] _datax;
146
+ // memory deallocation
147
+ delete [] newestimate;
148
+ delete [] newerrestim;
149
+ delete [] oldestimate;
150
+ delete [] olderrestim;
151
+ for (i=0 ; i<MIN_NMC; ++i){ delete[] *(_datax+i); }
152
+ delete [] _datax;
153
+ }
154
+ else {
155
+ this ->sample (NdecorrelationSteps, false );
156
+ }
128
157
}
129
158
130
159
131
- void MCI::sample (const long &npoints, const bool &flagobs)
160
+ void MCI::sample (const long &npoints, const bool &flagobs, const long &stepsPerBlock )
132
161
{
162
+ if (flagobs && stepsPerBlock>0 && npoints%stepsPerBlock!=0 ) {
163
+ throw std::invalid_argument (" If fixed blocking is used, npoints must be a multiple of stepsPerBlock." );
164
+ }
165
+
133
166
int i;
134
- // initialize the running index
167
+ // initialize the running indices
135
168
_ridx=0 ;
169
+ _bidx=0 ;
170
+
171
+ if (flagobs) {
172
+ // set the data to 0
173
+ for (i=0 ; i<npoints/stepsPerBlock; ++i) {
174
+ for (long j=0 ; j<_nobsdim; ++j) {
175
+ *(*(_datax+i)+j) = 0 .;
176
+ }
177
+ }
178
+ }
179
+
136
180
// initialize the pdf at x
137
181
computeOldSamplingFunction ();
138
182
// initialize the observables values at x
@@ -170,13 +214,15 @@ void MCI::sample(const long &npoints, const bool &flagobs)
170
214
if (_flagwlkfile) this ->storeWalkerPositions ();
171
215
}
172
216
_ridx++;
217
+ _bidx = _ridx / stepsPerBlock;
173
218
}
174
219
} else
175
220
{
176
221
for (i=0 ; i<npoints; ++i)
177
222
{
178
223
this ->doStepMRT2 (&flagacc);
179
224
_ridx++;
225
+ _bidx = _ridx / stepsPerBlock;
180
226
}
181
227
}
182
228
}
@@ -194,20 +240,22 @@ void MCI::sample(const long &npoints, const bool &flagobs)
194
240
if (_flagwlkfile) this ->storeWalkerPositions ();
195
241
}
196
242
_ridx++;
243
+ _bidx = _ridx / stepsPerBlock;
197
244
}
198
245
} else
199
246
{
200
247
for (i=0 ; i<npoints; ++i)
201
248
{
202
249
this ->newRandomX ();
203
250
_ridx++;
251
+ _bidx = _ridx / stepsPerBlock;
204
252
}
205
253
}
206
254
}
207
255
}
208
256
209
257
210
- void MCI::findMRT2Step ()
258
+ void MCI::findMRT2Step (const int &NfindMRT2stepIterations )
211
259
{
212
260
int j;
213
261
// constants
@@ -221,7 +269,7 @@ void MCI::findMRT2Step()
221
269
int cons_count = 0 ; // number of consecutive loops without need of changing mrt2step
222
270
int counter = 0 ; // counter of loops
223
271
double fact;
224
- while ( cons_count < MIN_CONS )
272
+ while ( ( cons_count < MIN_CONS && NfindMRT2stepIterations < 0 ) || counter < NfindMRT2stepIterations )
225
273
{
226
274
counter++;
227
275
// do MIN_STAT M(RT)^2 steps
@@ -258,7 +306,6 @@ void MCI::findMRT2Step()
258
306
{
259
307
if ( *(_mrt2step+j) - ( *(*(_irange+j)+1 ) - *(*(_irange+j)) ) > 0 . )
260
308
{
261
- cons_count = MIN_CONS; // make the main loop terminate
262
309
*(_mrt2step+j) = ( *(*(_irange+j)+1 ) - *(*(_irange+j)) );
263
310
}
264
311
}
@@ -267,7 +314,6 @@ void MCI::findMRT2Step()
267
314
{
268
315
if ( *(_mrt2step+j) < SMALLEST_ACCEPTABLE_DOUBLE )
269
316
{
270
- cons_count = MIN_CONS; // make the main loop terminate
271
317
*(_mrt2step+j) = SMALLEST_ACCEPTABLE_DOUBLE;
272
318
}
273
319
}
@@ -419,7 +465,7 @@ void MCI::saveObservables()
419
465
{
420
466
for (int j=0 ; j<_obs[i]->getNObs (); ++j)
421
467
{
422
- _datax[_ridx ][idx]=_obs[i]->getObservable (j);
468
+ _datax[_bidx ][idx]+ =_obs[i]->getObservable (j);
423
469
idx++;
424
470
}
425
471
}
0 commit comments